Skip to content

Commit a7fcf24

Browse files
Close loops properly, don't trace into nested loops
1 parent e4f1624 commit a7fcf24

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

Python/optimizer.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ _PyJit_translate_single_bytecode_to_trace(
564564
int jump_taken)
565565
{
566566

567-
int is_first_instr = tstate->interp->jit_state.close_loop_instr == this_instr;
568567
bool progress_needed = (tstate->interp->jit_state.initial_chain_depth % MAX_CHAIN_DEPTH) == 0;;
569568
_PyBloomFilter *dependencies = &tstate->interp->jit_state.dependencies;
570569
_Py_BloomFilter_Add(dependencies, old_code);
@@ -685,12 +684,6 @@ _PyJit_translate_single_bytecode_to_trace(
685684
assert(!OPCODE_HAS_DEOPT(opcode));
686685
}
687686

688-
// Loop back to the start
689-
if (is_first_instr && tstate->interp->jit_state.code_curr_size > 5) {
690-
ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0);
691-
goto done;
692-
}
693-
694687
if (OPCODE_HAS_EXIT(opcode)) {
695688
// Make space for side exit and final _EXIT_TRACE:
696689
max_length--;
@@ -725,7 +718,21 @@ _PyJit_translate_single_bytecode_to_trace(
725718
ADD_TO_TRACE(_CHECK_PERIODIC, 0, 0, target);
726719
_Py_FALLTHROUGH;
727720
case JUMP_BACKWARD_NO_INTERRUPT:
721+
{
722+
if ((next_instr != tstate->interp->jit_state.close_loop_instr) &&
723+
(next_instr != tstate->interp->jit_state.insert_exec_instr) &&
724+
tstate->interp->jit_state.code_curr_size > 5) {
725+
// We encountered a JUMP_BACKWARD but not to the top of our own loop.
726+
// We don't want to continue tracing as we might get stuck in the
727+
// inner loop. Instead, end the trace where the executor of the
728+
// inner loop might start and let the traces rejoin.
729+
OPT_STAT_INC(inner_loop);
730+
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, target);
731+
DPRINTF(2, "JUMP_BACKWARD not to top ends trace %p %p %p\n", next_instr, tstate->interp->jit_state.close_loop_instr, tstate->interp->jit_state.insert_exec_instr);
732+
goto done;
733+
}
728734
break;
735+
}
729736

730737
case RESUME:
731738
case RESUME_CHECK:
@@ -854,6 +861,12 @@ _PyJit_translate_single_bytecode_to_trace(
854861
if (needs_guard_ip) {
855862
ADD_TO_TRACE(_GUARD_IP, 0, (uintptr_t)next_instr, 0);
856863
}
864+
// Loop back to the start
865+
int is_first_instr = tstate->interp->jit_state.close_loop_instr == next_instr || tstate->interp->jit_state.insert_exec_instr == next_instr;
866+
if (is_first_instr && tstate->interp->jit_state.code_curr_size > 5) {
867+
ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0);
868+
goto done;
869+
}
857870
tstate->interp->jit_state.code_curr_size = trace_length;
858871
tstate->interp->jit_state.code_max_size = max_length;
859872
return 1;

0 commit comments

Comments
 (0)