mirror of
https://github.com/python/cpython
synced 2024-09-05 08:17:45 +00:00
Add specialization stats for FOR_ITER. (GH-31079)
This commit is contained in:
parent
f66c857572
commit
0d05da1fbf
|
@ -4212,6 +4212,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
|
|||
PREDICTED(FOR_ITER);
|
||||
/* before: [iter]; after: [iter, iter()] *or* [] */
|
||||
PyObject *iter = TOP();
|
||||
#ifdef Py_STATS
|
||||
extern int _PySpecialization_ClassifyIterator(PyObject *);
|
||||
_py_stats.opcode_stats[FOR_ITER].specialization.failure++;
|
||||
_py_stats.opcode_stats[FOR_ITER].specialization.failure_kinds[_PySpecialization_ClassifyIterator(iter)]++;
|
||||
#endif
|
||||
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
|
||||
if (next != NULL) {
|
||||
PUSH(next);
|
||||
|
|
|
@ -548,6 +548,23 @@ initial_counter_value(void) {
|
|||
#define SPEC_FAIL_NOT_FOLLOWED_BY_COND_JUMP 14
|
||||
#define SPEC_FAIL_BIG_INT 15
|
||||
|
||||
/* FOR_ITER */
|
||||
#define SPEC_FAIL_ITER_GENERATOR 10
|
||||
#define SPEC_FAIL_ITER_COROUTINE 11
|
||||
#define SPEC_FAIL_ITER_ASYNC_GENERATOR 12
|
||||
#define SPEC_FAIL_ITER_LIST 13
|
||||
#define SPEC_FAIL_ITER_TUPLE 14
|
||||
#define SPEC_FAIL_ITER_SET 15
|
||||
#define SPEC_FAIL_ITER_STRING 16
|
||||
#define SPEC_FAIL_ITER_BYTES 17
|
||||
#define SPEC_FAIL_ITER_RANGE 18
|
||||
#define SPEC_FAIL_ITER_ITERTOOLS 19
|
||||
#define SPEC_FAIL_ITER_DICT_KEYS 20
|
||||
#define SPEC_FAIL_ITER_DICT_ITEMS 21
|
||||
#define SPEC_FAIL_ITER_DICT_VALUES 22
|
||||
#define SPEC_FAIL_ITER_ENUMERATE 23
|
||||
|
||||
|
||||
static int
|
||||
specialize_module_load_attr(
|
||||
PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
|
||||
|
@ -1817,3 +1834,54 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
|
|||
STAT_INC(COMPARE_OP, success);
|
||||
adaptive->counter = initial_counter_value();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_PySpecialization_ClassifyIterator(PyObject *iter)
|
||||
{
|
||||
if (PyGen_CheckExact(iter)) {
|
||||
return SPEC_FAIL_ITER_GENERATOR;
|
||||
}
|
||||
if (PyCoro_CheckExact(iter)) {
|
||||
return SPEC_FAIL_ITER_COROUTINE;
|
||||
}
|
||||
if (PyAsyncGen_CheckExact(iter)) {
|
||||
return SPEC_FAIL_ITER_ASYNC_GENERATOR;
|
||||
}
|
||||
PyTypeObject *t = _Py_TYPE(iter);
|
||||
if (t == &PyListIter_Type) {
|
||||
return SPEC_FAIL_ITER_LIST;
|
||||
}
|
||||
if (t == &PyTupleIter_Type) {
|
||||
return SPEC_FAIL_ITER_TUPLE;
|
||||
}
|
||||
if (t == &PyDictIterKey_Type) {
|
||||
return SPEC_FAIL_ITER_DICT_KEYS;
|
||||
}
|
||||
if (t == &PyDictIterValue_Type) {
|
||||
return SPEC_FAIL_ITER_DICT_VALUES;
|
||||
}
|
||||
if (t == &PyDictIterItem_Type) {
|
||||
return SPEC_FAIL_ITER_DICT_ITEMS;
|
||||
}
|
||||
if (t == &PySetIter_Type) {
|
||||
return SPEC_FAIL_ITER_SET;
|
||||
}
|
||||
if (t == &PyUnicodeIter_Type) {
|
||||
return SPEC_FAIL_ITER_STRING;
|
||||
}
|
||||
if (t == &PyBytesIter_Type) {
|
||||
return SPEC_FAIL_ITER_BYTES;
|
||||
}
|
||||
if (t == &PyRangeIter_Type) {
|
||||
return SPEC_FAIL_ITER_RANGE;
|
||||
}
|
||||
if (t == &PyEnum_Type) {
|
||||
return SPEC_FAIL_ITER_ENUMERATE;
|
||||
}
|
||||
|
||||
if (strncmp(t->tp_name, "itertools", 8) == 0) {
|
||||
return SPEC_FAIL_ITER_ITERTOOLS;
|
||||
}
|
||||
return SPEC_FAIL_OTHER;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count"
|
||||
|
||||
def print_specialization_stats(name, family_stats):
|
||||
if "specialization.deferred" not in family_stats:
|
||||
if "specialization.failure" not in family_stats:
|
||||
return
|
||||
total = sum(family_stats.get(kind, 0) for kind in TOTAL)
|
||||
if total == 0:
|
||||
|
|
Loading…
Reference in a new issue