From fd3bb482885d6703e55570af86669978b9f517b6 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 23 Sep 2025 23:27:01 +0100 Subject: [PATCH] Point to previous executor when side-exiting --- Include/internal/pycore_interp_structs.h | 2 +- Include/internal/pycore_optimizer.h | 2 +- Python/bytecodes.c | 4 ++-- Python/executor_cases.c.h | 2 +- Python/generated_cases.c.h | 24 +++--------------------- Python/optimizer.c | 9 +++++++-- 6 files changed, 15 insertions(+), 28 deletions(-) diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 5834a6f8edda..9671325362d5 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -953,7 +953,7 @@ struct _is { int jit_tracer_initial_chain_depth; PyCodeObject *jit_tracer_initial_code; // Borrowed PyFunctionObject *jit_tracer_initial_func; // Borrowed - int jit_tracer_seen_initial_before; + struct _PyExitData *jit_tracer_previous_exit; bool jit_completed_loop; bool jit; bool compiling; diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 5dc0a3426869..79b1931d0704 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -371,7 +371,7 @@ _PyJIT_translate_single_bytecode_to_trace( int jump_taken); void -_PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int curr_stackdepth, int chain_depth); +_PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int curr_stackdepth, int chain_depth, _PyExitData *exit); #ifdef __cplusplus } #endif diff --git a/Python/bytecodes.c b/Python/bytecodes.c index e0150aafaf52..d033900c3083 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2978,7 +2978,7 @@ dummy_func( DISPATCH(); } } - _PyJIT_InitializeTracing(tstate, frame, next_instr, STACK_LEVEL(), 0); + _PyJIT_InitializeTracing(tstate, frame, next_instr, STACK_LEVEL(), 0, NULL); ENTER_TRACING(); // Don't add the JUMP_BACKWARD_JIT instruction to the trace. DISPATCH(); @@ -5456,7 +5456,7 @@ dummy_func( _PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit); assert(tstate->current_executor == (PyObject *)previous_executor); int chain_depth = is_dynamic ? 0 : current_executor->vm_data.chain_depth + 1; - _PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth); + _PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth, exit); GOTO_TIER_ONE(target, 1); } } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 56a1c9b7a52e..d4c7c6ad5687 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -7540,7 +7540,7 @@ _PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit); assert(tstate->current_executor == (PyObject *)previous_executor); int chain_depth = is_dynamic ? 0 : current_executor->vm_data.chain_depth + 1; - _PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth); + _PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth, exit); GOTO_TIER_ONE(target, 1); } break; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 92ddfeb3a982..229d75a8dc0d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5976,25 +5976,7 @@ next_instr = this_instr; DISPATCH_GOTO(); } - OPT_STAT_INC(traces_executed); \ - next_instr = _Py_jit_entry((executor), frame, stack_pointer, tstate); \ - frame = tstate->current_frame; \ - stack_pointer = _PyFrame_GetStackPointer(frame); \ - int keep_tracing_bit = (uintptr_t)next_instr & 1; \ - next_instr = (_Py_CODEUNIT *)(((uintptr_t)next_instr) >> 1 << 1); \ - if (next_instr == NULL) { \ - next_instr = frame->instr_ptr; \ - JUMP_TO_LABEL(error); \ - } \ - if (keep_tracing_bit) { \ - assert(next_instr->op.code != ENTER_EXECUTOR); \ - assert(tstate->interp->jit_tracer_code_curr_size == 2); \ - ENTER_TRACING(); \ - } \ - else { \ - LEAVE_TRACING(); \ - } \ - DISPATCH(); + TIER1_TO_TIER2(executor); #else Py_FatalError("ENTER_EXECUTOR is not supported in this build"); #endif /* _Py_TIER2 */ @@ -8424,7 +8406,7 @@ DISPATCH(); } } - _PyJIT_InitializeTracing(tstate, frame, next_instr, STACK_LEVEL(), 0); + _PyJIT_InitializeTracing(tstate, frame, next_instr, STACK_LEVEL(), 0, NULL); ENTER_TRACING(); DISPATCH(); } @@ -22090,7 +22072,7 @@ TRACING_DISPATCH(); } } - _PyJIT_InitializeTracing(tstate, frame, next_instr, STACK_LEVEL(), 0); + _PyJIT_InitializeTracing(tstate, frame, next_instr, STACK_LEVEL(), 0, NULL); ENTER_TRACING(); TRACING_DISPATCH(); } diff --git a/Python/optimizer.c b/Python/optimizer.c index 7789558a29b9..8c7028b2a5a3 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -161,6 +161,11 @@ _PyOptimizer_Optimize( else { executor->vm_data.code = NULL; } + if (chain_depth > 0) { + _PyExitData *prev_exit = tstate->interp->jit_tracer_previous_exit; + assert(prev_exit != NULL); + prev_exit->executor = executor;; + } executor->vm_data.chain_depth = chain_depth; assert(executor->vm_data.valid); interp->compiling = false; @@ -808,7 +813,7 @@ full: } void -_PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int curr_stackdepth, int chain_depth) +_PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int curr_stackdepth, int chain_depth, _PyExitData *exit) { PyCodeObject *code = _PyFrame_GetCode(frame); #ifdef Py_DEBUG @@ -831,7 +836,7 @@ _PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_ tstate->interp->jit_tracer_initial_instr = next_instr; tstate->interp->jit_tracer_initial_code = code; tstate->interp->jit_tracer_initial_func = _PyFrame_GetFunction(frame); - tstate->interp->jit_tracer_seen_initial_before = 0; + tstate->interp->jit_tracer_previous_exit = exit; memset(&tstate->interp->jit_tracer_dependencies.bits, 0, sizeof(tstate->interp->jit_tracer_dependencies.bits)); tstate->interp->jit_completed_loop = false; tstate->interp->jit_tracer_initial_stack_depth = curr_stackdepth; -- 2.47.3