]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-145064: Fix JIT assertion failure during CALL_ALLOC_AND_ENTER_INIT side exit...
authorHai Zhu <haiizhu@outlook.com>
Sun, 22 Feb 2026 18:46:03 +0000 (02:46 +0800)
committerGitHub <noreply@github.com>
Sun, 22 Feb 2026 18:46:03 +0000 (18:46 +0000)
Lib/test/test_capi/test_opt.py
Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst [new file with mode: 0644]
Python/optimizer.c

index 7ac71fbfab1fe035b4cdb889188b24135b577e2d..fe1b45608841a294df8b5db5b863f872d94cf3bb 100644 (file)
@@ -4065,6 +4065,55 @@ class TestUopsOptimization(unittest.TestCase):
         self.assertNotIn('_PyJit_TryInitializeTracing', stderr,
                          f"JIT tracer memory leak detected:\n{stderr}")
 
+    def test_cold_exit_on_init_cleanup_frame(self):
+
+        result = script_helper.run_python_until_end('-c', textwrap.dedent("""
+        class A:
+            __slots__ = ('x', 'y', 'z', 'w')
+            def __init__(self):
+                self.x = self.y = -1
+                self.z = self.w = None
+
+        class B(A):
+            __slots__ = ('a', 'b', 'c', 'd', 'e')
+            def __init__(self):
+                super().__init__()
+                self.a = self.b = None
+                self.c = ""
+                self.d = self.e = False
+
+        class C(B):
+            __slots__ = ('name', 'flag')
+            def __init__(self, name):
+                super().__init__()
+                self.name = name
+                self.flag = False
+
+        funcs = []
+        for n in range(20, 80):
+            lines = [f"def f{n}(names, info):"]
+            for j in range(n):
+                lines.append(f"    v{j} = names[{j % 3}]")
+                if j % 3 == 0:
+                    lines.append(f"    if v{j} in info:")
+                    lines.append(f"        v{j} = info[v{j}]")
+                elif j % 5 == 0:
+                    lines.append(f"    v{j} = len(v{j}) if isinstance(v{j}, str) else 0")
+            lines.append("    return C(names[0])")
+            ns = {'C': C}
+            exec("\\n".join(lines), ns)
+            funcs.append(ns[f"f{n}"])
+
+        names = ['alpha', 'beta', 'gamma']
+        info = {'alpha': 'x', 'beta': 'y', 'gamma': 'z'}
+
+        for f in funcs:
+            for _ in range(10):
+                f(names, info)
+        """), PYTHON_JIT="1", PYTHON_JIT_STRESS="1",
+             PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE="1")
+        self.assertEqual(result[0].rc, 0, result)
+
 def global_identity(x):
     return x
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst
new file mode 100644 (file)
index 0000000..1f298e1
--- /dev/null
@@ -0,0 +1 @@
+Fix JIT optimizer assertion failure during ``CALL_ALLOC_AND_ENTER_INIT`` side exit.
index 6a575c8573724a55c341c04cdb986d85dde19f96..f485c27bca2a4fa4ef12f72e87eec9ef2809e752 100644 (file)
@@ -995,7 +995,7 @@ _PyJit_TryInitializeTracing(
         return 0;
     }
     PyObject *func = PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
-    if (func == NULL) {
+    if (func == NULL || !PyFunction_Check(func)) {
         return 0;
     }
     PyCodeObject *code = _PyFrame_GetCode(frame);