@@ -552,9 +552,28 @@ initial_counter_value(void) {
552
552
#define SPEC_FAIL_SUBSCR_PY_OTHER 21
553
553
#define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22
554
554
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
558
577
559
578
/* Calls */
560
579
#define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9
@@ -1745,6 +1764,76 @@ _Py_Specialize_CallNoKw(
1745
1764
return 0 ;
1746
1765
}
1747
1766
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
+
1748
1837
void
1749
1838
_Py_Specialize_BinaryOp (PyObject * lhs , PyObject * rhs , _Py_CODEUNIT * instr ,
1750
1839
SpecializedCacheEntry * cache )
@@ -1754,8 +1843,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
1754
1843
case NB_ADD :
1755
1844
case NB_INPLACE_ADD :
1756
1845
if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1757
- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES );
1758
- goto failure ;
1846
+ break ;
1759
1847
}
1760
1848
if (PyUnicode_CheckExact (lhs )) {
1761
1849
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,
1780
1868
case NB_MULTIPLY :
1781
1869
case NB_INPLACE_MULTIPLY :
1782
1870
if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1783
- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES );
1784
- goto failure ;
1871
+ break ;
1785
1872
}
1786
1873
if (PyLong_CheckExact (lhs )) {
1787
1874
* instr = _Py_MAKECODEUNIT (BINARY_OP_MULTIPLY_INT ,
@@ -1797,8 +1884,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
1797
1884
case NB_SUBTRACT :
1798
1885
case NB_INPLACE_SUBTRACT :
1799
1886
if (!Py_IS_TYPE (lhs , Py_TYPE (rhs ))) {
1800
- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES );
1801
- goto failure ;
1887
+ break ;
1802
1888
}
1803
1889
if (PyLong_CheckExact (lhs )) {
1804
1890
* instr = _Py_MAKECODEUNIT (BINARY_OP_SUBTRACT_INT ,
@@ -1811,14 +1897,19 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
1811
1897
goto success ;
1812
1898
}
1813
1899
break ;
1900
+ #ifndef Py_STATS
1814
1901
default :
1815
1902
// These operators don't have any available specializations. Rather
1816
1903
// 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):
1818
1907
* instr = _Py_MAKECODEUNIT (BINARY_OP , adaptive -> original_oparg );
1908
+ return ;
1909
+ #endif
1819
1910
}
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 ));
1822
1913
STAT_INC (BINARY_OP , failure );
1823
1914
cache_backoff (adaptive );
1824
1915
return ;
0 commit comments