]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149217: Avoid adding dependencies on immutable, immortal classes in the JIT (GH149256)
authorWulian233 <1055917385@qq.com>
Sun, 3 May 2026 10:06:39 +0000 (18:06 +0800)
committerGitHub <noreply@github.com>
Sun, 3 May 2026 10:06:39 +0000 (11:06 +0100)
Python/optimizer_analysis.c
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h

index 9f6ce206ef4722c0855e44f38ea441dfbe916526..1dc3a248f45f0c851f700a7747a227fc178680a0 100644 (file)
@@ -156,6 +156,16 @@ type_watcher_callback(PyTypeObject* type)
     return 0;
 }
 
+static void
+watch_type(PyTypeObject *type, _PyBloomFilter *filter)
+{
+    if (_Py_IsImmortal(type) && (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE)) {
+        return;
+    }
+    PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
+    _Py_BloomFilter_Add(filter, type);
+}
+
 static PyObject *
 convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
 {
@@ -367,8 +377,7 @@ optimize_dict_known_hash(
         // for user-defined objects which don't override tp_hash
         Py_hash_t hash = PyObject_Hash(sub);
         ADD_OP(opcode, 0, hash);
-        PyType_Watch(TYPE_WATCHER_ID, (PyObject *)Py_TYPE(sub));
-        _Py_BloomFilter_Add(dependencies, Py_TYPE(sub));
+        watch_type(Py_TYPE(sub), dependencies);
     }
 }
 
@@ -401,8 +410,7 @@ lookup_attr(JitOptContext *ctx, _PyBloomFilter *dependencies, _PyUOpInstruction
                 ADD_OP(suffix, 2, 0);
             }
             if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
-                _Py_BloomFilter_Add(dependencies, type);
+                watch_type(type, dependencies);
             }
             return sym_new_const(ctx, lookup);
         }
@@ -473,10 +481,8 @@ lookup_super_attr(JitOptContext *ctx, _PyBloomFilter *dependencies,
     }
     // if obj_type is immutable, then all its superclasses are immutable
     if ((obj_type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-        PyType_Watch(TYPE_WATCHER_ID, (PyObject *)su_type);
-        _Py_BloomFilter_Add(dependencies, su_type);
-        PyType_Watch(TYPE_WATCHER_ID, (PyObject *)obj_type);
-        _Py_BloomFilter_Add(dependencies, obj_type);
+        watch_type(su_type, dependencies);
+        watch_type(obj_type, dependencies);
     }
     return sym_new_const_steal(ctx, lookup);
 }
index fa34fe4cbb34171cbca1c5cfdaf324460bde8b1c..0837d57b61b29d967b24c025741cfcf8f2888ef3 100644 (file)
@@ -149,10 +149,7 @@ dummy_func(void) {
                 // Promote the probable type version to a known one.
                 sym_set_type(owner, probable_type);
                 sym_set_type_version(owner, type_version);
-                if ((probable_type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                    PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
-                    _Py_BloomFilter_Add(dependencies, probable_type);
-                }
+                watch_type(probable_type, dependencies);
             }
             else {
                 ctx->contradiction = true;
@@ -238,10 +235,7 @@ dummy_func(void) {
             }
             else {
                 sym_set_const(owner, type);
-                if ((((PyTypeObject *)type)->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                    PyType_Watch(TYPE_WATCHER_ID, type);
-                    _Py_BloomFilter_Add(dependencies, type);
-                }
+                watch_type((PyTypeObject *)type, dependencies);
             }
         }
     }
@@ -258,8 +252,7 @@ dummy_func(void) {
                 probable_type->tp_version_tag == type_version) {
                 sym_set_type(owner, probable_type);
                 sym_set_type_version(owner, type_version);
-                PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
-                _Py_BloomFilter_Add(dependencies, probable_type);
+                watch_type(probable_type, dependencies);
             }
             else {
                 ctx->contradiction = true;
@@ -1326,8 +1319,7 @@ dummy_func(void) {
             assert(init != NULL);
             assert(PyFunction_Check(init));
             callable = sym_new_const(ctx, init);
-            PyType_Watch(TYPE_WATCHER_ID, callable_o);
-            _Py_BloomFilter_Add(dependencies, callable_o);;
+            watch_type((PyTypeObject *)callable_o, dependencies);
         }
         else {
             callable = sym_new_not_null(ctx);
@@ -2033,10 +2025,7 @@ dummy_func(void) {
                        0, (uintptr_t)descr);
                 ADD_OP(_SWAP, 3, 0);
                 optimize_pop_top(ctx, this_instr, method_and_self[0]);
-                if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                    PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
-                    _Py_BloomFilter_Add(dependencies, type);
-                }
+                watch_type(type, dependencies);
                 method_and_self[0] = sym_new_const(ctx, descr);
                 optimized = true;
             }
index 553bd7302026f0ea20a208881eda266441aefacf..1ade86f64b2b2066945cc9639966695c3056c88d 100644 (file)
                     probable_type->tp_version_tag == type_version) {
                     sym_set_type(owner, probable_type);
                     sym_set_type_version(owner, type_version);
-                    PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
-                    _Py_BloomFilter_Add(dependencies, probable_type);
+                    watch_type(probable_type, dependencies);
                 }
                 else {
                     ctx->contradiction = true;
                     probable_type->tp_version_tag == type_version) {
                     sym_set_type(owner, probable_type);
                     sym_set_type_version(owner, type_version);
-                    if ((probable_type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                        PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
-                        _Py_BloomFilter_Add(dependencies, probable_type);
-                    }
+                    watch_type(probable_type, dependencies);
                 }
                 else {
                     ctx->contradiction = true;
                 }
                 else {
                     sym_set_const(owner, type);
-                    if ((((PyTypeObject *)type)->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                        PyType_Watch(TYPE_WATCHER_ID, type);
-                        _Py_BloomFilter_Add(dependencies, type);
-                    }
+                    watch_type((PyTypeObject *)type, dependencies);
                 }
             }
             break;
                         0, (uintptr_t)descr);
                     ADD_OP(_SWAP, 3, 0);
                     optimize_pop_top(ctx, this_instr, method_and_self[0]);
-                    if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
-                        PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
-                        _Py_BloomFilter_Add(dependencies, type);
-                    }
+                    watch_type(type, dependencies);
                     method_and_self[0] = sym_new_const(ctx, descr);
                     optimized = true;
                 }
                 assert(PyFunction_Check(init));
                 callable = sym_new_const(ctx, init);
                 stack_pointer[-2 - oparg] = callable;
-                PyType_Watch(TYPE_WATCHER_ID, callable_o);
-                _Py_BloomFilter_Add(dependencies, callable_o);;
+                watch_type((PyTypeObject *)callable_o, dependencies);
             }
             else {
                 callable = sym_new_not_null(ctx);