gh-152192: Fix JUMP_BACKWARD passing a truncated oparg to the jit tracer#152382
gh-152192: Fix JUMP_BACKWARD passing a truncated oparg to the jit tracer#152382deadlovelll wants to merge 1 commit into
Conversation
| ext, jb = next((p, i) for p, i in zip(instrs, instrs[1:]) | ||
| if i.opname == "JUMP_BACKWARD" and p.opname == "EXTENDED_ARG") | ||
|
|
||
| f(TIER2_THRESHOLD + 1) |
There was a problem hiding this comment.
I want to clarify a little bit about this test.
When the jit counter is enabled we enter into _JIT op with original oparg = 299
Then oparg truncates with buggy loop
while (oparg > 255) {
oparg >>= 8
insert_exec_at--;
}oparg becomes 1, and we pass it to _PyJit_TryInitializeTracing
In _PyJit_TryInitializeTracing we store this broken oparg
tracer->prev_state.instr_oparg = oparg;And call ENTER_TRACING()
In next calls code uses TRACE_RECORD which in turn calls _PyJit_translate_single_bytecode_to_trace. This is the point where shift exists
// Rewind EXTENDED_ARG so that we see the whole thing.
// We must point to the first EXTENDED_ARG when deopting.
int oparg = tracer->prev_state.instr_oparg;
int opcode = this_instr->op.code;
int rewind_oparg = oparg;
while (rewind_oparg > 255) {
rewind_oparg >>= 8;
target--;
}We get the broken oparg from tracer->prev_state.instr_oparg and the loop does not executes because 1 < 255. target does not decrements and the instruction is not correct (should be EXTENDED_ARG but actually JUMP_BACKWARD)
P.S: I may not be fully correct in the internals but the test catches the shift on the buggy build
The
_JITop used oparg as the counter in thewhileloop, truncating it before reaching_PyJit_TryInitializeTracing.Fixed it by using a temporary value.
For more details see gh-152192