Skip to content

Commit ee9c052

Browse files
authored
Refine specialization stats (GH-27992)
1 parent 2ec9428 commit ee9c052

File tree

1 file changed

+89
-17
lines changed

1 file changed

+89
-17
lines changed

Python/specialize.c

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

450455
static 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
10491120
int
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;
10781150
fail:
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
}
11191191
fail:
11201192
STAT_INC(BINARY_ADD, specialization_failure);

0 commit comments

Comments
 (0)