Skip to content

Commit 622300b

Browse files
authored
GH-132554: Add stats for GET_ITER (GH-132592)
* Add stats for GET_ITER * Look for common iterable types, not iterator types * Add stats for self iter and fix naming in summary
1 parent 01f11a0 commit 622300b

File tree

6 files changed

+64
-1
lines changed

6 files changed

+64
-1
lines changed

Include/internal/pycore_code.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ extern void _Py_Specialize_ForIter(_PyStackRef iter, _Py_CODEUNIT *instr, int op
317317
extern void _Py_Specialize_Send(_PyStackRef receiver, _Py_CODEUNIT *instr);
318318
extern void _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr);
319319
extern void _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr);
320+
extern void _Py_GatherStats_GetIter(_PyStackRef iterable);
320321

321322
// Utility functions for reading/writing 32/64-bit values in the inline caches.
322323
// Great care should be taken to ensure that these functions remain correct and

Python/bytecodes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3029,6 +3029,9 @@ dummy_func(
30293029
}
30303030

30313031
inst(GET_ITER, (iterable -- iter)) {
3032+
#ifdef Py_STATS
3033+
_Py_GatherStats_GetIter(iterable);
3034+
#endif
30323035
/* before: [obj]; after [getiter(obj)] */
30333036
PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
30343037
PyStackRef_CLOSE(iterable);

Python/executor_cases.c.h

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats)
146146
* even though we don't specialize them yet. */
147147
fprintf(out, "opcode[BINARY_SLICE].specializable : 1\n");
148148
fprintf(out, "opcode[STORE_SLICE].specializable : 1\n");
149+
fprintf(out, "opcode[GET_ITER].specializable : 1\n");
149150
for (int i = 0; i < 256; i++) {
150151
if (_PyOpcode_Caches[i]) {
151152
/* Ignore jumps as they cannot be specialized */
@@ -668,6 +669,7 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
668669
#define SPEC_FAIL_ITER_CALLABLE 28
669670
#define SPEC_FAIL_ITER_ASCII_STRING 29
670671
#define SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND 30
672+
#define SPEC_FAIL_ITER_SELF 31
671673

672674
// UNPACK_SEQUENCE
673675

@@ -3115,6 +3117,53 @@ _Py_Specialize_ContainsOp(_PyStackRef value_st, _Py_CODEUNIT *instr)
31153117
return;
31163118
}
31173119

3120+
#ifdef Py_STATS
3121+
void
3122+
_Py_GatherStats_GetIter(_PyStackRef iterable)
3123+
{
3124+
PyTypeObject *tp = PyStackRef_TYPE(iterable);
3125+
int kind = SPEC_FAIL_OTHER;
3126+
if (tp == &PyTuple_Type) {
3127+
kind = SPEC_FAIL_ITER_TUPLE;
3128+
}
3129+
else if (tp == &PyList_Type) {
3130+
kind = SPEC_FAIL_ITER_LIST;
3131+
}
3132+
else if (tp == &PyDict_Type) {
3133+
kind = SPEC_FAIL_ITER_DICT_KEYS;
3134+
}
3135+
else if (tp == &PySet_Type) {
3136+
kind = SPEC_FAIL_ITER_SET;
3137+
}
3138+
else if (tp == &PyBytes_Type) {
3139+
kind = SPEC_FAIL_ITER_BYTES;
3140+
}
3141+
else if (tp == &PyEnum_Type) {
3142+
kind = SPEC_FAIL_ITER_ENUMERATE;
3143+
}
3144+
else if (tp == &PyUnicode_Type) {
3145+
kind = SPEC_FAIL_ITER_STRING;
3146+
}
3147+
else if (tp == &PyGen_Type) {
3148+
kind = SPEC_FAIL_ITER_GENERATOR;
3149+
}
3150+
else if (tp == &PyCoro_Type) {
3151+
kind = SPEC_FAIL_ITER_COROUTINE;
3152+
}
3153+
else if (tp == &PyAsyncGen_Type) {
3154+
kind = SPEC_FAIL_ITER_ASYNC_GENERATOR;
3155+
}
3156+
else if (tp == &_PyAsyncGenASend_Type) {
3157+
kind = SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND;
3158+
}
3159+
else if (tp->tp_iter == PyObject_SelfIter) {
3160+
kind = SPEC_FAIL_ITER_SELF;
3161+
}
3162+
SPECIALIZATION_FAIL(GET_ITER, kind);
3163+
}
3164+
#endif
3165+
3166+
31183167
/* Code init cleanup.
31193168
* CALL_ALLOC_AND_ENTER_INIT will set up
31203169
* the frame to execute the EXIT_INIT_CHECK

Tools/scripts/summarize_stats.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ def kind_to_text(kind: int, opcode: str):
288288
opcode = "SUPER"
289289
elif opcode.endswith("ATTR"):
290290
opcode = "ATTR"
291-
elif opcode in ("FOR_ITER", "SEND"):
291+
elif opcode in ("FOR_ITER", "GET_ITER", "SEND"):
292292
opcode = "ITER"
293293
elif opcode.endswith("SUBSCR"):
294294
opcode = "SUBSCR"

0 commit comments

Comments
 (0)