Skip to content

Commit 2373aee

Browse files
trace over everything except backwards jumps
1 parent 5cec130 commit 2373aee

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

Python/bytecodes.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5666,10 +5666,19 @@ dummy_func(
56665666
PyCodeObject *code = _PyFrame_GetCode(frame);
56675667
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
56685668
int orig_opcode = executor->vm_data.opcode;
5669-
// Function entry, trace over it to form a longer trace.
5670-
if (orig_opcode == RESUME_CHECK_JIT || orig_opcode == RESUME) {
5669+
// Not backwards jump, trace over it to form a longer trace.
5670+
if (orig_opcode != JUMP_BACKWARD_JIT &&
5671+
orig_opcode != JUMP_BACKWARD &&
5672+
orig_opcode != JUMP_BACKWARD_NO_INTERRUPT &&
5673+
orig_opcode != JUMP_BACKWARD_NO_JIT) {
5674+
assert(executor->vm_data.index == INSTR_OFFSET());
5675+
assert(executor->vm_data.code == code);
5676+
assert(executor->vm_data.valid);
56715677
oparg = (oparg & ~255) | executor->vm_data.oparg;
56725678
opcode = orig_opcode;
5679+
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) {
5680+
PAUSE_ADAPTIVE_COUNTER(next_instr[1].counter);
5681+
}
56735682
DISPATCH_GOTO_NON_TRACING();
56745683
}
56755684
_PyJit_translate_single_bytecode_to_trace(tstate, frame, NULL, _EXIT_TRACE);

Python/generated_cases.c.h

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -646,25 +646,38 @@ _PyJit_translate_single_bytecode_to_trace(
646646
int oparg = _tstate->jit_tracer_state.prev_state.instr_oparg;
647647
int opcode = this_instr->op.code;
648648

649+
// Loop back to the start
650+
int is_first_instr = _tstate->jit_tracer_state.initial_state.close_loop_instr == next_instr ||
651+
_tstate->jit_tracer_state.initial_state.start_instr == next_instr;
649652
if (stop_tracing_opcode == _DEOPT) {
650653
// gh-143183: It's important we rewind to the last known proper target.
651654
// The current target might be garbage as stop tracing usually indicates
652655
// we are in something that we can't trace.
653-
DPRINTF(2, "Told to stop tracing\n");
656+
DPRINTF(2, "Told to stop tracing. Reason: %s\n", _PyOpcode_OpName[next_instr->op.code]);
654657
goto unsupported;
655658
}
656-
else if (stop_tracing_opcode != 0) {
659+
if (stop_tracing_opcode != 0) {
657660
assert(stop_tracing_opcode == _EXIT_TRACE);
658-
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
661+
if (is_first_instr) {
662+
ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, target);
663+
}
664+
else {
665+
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, target);
666+
}
659667
goto done;
660668
}
661669

662-
// Function entry executor, trace over it to form a longer trace.
670+
// Executor, trace over it to form a longer trace.
663671
// Otherwise, we end up with fragmented loop traces that have bad performance.
672+
// The only exception is if we see another loop trace. In that case, we link to it.
664673
if (opcode == ENTER_EXECUTOR) {
674+
DPRINTF(2, "ENTER_EXECUTOR seen\n");
665675
_PyExecutorObject *executor = old_code->co_executors->executors[oparg & 255];
666676
int orig_opcode = executor->vm_data.opcode;
667-
assert(orig_opcode == RESUME_CHECK_JIT || orig_opcode == RESUME);
677+
assert(orig_opcode != JUMP_BACKWARD_JIT &&
678+
orig_opcode != JUMP_BACKWARD &&
679+
orig_opcode != JUMP_BACKWARD_NO_INTERRUPT &&
680+
orig_opcode != JUMP_BACKWARD_NO_JIT);
668681
oparg = (oparg & ~255) | executor->vm_data.oparg;
669682
opcode = orig_opcode;
670683
}
@@ -822,7 +835,6 @@ _PyJit_translate_single_bytecode_to_trace(
822835
_Py_CODEUNIT *computed_jump_instr = computed_next_instr_without_modifiers + oparg;
823836
assert(next_instr == computed_next_instr || next_instr == computed_jump_instr);
824837
int jump_happened = computed_jump_instr == next_instr;
825-
assert(jump_happened == (target_instr[1].cache & 1));
826838
uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_happened];
827839
ADD_TO_TRACE(uopcode, 0, 0, INSTR_IP(jump_happened ? computed_next_instr : computed_jump_instr, old_code));
828840
break;
@@ -993,9 +1005,6 @@ _PyJit_translate_single_bytecode_to_trace(
9931005
}
9941006
ADD_TO_TRACE(guard_ip, 0, (uintptr_t)next_instr, 0);
9951007
}
996-
// Loop back to the start
997-
int is_first_instr = _tstate->jit_tracer_state.initial_state.close_loop_instr == next_instr ||
998-
_tstate->jit_tracer_state.initial_state.start_instr == next_instr;
9991008
if (is_first_instr && _tstate->jit_tracer_state.prev_state.code_curr_size > CODE_SIZE_NO_PROGRESS) {
10001009
if (needs_guard_ip) {
10011010
ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)next_instr, 0);
@@ -1764,7 +1773,7 @@ _Py_ExecutorDetach(_PyExecutorObject *executor)
17641773
assert(instruction->op.code == ENTER_EXECUTOR);
17651774
int index = instruction->op.arg;
17661775
assert(code->co_executors->executors[index] == executor);
1767-
instruction->op.code = executor->vm_data.opcode;
1776+
instruction->op.code = _PyOpcode_Deopt[executor->vm_data.opcode];
17681777
instruction->op.arg = executor->vm_data.oparg;
17691778
executor->vm_data.code = NULL;
17701779
code->co_executors->executors[index] = NULL;

0 commit comments

Comments
 (0)