mirror of
https://github.com/python/cpython.git
synced 2025-10-14 10:53:40 +00:00
Add specialization stats for FOR_ITER. (GH-31079)
This commit is contained in:
parent
f66c857572
commit
0d05da1fbf
3 changed files with 74 additions and 1 deletions
|
@ -4212,6 +4212,11 @@ handle_eval_breaker:
|
||||||
PREDICTED(FOR_ITER);
|
PREDICTED(FOR_ITER);
|
||||||
/* before: [iter]; after: [iter, iter()] *or* [] */
|
/* before: [iter]; after: [iter, iter()] *or* [] */
|
||||||
PyObject *iter = TOP();
|
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);
|
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
|
||||||
if (next != NULL) {
|
if (next != NULL) {
|
||||||
PUSH(next);
|
PUSH(next);
|
||||||
|
|
|
@ -548,6 +548,23 @@ initial_counter_value(void) {
|
||||||
#define SPEC_FAIL_NOT_FOLLOWED_BY_COND_JUMP 14
|
#define SPEC_FAIL_NOT_FOLLOWED_BY_COND_JUMP 14
|
||||||
#define SPEC_FAIL_BIG_INT 15
|
#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
|
static int
|
||||||
specialize_module_load_attr(
|
specialize_module_load_attr(
|
||||||
PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
|
PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
|
||||||
|
@ -1817,3 +1834,54 @@ success:
|
||||||
STAT_INC(COMPARE_OP, success);
|
STAT_INC(COMPARE_OP, success);
|
||||||
adaptive->counter = initial_counter_value();
|
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 @@ for name in opcode.opname[1:]:
|
||||||
TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count"
|
TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count"
|
||||||
|
|
||||||
def print_specialization_stats(name, family_stats):
|
def print_specialization_stats(name, family_stats):
|
||||||
if "specialization.deferred" not in family_stats:
|
if "specialization.failure" not in family_stats:
|
||||||
return
|
return
|
||||||
total = sum(family_stats.get(kind, 0) for kind in TOTAL)
|
total = sum(family_stats.get(kind, 0) for kind in TOTAL)
|
||||||
if total == 0:
|
if total == 0:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue