@@ -552,9 +552,28 @@ initial_counter_value(void) {
552552#define SPEC_FAIL_SUBSCR_PY_OTHER 21
553553#define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22
554554
555- /* Binary add */
556-
557- #define SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES 12
555+ /* Binary op */
556+
557+ #define SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES 8
558+ #define SPEC_FAIL_BINARY_OP_ADD_OTHER 9
559+ #define SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES 10
560+ #define SPEC_FAIL_BINARY_OP_AND_INT 11
561+ #define SPEC_FAIL_BINARY_OP_AND_OTHER 12
562+ #define SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE 13
563+ #define SPEC_FAIL_BINARY_OP_LSHIFT 14
564+ #define SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY 15
565+ #define SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES 16
566+ #define SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER 17
567+ #define SPEC_FAIL_BINARY_OP_OR 18
568+ #define SPEC_FAIL_BINARY_OP_POWER 19
569+ #define SPEC_FAIL_BINARY_OP_REMAINDER 20
570+ #define SPEC_FAIL_BINARY_OP_RSHIFT 21
571+ #define SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES 22
572+ #define SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER 23
573+ #define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES 24
574+ #define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT 25
575+ #define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER 26
576+ #define SPEC_FAIL_BINARY_OP_XOR 27
558577
559578/* Calls */
560579#define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9
@@ -1745,6 +1764,76 @@ _Py_Specialize_CallNoKw(
17451764 return 0 ;
17461765}
17471766
1767+ #ifdef Py_STATS
1768+ static int
1769+ binary_op_fail_kind (int oparg , PyObject * lhs , PyObject * rhs )
1770+ {
1771+ switch (oparg ) {
1772+ case NB_ADD :
1773+ case NB_INPLACE_ADD :
1774+ if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1775+ return SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES ;
1776+ }
1777+ return SPEC_FAIL_BINARY_OP_ADD_OTHER ;
1778+ case NB_AND :
1779+ case NB_INPLACE_AND :
1780+ if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1781+ return SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES ;
1782+ }
1783+ if (PyLong_CheckExact (lhs )) {
1784+ return SPEC_FAIL_BINARY_OP_AND_INT ;
1785+ }
1786+ return SPEC_FAIL_BINARY_OP_AND_OTHER ;
1787+ case NB_FLOOR_DIVIDE :
1788+ case NB_INPLACE_FLOOR_DIVIDE :
1789+ return SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE ;
1790+ case NB_LSHIFT :
1791+ case NB_INPLACE_LSHIFT :
1792+ return SPEC_FAIL_BINARY_OP_LSHIFT ;
1793+ case NB_MATRIX_MULTIPLY :
1794+ case NB_INPLACE_MATRIX_MULTIPLY :
1795+ return SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY ;
1796+ case NB_MULTIPLY :
1797+ case NB_INPLACE_MULTIPLY :
1798+ if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1799+ return SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES ;
1800+ }
1801+ return SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER ;
1802+ case NB_OR :
1803+ case NB_INPLACE_OR :
1804+ return SPEC_FAIL_BINARY_OP_OR ;
1805+ case NB_POWER :
1806+ case NB_INPLACE_POWER :
1807+ return SPEC_FAIL_BINARY_OP_POWER ;
1808+ case NB_REMAINDER :
1809+ case NB_INPLACE_REMAINDER :
1810+ return SPEC_FAIL_BINARY_OP_REMAINDER ;
1811+ case NB_RSHIFT :
1812+ case NB_INPLACE_RSHIFT :
1813+ return SPEC_FAIL_BINARY_OP_RSHIFT ;
1814+ case NB_SUBTRACT :
1815+ case NB_INPLACE_SUBTRACT :
1816+ if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1817+ return SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES ;
1818+ }
1819+ return SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER ;
1820+ case NB_TRUE_DIVIDE :
1821+ case NB_INPLACE_TRUE_DIVIDE :
1822+ if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1823+ return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES ;
1824+ }
1825+ if (PyFloat_CheckExact (lhs )) {
1826+ return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT ;
1827+ }
1828+ return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER ;
1829+ case NB_XOR :
1830+ case NB_INPLACE_XOR :
1831+ return SPEC_FAIL_BINARY_OP_XOR ;
1832+ }
1833+ Py_UNREACHABLE ();
1834+ }
1835+ #endif
1836+
17481837void
17491838_Py_Specialize_BinaryOp (PyObject * lhs , PyObject * rhs , _Py_CODEUNIT * instr ,
17501839 SpecializedCacheEntry * cache )
@@ -1754,8 +1843,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
17541843 case NB_ADD :
17551844 case NB_INPLACE_ADD :
17561845 if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1757- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES );
1758- goto failure ;
1846+ break ;
17591847 }
17601848 if (PyUnicode_CheckExact (lhs )) {
17611849 if (_Py_OPCODE (instr [1 ]) == STORE_FAST && Py_REFCNT (lhs ) == 2 ) {
@@ -1780,8 +1868,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
17801868 case NB_MULTIPLY :
17811869 case NB_INPLACE_MULTIPLY :
17821870 if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1783- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES );
1784- goto failure ;
1871+ break ;
17851872 }
17861873 if (PyLong_CheckExact (lhs )) {
17871874 * instr = _Py_MAKECODEUNIT (BINARY_OP_MULTIPLY_INT ,
@@ -1797,8 +1884,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
17971884 case NB_SUBTRACT :
17981885 case NB_INPLACE_SUBTRACT :
17991886 if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1800- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES );
1801- goto failure ;
1887+ break ;
18021888 }
18031889 if (PyLong_CheckExact (lhs )) {
18041890 * instr = _Py_MAKECODEUNIT (BINARY_OP_SUBTRACT_INT ,
@@ -1811,14 +1897,19 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
18111897 goto success ;
18121898 }
18131899 break ;
1900+ #ifndef Py_STATS
18141901 default :
18151902 // These operators don't have any available specializations. Rather
18161903 // than repeatedly attempting to specialize them, just convert them
1817- // back to BINARY_OP (while still recording a failure, of course)!
1904+ // back to BINARY_OP (unless we're collecting stats, where it's more
1905+ // important to get accurate hit counts for the unadaptive version
1906+ // and each of the different failure types):
18181907 * instr = _Py_MAKECODEUNIT (BINARY_OP , adaptive -> original_oparg );
1908+ return ;
1909+ #endif
18191910 }
1820- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_OTHER );
1821- failure :
1911+ SPECIALIZATION_FAIL (
1912+ BINARY_OP , binary_op_fail_kind ( adaptive -> original_oparg , lhs , rhs ));
18221913 STAT_INC (BINARY_OP , failure );
18231914 cache_backoff (adaptive );
18241915 return ;
0 commit comments