Skip to content

Commit 289c112

Browse files
authored
Better stats for LOAD_ATTR and STORE_ATTR (GH-100295)
* Don't attempt to specialize for LOAD_ATTR on instance if class has attribute * Improvement to LOAD_ATTR and STORE_ATTR specialization stats.
1 parent 0415cf8 commit 289c112

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

Include/pystats.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extern "C" {
88

99
#ifdef Py_STATS
1010

11-
#define SPECIALIZATION_FAILURE_KINDS 32
11+
#define SPECIALIZATION_FAILURE_KINDS 36
1212

1313
/* Stats for determining who is calling PyEval_EvalFrame */
1414
#define EVAL_CALL_TOTAL 0

Python/specialize.c

+35-12
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ _PyCode_Quicken(PyCodeObject *code)
340340
#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28
341341
#define SPEC_FAIL_ATTR_NOT_IN_KEYS 29
342342
#define SPEC_FAIL_ATTR_NOT_IN_DICT 30
343+
#define SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE 31
344+
#define SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR 32
345+
#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ 33
343346

344347
/* Binary subscr and store subscr */
345348

@@ -813,16 +816,29 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
813816
goto success;
814817
}
815818
case BUILTIN_CLASSMETHOD:
819+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ);
820+
goto fail;
816821
case PYTHON_CLASSMETHOD:
822+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ);
823+
goto fail;
817824
case NON_OVERRIDING:
825+
SPECIALIZATION_FAIL(LOAD_ATTR,
826+
(type->tp_flags & Py_TPFLAGS_MANAGED_DICT) ?
827+
SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR :
828+
SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
829+
goto fail;
818830
case NON_DESCRIPTOR:
831+
SPECIALIZATION_FAIL(LOAD_ATTR,
832+
(type->tp_flags & Py_TPFLAGS_MANAGED_DICT) ?
833+
SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE :
834+
SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
835+
goto fail;
819836
case ABSENT:
820-
break;
821-
}
822-
if (specialize_dict_access(owner, instr, type, kind, name, LOAD_ATTR,
823-
LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT))
824-
{
825-
goto success;
837+
if (specialize_dict_access(owner, instr, type, kind, name, LOAD_ATTR,
838+
LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT))
839+
{
840+
goto success;
841+
}
826842
}
827843
fail:
828844
STAT_INC(LOAD_ATTR, failure);
@@ -901,16 +917,23 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
901917
SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN);
902918
goto fail;
903919
case BUILTIN_CLASSMETHOD:
920+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ);
921+
goto fail;
904922
case PYTHON_CLASSMETHOD:
923+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ);
924+
goto fail;
905925
case NON_OVERRIDING:
926+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR);
927+
goto fail;
906928
case NON_DESCRIPTOR:
929+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE);
930+
goto fail;
907931
case ABSENT:
908-
break;
909-
}
910-
if (specialize_dict_access(owner, instr, type, kind, name, STORE_ATTR,
911-
STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT))
912-
{
913-
goto success;
932+
if (specialize_dict_access(owner, instr, type, kind, name, STORE_ATTR,
933+
STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT))
934+
{
935+
goto success;
936+
}
914937
}
915938
fail:
916939
STAT_INC(STORE_ATTR, failure);

0 commit comments

Comments
 (0)