gh-143183: Rewind stop tracing to previous target (GH-143187)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Ken Jin 2025-12-29 06:12:31 +08:00 committed by GitHub
parent 713684de53
commit daa9aa4c0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 12 deletions

View file

@ -625,6 +625,7 @@ _PyJit_translate_single_bytecode_to_trace(
int trace_length = _tstate->jit_tracer_state.prev_state.code_curr_size;
_PyUOpInstruction *trace = _tstate->jit_tracer_state.code_buffer;
int max_length = _tstate->jit_tracer_state.prev_state.code_max_size;
int exit_op = stop_tracing_opcode == 0 ? _EXIT_TRACE : stop_tracing_opcode;
_Py_CODEUNIT *this_instr = _tstate->jit_tracer_state.prev_state.instr;
_Py_CODEUNIT *target_instr = this_instr;
@ -691,8 +692,11 @@ _PyJit_translate_single_bytecode_to_trace(
}
if (stop_tracing_opcode != 0) {
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
goto done;
// gh-143183: It's important we rewind to the last known proper target.
// The current target might be garbage as stop tracing usually indicates
// we are in something that we can't trace.
DPRINTF(2, "Told to stop tracing\n");
goto unsupported;
}
DPRINTF(2, "%p %d: %s(%d) %d %d\n", old_code, target, _PyOpcode_OpName[opcode], oparg, needs_guard_ip, old_stack_level);
@ -703,10 +707,6 @@ _PyJit_translate_single_bytecode_to_trace(
}
#endif
if (opcode == ENTER_EXECUTOR) {
goto full;
}
if (!_tstate->jit_tracer_state.prev_state.dependencies_still_valid) {
goto full;
}
@ -720,11 +720,6 @@ _PyJit_translate_single_bytecode_to_trace(
if (oparg > 0xFFFF) {
DPRINTF(2, "Unsupported: oparg too large\n");
goto unsupported;
}
// TODO (gh-140277): The constituent use one extra stack slot. So we need to check for headroom.
if (opcode == BINARY_OP_SUBSCR_GETITEM && old_stack_level + 1 > old_code->co_stacksize) {
unsupported:
{
// Rewind to previous instruction and replace with _EXIT_TRACE.
@ -738,7 +733,7 @@ _PyJit_translate_single_bytecode_to_trace(
int32_t old_target = (int32_t)uop_get_target(curr);
curr++;
trace_length++;
curr->opcode = _EXIT_TRACE;
curr->opcode = exit_op;
curr->format = UOP_FORMAT_TARGET;
curr->target = old_target;
}
@ -746,6 +741,7 @@ _PyJit_translate_single_bytecode_to_trace(
}
}
if (opcode == NOP) {
return 1;
}