]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
fix problem with jumping labels
authorKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Tue, 23 Sep 2025 22:17:36 +0000 (23:17 +0100)
committerKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Tue, 23 Sep 2025 22:17:36 +0000 (23:17 +0100)
Python/ceval_macros.h
Python/generated_cases.c.h
Python/optimizer.c
Python/optimizer_analysis.c

index 540785414e7334380721c74a7890c34e5d6944c0..b15b6788205915a398e73fe71ac9bf25fb59560f 100644 (file)
 
 #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
index 1f77215f582219d60ff036cbb9eaddaef59d50e1..92ddfeb3a982f9d203fde611db27e95e129eac91 100644 (file)
                 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 */
index 1badc9127987a3f1b2908dceddd3c63f5a50ce60..7789558a29b9e483624652a1fab13c90ca6cf9d5 100644 (file)
@@ -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) {
index 1bb52188fba48e8bfcd1a305b81db4e98b165f12..b90575abf51cddfb9efa51343330d9fbf03ae724 100644 (file)
@@ -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);