mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-141786 Fix missing parent executor during trace
An executor's trace can point to another executor, forming a graph of traces / executors. Sometimes it is possible while recording a trace that the parent executor is freed / invalidated halfway. This leads to the bug described in the issue gh-141786, which if left unfixed could cause a memory leak. This patch checks for the validity of the parent executor as well as allowing JIT from the cold executor. While the cold executor is not linked, it is the executor responsible for creating side traces and we still want to JIT from it.
This commit is contained in:
parent
53ec7c8fc0
commit
63662b9178
2 changed files with 11 additions and 2 deletions
|
|
@ -1408,7 +1408,9 @@ stop_tracing_and_jit(PyThreadState *tstate, _PyInterpreterFrame *frame)
|
|||
// Likewise, we hold a strong reference to the executor containing this exit, so the exit is guaranteed
|
||||
// to be valid to access.
|
||||
if (err <= 0) {
|
||||
exit->temperature = restart_backoff_counter(exit->temperature);
|
||||
if (exit->executor->vm_data.linked || exit->executor->vm_data.valid) {
|
||||
exit->temperature = restart_backoff_counter(exit->temperature);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exit->temperature = initial_temperature_backoff_counter();
|
||||
|
|
|
|||
|
|
@ -140,6 +140,14 @@ _PyOptimizer_Optimize(
|
|||
}
|
||||
assert(!interp->compiling);
|
||||
assert(_tstate->jit_tracer_state.initial_state.stack_depth >= 0);
|
||||
_PyExitData *exit = _tstate->jit_tracer_state.initial_state.exit;
|
||||
_PyExecutorObject *cold_executor = _PyExecutor_GetColdExecutor();
|
||||
if (exit != NULL &&
|
||||
(!exit->executor->vm_data.linked || !exit->executor->vm_data.valid) &&
|
||||
exit->executor != cold_executor) {
|
||||
// gh-141786 Parent executor is either unlinked or invalid - cannot optimize.
|
||||
return 0;
|
||||
}
|
||||
#ifndef Py_GIL_DISABLED
|
||||
assert(_tstate->jit_tracer_state.initial_state.func != NULL);
|
||||
interp->compiling = true;
|
||||
|
|
@ -185,7 +193,6 @@ _PyOptimizer_Optimize(
|
|||
else {
|
||||
executor->vm_data.code = NULL;
|
||||
}
|
||||
_PyExitData *exit = _tstate->jit_tracer_state.initial_state.exit;
|
||||
if (exit != NULL) {
|
||||
exit->executor = executor;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue