@@ -405,6 +405,7 @@ _Py_Quicken(PyCodeObject *code) {
405405
406406/* Common */
407407
408+ #define SPEC_FAIL_OTHER 0
408409#define SPEC_FAIL_NO_DICT 1
409410#define SPEC_FAIL_OVERRIDDEN 2
410411#define SPEC_FAIL_OUT_OF_VERSIONS 3
@@ -427,24 +428,28 @@ _Py_Quicken(PyCodeObject *code) {
427428
428429/* Methods */
429430
430- #define SPEC_FAIL_NEGATIVE_DICTOFFSET 14
431431#define SPEC_FAIL_IS_ATTR 15
432432#define SPEC_FAIL_DICT_SUBCLASS 16
433433#define SPEC_FAIL_BUILTIN_CLASS_METHOD 17
434434#define SPEC_FAIL_CLASS_METHOD_OBJ 18
435- #define SPEC_FAIL_NOT_METHOD 19
435+ #define SPEC_FAIL_OBJECT_SLOT 19
436436
437437/* Binary subscr */
438438
439- #define SPEC_FAIL_LIST_NON_INT_SUBSCRIPT 8
440- #define SPEC_FAIL_TUPLE_NON_INT_SUBSCRIPT 9
441- #define SPEC_FAIL_NOT_TUPLE_LIST_OR_DICT 10
439+ #define SPEC_FAIL_ARRAY_INT 8
440+ #define SPEC_FAIL_ARRAY_SLICE 9
441+ #define SPEC_FAIL_LIST_SLICE 10
442+ #define SPEC_FAIL_TUPLE_SLICE 11
443+ #define SPEC_FAIL_STRING_INT 12
444+ #define SPEC_FAIL_STRING_SLICE 13
445+ #define SPEC_FAIL_BUFFER_INT 15
446+ #define SPEC_FAIL_BUFFER_SLICE 16
447+ #define SPEC_FAIL_SEQUENCE_INT 17
442448
443449/* Binary add */
444450
445451#define SPEC_FAIL_NON_FUNCTION_SCOPE 11
446452#define SPEC_FAIL_DIFFERENT_TYPES 12
447- #define SPEC_FAIL_OTHER_TYPE 13
448453
449454
450455static int
@@ -870,7 +875,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
870875 // Technically this is fine for bound method calls, but it's uncommon and
871876 // slightly slower at runtime to get dict.
872877 if (owner_cls -> tp_dictoffset < 0 ) {
873- SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_NEGATIVE_DICTOFFSET );
878+ SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_OUT_OF_RANGE );
874879 goto fail ;
875880 }
876881 PyObject * * owner_dictptr = _PyObject_GetDictPtr (owner );
@@ -896,16 +901,43 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
896901
897902 assert (descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN );
898903 switch (kind ) {
904+ case OVERRIDING :
905+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OVERRIDING_DESCRIPTOR );
906+ goto fail ;
899907 case METHOD :
900908 break ;
909+ case PROPERTY :
910+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_PROPERTY );
911+ goto fail ;
912+ case OBJECT_SLOT :
913+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OBJECT_SLOT );
914+ goto fail ;
915+ case OTHER_SLOT :
916+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_NON_OBJECT_SLOT );
917+ goto fail ;
918+ case DUNDER_CLASS :
919+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OTHER );
920+ goto fail ;
921+ case MUTABLE :
922+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_MUTABLE_CLASS );
923+ goto fail ;
924+ case GETSET_OVERRIDDEN :
925+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OVERRIDDEN );
926+ goto fail ;
901927 case BUILTIN_CLASSMETHOD :
902928 SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_BUILTIN_CLASS_METHOD );
903929 goto fail ;
904930 case PYTHON_CLASSMETHOD :
905931 SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_CLASS_METHOD_OBJ );
906932 goto fail ;
907- default :
908- SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_NOT_METHOD );
933+ case NON_OVERRIDING :
934+ SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_NON_OVERRIDING_DESCRIPTOR );
935+ goto fail ;
936+ case NON_DESCRIPTOR :
937+ SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_NOT_DESCRIPTOR );
938+ goto fail ;
939+ case ABSENT :
940+ SPECIALIZATION_FAIL (LOAD_METHOD , SPEC_FAIL_EXPECTED_ERROR );
909941 goto fail ;
910942 }
911943
@@ -1046,6 +1078,45 @@ _Py_Specialize_LoadGlobal(
10461078 return 0 ;
10471079}
10481080
1081+ #if COLLECT_SPECIALIZATION_STATS_DETAILED
1082+ static int
1083+ binary_subscr_faiL_kind (PyTypeObject * container_type , PyObject * sub )
1084+ {
1085+ if (container_type == & PyUnicode_Type ) {
1086+ if (PyLong_CheckExact (sub )) {
1087+ return SPEC_FAIL_STRING_INT ;
1088+ }
1089+ if (PySlice_Check (sub )) {
1090+ return SPEC_FAIL_STRING_SLICE ;
1091+ }
1092+ return SPEC_FAIL_OTHER ;
1093+ }
1094+ else if (strcmp (container_type -> tp_name , "array.array" ) == 0 ) {
1095+ if (PyLong_CheckExact (sub )) {
1096+ return SPEC_FAIL_ARRAY_INT ;
1097+ }
1098+ if (PySlice_Check (sub )) {
1099+ return SPEC_FAIL_ARRAY_SLICE ;
1100+ }
1101+ return SPEC_FAIL_OTHER ;
1102+ }
1103+ else if (container_type -> tp_as_buffer ) {
1104+ if (PyLong_CheckExact (sub )) {
1105+ return SPEC_FAIL_BUFFER_INT ;
1106+ }
1107+ if (PySlice_Check (sub )) {
1108+ return SPEC_FAIL_BUFFER_SLICE ;
1109+ }
1110+ return SPEC_FAIL_OTHER ;
1111+ }
1112+ else if (container_type -> tp_as_sequence ) {
1113+ if (PyLong_CheckExact (sub ) && container_type -> tp_as_sequence -> sq_item ) {
1114+ return SPEC_FAIL_SEQUENCE_INT ;
1115+ }
1116+ }
1117+ return SPEC_FAIL_OTHER ;
1118+ }
1119+ #endif
10491120int
10501121_Py_Specialize_BinarySubscr (
10511122 PyObject * container , PyObject * sub , _Py_CODEUNIT * instr )
@@ -1055,25 +1126,26 @@ _Py_Specialize_BinarySubscr(
10551126 if (PyLong_CheckExact (sub )) {
10561127 * instr = _Py_MAKECODEUNIT (BINARY_SUBSCR_LIST_INT , saturating_start ());
10571128 goto success ;
1058- } else {
1059- SPECIALIZATION_FAIL (BINARY_SUBSCR , SPEC_FAIL_LIST_NON_INT_SUBSCRIPT );
1060- goto fail ;
10611129 }
1130+ SPECIALIZATION_FAIL (BINARY_SUBSCR ,
1131+ PySlice_Check (sub ) ? SPEC_FAIL_LIST_SLICE : SPEC_FAIL_OTHER );
1132+ goto fail ;
10621133 }
10631134 if (container_type == & PyTuple_Type ) {
10641135 if (PyLong_CheckExact (sub )) {
10651136 * instr = _Py_MAKECODEUNIT (BINARY_SUBSCR_TUPLE_INT , saturating_start ());
10661137 goto success ;
1067- } else {
1068- SPECIALIZATION_FAIL (BINARY_SUBSCR , SPEC_FAIL_TUPLE_NON_INT_SUBSCRIPT );
1069- goto fail ;
10701138 }
1139+ SPECIALIZATION_FAIL (BINARY_SUBSCR ,
1140+ PySlice_Check (sub ) ? SPEC_FAIL_TUPLE_SLICE : SPEC_FAIL_OTHER );
1141+ goto fail ;
10711142 }
10721143 if (container_type == & PyDict_Type ) {
10731144 * instr = _Py_MAKECODEUNIT (BINARY_SUBSCR_DICT , saturating_start ());
10741145 goto success ;
10751146 }
1076- SPECIALIZATION_FAIL (BINARY_SUBSCR ,SPEC_FAIL_NOT_TUPLE_LIST_OR_DICT );
1147+ SPECIALIZATION_FAIL (BINARY_SUBSCR ,
1148+ binary_subscr_faiL_kind (container_type , sub ));
10771149 goto fail ;
10781150fail :
10791151 STAT_INC (BINARY_SUBSCR , specialization_failure );
@@ -1114,7 +1186,7 @@ _Py_Specialize_BinaryAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr)
11141186
11151187 }
11161188 else {
1117- SPECIALIZATION_FAIL (BINARY_ADD , SPEC_FAIL_OTHER_TYPE );
1189+ SPECIALIZATION_FAIL (BINARY_ADD , SPEC_FAIL_OTHER );
11181190 }
11191191fail :
11201192 STAT_INC (BINARY_ADD , specialization_failure );
0 commit comments