From 439c21beaa0ae823acbe0ea5cca17b9344c2a97e Mon Sep 17 00:00:00 2001 From: Bhuvansh Date: Wed, 22 Jul 2026 14:47:47 +0530 Subject: [PATCH] gh-154014: Initialize cold executor vm_data fields (GH-154142) (cherry picked from commit d1174a48ea8fda8bd0057f10e9776ec148276100) Co-authored-by: Bhuvansh --- Lib/test/test_capi/test_opt.py | 10 ++++++++++ .../2026-07-19-16-18-25.gh-issue-154014.CJsjVL.rst | 2 ++ Python/optimizer.c | 7 ++++++- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-16-18-25.gh-issue-154014.CJsjVL.rst diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 9f0427172b5048e..b2439dfdeb7a221 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -5102,6 +5102,16 @@ def f(): f" {executor} at offset {idx} rather" f" than expected _EXIT_TRACE") + def test_jit_shutdown_after_cold_executor_creation(self): + script_helper.assert_python_ok("-c", textwrap.dedent(f""" + def f(): + for x in range({TIER2_THRESHOLD + 3}): + for y in range({TIER2_THRESHOLD + 3}): + z = x + y + + f() + """), PYTHON_JIT="1") + def test_enter_executor_valid_op_arg(self): script_helper.assert_python_ok("-c", textwrap.dedent(""" import sys diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-16-18-25.gh-issue-154014.CJsjVL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-16-18-25.gh-issue-154014.CJsjVL.rst new file mode 100644 index 000000000000000..6bdcf83725168a2 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-16-18-25.gh-issue-154014.CJsjVL.rst @@ -0,0 +1,2 @@ +Fix a JIT assertion during interpreter shutdown by initializing ``vm_data`` +fields for cold executors that bypass ``_Py_ExecutorInit()``. diff --git a/Python/optimizer.c b/Python/optimizer.c index db258fff22cdd13..a39d0494ddc5d5b 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1830,6 +1830,11 @@ make_cold_executor(uint16_t opcode) Py_FatalError("Cannot allocate core JIT code"); } ((_PyUOpInstruction *)cold->trace)->opcode = opcode; + // Cold executors bypass _Py_ExecutorInit(). + cold->vm_data.valid = true; + cold->vm_data.pending_deletion = 0; + cold->vm_data.code = NULL; + // This is initialized to false so we can prevent the executor // from being immediately detected as cold and invalidated. cold->vm_data.cold = false; @@ -1837,7 +1842,7 @@ make_cold_executor(uint16_t opcode) cold->jit_code = NULL; cold->jit_size = 0; if (_PyJIT_Compile(cold, cold->trace, 1)) { - Py_DECREF(cold); + _PyExecutor_Free(cold); Py_FatalError("Cannot allocate core JIT code"); } #endif