]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-100239: more refined specialisation stats for BINARY_OP/SUBSCR (#132068)
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Fri, 4 Apr 2025 14:33:31 +0000 (15:33 +0100)
committerGitHub <noreply@github.com>
Fri, 4 Apr 2025 14:33:31 +0000 (15:33 +0100)
Include/cpython/pystats.h
Python/specialize.c
Tools/scripts/summarize_stats.py

index 4421b4d6e91dad4de7da879c1183e3fdafdeb098..f16391f8437ec11ed3180fd539e74721c336801b 100644 (file)
@@ -31,7 +31,7 @@
 
 #define PYSTATS_MAX_UOP_ID 512
 
-#define SPECIALIZATION_FAILURE_KINDS 37
+#define SPECIALIZATION_FAILURE_KINDS 44
 
 /* Stats for determining who is calling PyEval_EvalFrame */
 #define EVAL_CALL_TOTAL 0
index ac847b7c752b2823ae3c3867a858208409ba6c22..e7924aa711efa328d6b01ad01e7969bc170c6ba3 100644 (file)
@@ -597,6 +597,13 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
 #define SPEC_FAIL_BINARY_OP_SUBSCR_TUPLE_SLICE          35
 #define SPEC_FAIL_BINARY_OP_SUBSCR_STRING_SLICE         36
 #define SPEC_FAIL_BINARY_OP_SUBSCR_NOT_HEAP_TYPE        37
+#define SPEC_FAIL_BINARY_OP_SUBSCR_OTHER_SLICE          38
+#define SPEC_FAIL_BINARY_OP_SUBSCR_MAPPINGPROXY         39
+#define SPEC_FAIL_BINARY_OP_SUBSCR_RE_MATCH             40
+#define SPEC_FAIL_BINARY_OP_SUBSCR_ARRAY                41
+#define SPEC_FAIL_BINARY_OP_SUBSCR_DEQUE                42
+#define SPEC_FAIL_BINARY_OP_SUBSCR_ENUMDICT             43
+#define SPEC_FAIL_BINARY_OP_SUBSCR_STACKSUMMARY         44
 
 /* Calls */
 
@@ -2358,6 +2365,34 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
                 }
             }
             Py_XDECREF(descriptor);
+
+            if (PyObject_TypeCheck(lhs, &PyDictProxy_Type)) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_MAPPINGPROXY;
+            }
+
+            if (strcmp(container_type->tp_name, "array.array") == 0) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_ARRAY;
+            }
+
+            if (strcmp(container_type->tp_name, "re.Match") == 0) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_RE_MATCH;
+            }
+
+            if (strcmp(container_type->tp_name, "collections.deque") == 0) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_DEQUE;
+            }
+
+            if (strcmp(_PyType_Name(container_type), "EnumDict") != 0) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_ENUMDICT;
+            }
+
+            if (strcmp(container_type->tp_name, "StackSummary") != 0) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_STACKSUMMARY;
+            }
+
+            if (PySlice_Check(rhs)) {
+                return SPEC_FAIL_BINARY_OP_SUBSCR_OTHER_SLICE;
+            }
             return SPEC_FAIL_BINARY_OP_SUBSCR;
     }
     Py_UNREACHABLE();
index 4243b53850b3de9089c3abad21cc3e0787c9f5e0..eb54b8dd115c947b37e16bfcb0d1a7de94c2dd57 100644 (file)
@@ -298,12 +298,20 @@ class OpcodeStats:
             return "kind " + str(kind)
 
         family_stats = self._get_stats_for_opcode(opcode)
-        failure_kinds = [0] * 40
+
+        def key_to_index(key):
+            return int(key[:-1].split("[")[1])
+
+        max_index = 0
+        for key in family_stats:
+            if key.startswith("specialization.failure_kind"):
+                max_index = max(max_index, key_to_index(key))
+
+        failure_kinds = [0] * (max_index + 1)
         for key in family_stats:
             if not key.startswith("specialization.failure_kind"):
                 continue
-            index = int(key[:-1].split("[")[1])
-            failure_kinds[index] = family_stats[key]
+            failure_kinds[key_to_index(key)] = family_stats[key]
         return {
             kind_to_text(index, opcode): value
             for (index, value) in enumerate(failure_kinds)