summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-02-02 15:56:47 (GMT)
committerGitHub <noreply@github.com>2022-02-02 15:56:47 (GMT)
commit0d05da1fbf39f32d2c22a1f3702f40f916997b60 (patch)
tree832794ca2c6f84e807f82289a7fa45487493ccd7 /Python
parentf66c857572a308822c70fd25e0197b6e0dec6e34 (diff)
downloadcpython-0d05da1fbf39f32d2c22a1f3702f40f916997b60.zip
cpython-0d05da1fbf39f32d2c22a1f3702f40f916997b60.tar.gz
cpython-0d05da1fbf39f32d2c22a1f3702f40f916997b60.tar.bz2
Add specialization stats for FOR_ITER. (GH-31079)
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c5
-rw-r--r--Python/specialize.c68
2 files changed, 73 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 70748e8..3c52c58 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4212,6 +4212,11 @@ handle_eval_breaker:
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);
diff --git a/Python/specialize.c b/Python/specialize.c
index 9290fbe..d90d7da 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -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 @@ success:
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;
+}