From 5fd5336b1e1c7e9aa501c5283a9033ea4e23ccf8 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 17 Nov 2025 06:01:34 +0000 Subject: [PATCH 1/4] Fix clearing of executors --- Python/optimizer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index 9db894f0bf054a..17a0e0b1789af6 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1669,12 +1669,14 @@ executor_clear(PyObject *op) * free the executor unless we hold a strong reference to it */ _PyExecutorObject *cold = _PyExecutor_GetColdExecutor(); + _PyExecutorObject *cold_dynamic = _PyExecutor_GetColdDynamicExecutor(); Py_INCREF(executor); for (uint32_t i = 0; i < executor->exit_count; i++) { executor->exits[i].temperature = initial_unreachable_backoff_counter(); _PyExecutorObject *e = executor->exits[i].executor; - executor->exits[i].executor = cold; - Py_DECREF(e); + if (e != cold && e != cold_dynamic) { + executor_clear(e); + } } _Py_ExecutorDetach(executor); Py_DECREF(executor); From 1b99fc19fdd85f6981c56a6d10d8bdb74056eb60 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 17 Nov 2025 06:02:53 +0000 Subject: [PATCH 2/4] set to NULL first --- Python/optimizer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/optimizer.c b/Python/optimizer.c index 17a0e0b1789af6..ce3b75514bc612 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1674,6 +1674,7 @@ executor_clear(PyObject *op) for (uint32_t i = 0; i < executor->exit_count; i++) { executor->exits[i].temperature = initial_unreachable_backoff_counter(); _PyExecutorObject *e = executor->exits[i].executor; + executor->exits[i].executor = NULL; if (e != cold && e != cold_dynamic) { executor_clear(e); } From 9db863886dbbc1c2e43aca762c3fdbc5cdcad8fd Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 17 Nov 2025 11:12:09 +0000 Subject: [PATCH 3/4] Update Python/optimizer.c Co-authored-by: Mikhail Efimov --- Python/optimizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index ce3b75514bc612..f8c10d1bf19f15 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1676,7 +1676,7 @@ executor_clear(PyObject *op) _PyExecutorObject *e = executor->exits[i].executor; executor->exits[i].executor = NULL; if (e != cold && e != cold_dynamic) { - executor_clear(e); + executor_clear((PyObject *)e); } } _Py_ExecutorDetach(executor); From d0d495f2ba34260b695a3acdff0a927ba922dc26 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 17 Nov 2025 19:25:57 +0000 Subject: [PATCH 4/4] slight fix --- Python/optimizer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index f8c10d1bf19f15..152e9c65e495d3 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1675,7 +1675,9 @@ executor_clear(PyObject *op) executor->exits[i].temperature = initial_unreachable_backoff_counter(); _PyExecutorObject *e = executor->exits[i].executor; executor->exits[i].executor = NULL; - if (e != cold && e != cold_dynamic) { + // Only clear side exit executors in the chain, not + // those that have progress (inserted into bytecode). + if (e != cold && e != cold_dynamic && e->vm_data.code != NULL) { executor_clear((PyObject *)e); } }