mirror of https://github.com/python/cpython
Refine specialization stats (GH-27992)
This commit is contained in:
parent
2ec9428e35
commit
ee9c0527ae
|
@ -405,6 +405,7 @@ _Py_Quicken(PyCodeObject *code) {
|
|||
|
||||
/* Common */
|
||||
|
||||
#define SPEC_FAIL_OTHER 0
|
||||
#define SPEC_FAIL_NO_DICT 1
|
||||
#define SPEC_FAIL_OVERRIDDEN 2
|
||||
#define SPEC_FAIL_OUT_OF_VERSIONS 3
|
||||
|
@ -427,24 +428,28 @@ _Py_Quicken(PyCodeObject *code) {
|
|||
|
||||
/* Methods */
|
||||
|
||||
#define SPEC_FAIL_NEGATIVE_DICTOFFSET 14
|
||||
#define SPEC_FAIL_IS_ATTR 15
|
||||
#define SPEC_FAIL_DICT_SUBCLASS 16
|
||||
#define SPEC_FAIL_BUILTIN_CLASS_METHOD 17
|
||||
#define SPEC_FAIL_CLASS_METHOD_OBJ 18
|
||||
#define SPEC_FAIL_NOT_METHOD 19
|
||||
#define SPEC_FAIL_OBJECT_SLOT 19
|
||||
|
||||
/* Binary subscr */
|
||||
|
||||
#define SPEC_FAIL_LIST_NON_INT_SUBSCRIPT 8
|
||||
#define SPEC_FAIL_TUPLE_NON_INT_SUBSCRIPT 9
|
||||
#define SPEC_FAIL_NOT_TUPLE_LIST_OR_DICT 10
|
||||
#define SPEC_FAIL_ARRAY_INT 8
|
||||
#define SPEC_FAIL_ARRAY_SLICE 9
|
||||
#define SPEC_FAIL_LIST_SLICE 10
|
||||
#define SPEC_FAIL_TUPLE_SLICE 11
|
||||
#define SPEC_FAIL_STRING_INT 12
|
||||
#define SPEC_FAIL_STRING_SLICE 13
|
||||
#define SPEC_FAIL_BUFFER_INT 15
|
||||
#define SPEC_FAIL_BUFFER_SLICE 16
|
||||
#define SPEC_FAIL_SEQUENCE_INT 17
|
||||
|
||||
/* Binary add */
|
||||
|
||||
#define SPEC_FAIL_NON_FUNCTION_SCOPE 11
|
||||
#define SPEC_FAIL_DIFFERENT_TYPES 12
|
||||
#define SPEC_FAIL_OTHER_TYPE 13
|
||||
|
||||
|
||||
static int
|
||||
|
@ -870,7 +875,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
|
|||
// Technically this is fine for bound method calls, but it's uncommon and
|
||||
// slightly slower at runtime to get dict.
|
||||
if (owner_cls->tp_dictoffset < 0) {
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_NEGATIVE_DICTOFFSET);
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_RANGE);
|
||||
goto fail;
|
||||
}
|
||||
PyObject **owner_dictptr = _PyObject_GetDictPtr(owner);
|
||||
|
@ -896,16 +901,43 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
|
|||
|
||||
assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN);
|
||||
switch (kind) {
|
||||
case OVERRIDING:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDING_DESCRIPTOR);
|
||||
goto fail;
|
||||
case METHOD:
|
||||
break;
|
||||
case PROPERTY:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_PROPERTY);
|
||||
goto fail;
|
||||
case OBJECT_SLOT:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OBJECT_SLOT);
|
||||
goto fail;
|
||||
case OTHER_SLOT:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NON_OBJECT_SLOT);
|
||||
goto fail;
|
||||
case DUNDER_CLASS:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
|
||||
goto fail;
|
||||
case MUTABLE:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_MUTABLE_CLASS);
|
||||
goto fail;
|
||||
case GETSET_OVERRIDDEN:
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
|
||||
goto fail;
|
||||
case BUILTIN_CLASSMETHOD:
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_BUILTIN_CLASS_METHOD);
|
||||
goto fail;
|
||||
case PYTHON_CLASSMETHOD:
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_CLASS_METHOD_OBJ);
|
||||
goto fail;
|
||||
default:
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_NOT_METHOD);
|
||||
case NON_OVERRIDING:
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_NON_OVERRIDING_DESCRIPTOR);
|
||||
goto fail;
|
||||
case NON_DESCRIPTOR:
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_NOT_DESCRIPTOR);
|
||||
goto fail;
|
||||
case ABSENT:
|
||||
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_EXPECTED_ERROR);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -1046,6 +1078,45 @@ success:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if COLLECT_SPECIALIZATION_STATS_DETAILED
|
||||
static int
|
||||
binary_subscr_faiL_kind(PyTypeObject *container_type, PyObject *sub)
|
||||
{
|
||||
if (container_type == &PyUnicode_Type) {
|
||||
if (PyLong_CheckExact(sub)) {
|
||||
return SPEC_FAIL_STRING_INT;
|
||||
}
|
||||
if (PySlice_Check(sub)) {
|
||||
return SPEC_FAIL_STRING_SLICE;
|
||||
}
|
||||
return SPEC_FAIL_OTHER;
|
||||
}
|
||||
else if (strcmp(container_type->tp_name, "array.array") == 0) {
|
||||
if (PyLong_CheckExact(sub)) {
|
||||
return SPEC_FAIL_ARRAY_INT;
|
||||
}
|
||||
if (PySlice_Check(sub)) {
|
||||
return SPEC_FAIL_ARRAY_SLICE;
|
||||
}
|
||||
return SPEC_FAIL_OTHER;
|
||||
}
|
||||
else if (container_type->tp_as_buffer) {
|
||||
if (PyLong_CheckExact(sub)) {
|
||||
return SPEC_FAIL_BUFFER_INT;
|
||||
}
|
||||
if (PySlice_Check(sub)) {
|
||||
return SPEC_FAIL_BUFFER_SLICE;
|
||||
}
|
||||
return SPEC_FAIL_OTHER;
|
||||
}
|
||||
else if (container_type->tp_as_sequence) {
|
||||
if (PyLong_CheckExact(sub) && container_type->tp_as_sequence->sq_item) {
|
||||
return SPEC_FAIL_SEQUENCE_INT;
|
||||
}
|
||||
}
|
||||
return SPEC_FAIL_OTHER;
|
||||
}
|
||||
#endif
|
||||
int
|
||||
_Py_Specialize_BinarySubscr(
|
||||
PyObject *container, PyObject *sub, _Py_CODEUNIT *instr)
|
||||
|
@ -1055,25 +1126,26 @@ _Py_Specialize_BinarySubscr(
|
|||
if (PyLong_CheckExact(sub)) {
|
||||
*instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_LIST_INT, saturating_start());
|
||||
goto success;
|
||||
} else {
|
||||
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_LIST_NON_INT_SUBSCRIPT);
|
||||
goto fail;
|
||||
}
|
||||
SPECIALIZATION_FAIL(BINARY_SUBSCR,
|
||||
PySlice_Check(sub) ? SPEC_FAIL_LIST_SLICE : SPEC_FAIL_OTHER);
|
||||
goto fail;
|
||||
}
|
||||
if (container_type == &PyTuple_Type) {
|
||||
if (PyLong_CheckExact(sub)) {
|
||||
*instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_TUPLE_INT, saturating_start());
|
||||
goto success;
|
||||
} else {
|
||||
SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_TUPLE_NON_INT_SUBSCRIPT);
|
||||
goto fail;
|
||||
}
|
||||
SPECIALIZATION_FAIL(BINARY_SUBSCR,
|
||||
PySlice_Check(sub) ? SPEC_FAIL_TUPLE_SLICE : SPEC_FAIL_OTHER);
|
||||
goto fail;
|
||||
}
|
||||
if (container_type == &PyDict_Type) {
|
||||
*instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_DICT, saturating_start());
|
||||
goto success;
|
||||
}
|
||||
SPECIALIZATION_FAIL(BINARY_SUBSCR,SPEC_FAIL_NOT_TUPLE_LIST_OR_DICT);
|
||||
SPECIALIZATION_FAIL(BINARY_SUBSCR,
|
||||
binary_subscr_faiL_kind(container_type, sub));
|
||||
goto fail;
|
||||
fail:
|
||||
STAT_INC(BINARY_SUBSCR, specialization_failure);
|
||||
|
@ -1114,7 +1186,7 @@ _Py_Specialize_BinaryAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr)
|
|||
|
||||
}
|
||||
else {
|
||||
SPECIALIZATION_FAIL(BINARY_ADD, SPEC_FAIL_OTHER_TYPE);
|
||||
SPECIALIZATION_FAIL(BINARY_ADD, SPEC_FAIL_OTHER);
|
||||
}
|
||||
fail:
|
||||
STAT_INC(BINARY_ADD, specialization_failure);
|
||||
|
|
Loading…
Reference in New Issue