From fac8c748a5baefd1c3272bf53a9d3372df726bf5 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 23 Sep 2025 23:17:36 +0100 Subject: [PATCH] fix problem with jumping labels --- Python/ceval_macros.h | 3 +-- Python/generated_cases.c.h | 20 +++++++++++++++++++- Python/optimizer.c | 19 +++++++++---------- Python/optimizer_analysis.c | 6 +++--- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 540785414e73..b15b67882059 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -132,8 +132,7 @@ #define TRACING_JUMP_TO_LABEL(label) \ RECORD_JUMP_TAKEN() \ - RECORD_TRACE() \ - BAIL_TRACING_NO_DISPATCH() \ + RECORD_TRACE_NO_DISPATCH() \ JUMP_TO_LABEL(label); #if _Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 1f77215f5822..92ddfeb3a982 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5976,7 +5976,25 @@ next_instr = this_instr; DISPATCH_GOTO(); } - TIER1_TO_TIER2(executor); + 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(); #else Py_FatalError("ENTER_EXECUTOR is not supported in this build"); #endif /* _Py_TIER2 */ diff --git a/Python/optimizer.c b/Python/optimizer.c index 1badc9127987..7789558a29b9 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -607,9 +607,12 @@ _PyJIT_translate_single_bytecode_to_trace( !(opcode == JUMP_BACKWARD_NO_INTERRUPT || opcode == JUMP_BACKWARD || opcode == JUMP_BACKWARD_JIT) && !(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_NONE || opcode == POP_JUMP_IF_NOT_NONE); + assert(opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG); + + const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; - // Strange control-flow - if (jump_taken || opcode == WITH_EXCEPT_START || opcode == RERAISE || opcode == CLEANUP_THROW || opcode == PUSH_EXC_INFO) { + // Strange control-flow, unsupported opcode, etc. + if (jump_taken || expansion->nuops == 0 || opcode == WITH_EXCEPT_START || opcode == RERAISE || opcode == CLEANUP_THROW || opcode == PUSH_EXC_INFO) { // Rewind to previous instruction and replace with _EXIT_TRACE. _PyUOpInstruction *curr = &trace[trace_length-1]; while (curr->opcode != _SET_IP && trace_length > 1) { @@ -620,10 +623,6 @@ _PyJIT_translate_single_bytecode_to_trace( curr->opcode = _EXIT_TRACE; goto done; } - - assert(opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG); - - const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; RESERVE_RAW(expansion->nuops + needs_guard_ip + 3, "uop and various checks"); ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target); @@ -692,12 +691,9 @@ _PyJIT_translate_single_bytecode_to_trace( default: { const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; - if (expansion->nuops == 0) { - DPRINTF(2, "Unsupported opcode %s\n", _PyOpcode_OpName[opcode]); - goto full; - } // Reserve space for nuops (+ _SET_IP + _EXIT_TRACE) int nuops = expansion->nuops; + assert(nuops > 0); RESERVE(nuops + 1); /* One extra for exit */ uint32_t orig_oparg = oparg; // For OPARG_TOP/BOTTOM for (int i = 0; i < nuops; i++) { @@ -906,6 +902,9 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length) for (int i = 0; i < length; i++) { _PyUOpInstruction *inst = &buffer[i]; int opcode = inst->opcode; + if (inst->format != UOP_FORMAT_TARGET) { + fprintf(stdout, "I: %d\n", i); + } int32_t target = (int32_t)uop_get_target(inst); uint16_t exit_flags = _PyUop_Flags[opcode] & (HAS_EXIT_FLAG | HAS_DEOPT_FLAG | HAS_PERIODIC_FLAG); if (exit_flags) { diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 1bb52188fba4..b90575abf51c 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -528,12 +528,12 @@ _Py_uop_analyze_and_optimize( { OPT_STAT_INC(optimizer_attempts); - // length = optimize_uops( + // int err = optimize_uops( // _PyFrame_GetFunction(frame), buffer, // length, curr_stacklen, dependencies); // - // if (length == 0) { - // return length; + // if (err == 0) { + // return err; // } assert(length > 0); -- 2.47.3