Skip to content

Commit 5cec130

Browse files
trace over RESUME/RESUME_CHECK_JIT
1 parent 96ea93a commit 5cec130

File tree

4 files changed

+45
-18
lines changed

4 files changed

+45
-18
lines changed

Python/bytecodes.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,7 +3041,7 @@ dummy_func(
30413041
#ifdef _Py_TIER2
30423042
if (IS_JIT_TRACING()) {
30433043
next_instr = this_instr;
3044-
goto stop_tracing;
3044+
goto consider_stop_tracing;
30453045
}
30463046
PyCodeObject *code = _PyFrame_GetCode(frame);
30473047
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
@@ -5659,10 +5659,19 @@ dummy_func(
56595659
#endif
56605660
}
56615661

5662-
label(stop_tracing) {
5662+
label(consider_stop_tracing) {
56635663
#if _Py_TIER2
56645664
assert(IS_JIT_TRACING());
56655665
int opcode = next_instr->op.code;
5666+
PyCodeObject *code = _PyFrame_GetCode(frame);
5667+
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
5668+
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) {
5671+
oparg = (oparg & ~255) | executor->vm_data.oparg;
5672+
opcode = orig_opcode;
5673+
DISPATCH_GOTO_NON_TRACING();
5674+
}
56665675
_PyJit_translate_single_bytecode_to_trace(tstate, frame, NULL, _EXIT_TRACE);
56675676
LEAVE_TRACING();
56685677
int err = stop_tracing_and_jit(tstate, frame);

Python/generated_cases.c.h

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

Python/opcode_targets.h

Lines changed: 1 addition & 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: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,29 @@ _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+
if (stop_tracing_opcode == _DEOPT) {
650+
// gh-143183: It's important we rewind to the last known proper target.
651+
// The current target might be garbage as stop tracing usually indicates
652+
// we are in something that we can't trace.
653+
DPRINTF(2, "Told to stop tracing\n");
654+
goto unsupported;
655+
}
656+
else if (stop_tracing_opcode != 0) {
657+
assert(stop_tracing_opcode == _EXIT_TRACE);
658+
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
659+
goto done;
660+
}
661+
662+
// Function entry executor, trace over it to form a longer trace.
663+
// Otherwise, we end up with fragmented loop traces that have bad performance.
664+
if (opcode == ENTER_EXECUTOR) {
665+
_PyExecutorObject *executor = old_code->co_executors->executors[oparg & 255];
666+
int orig_opcode = executor->vm_data.opcode;
667+
assert(orig_opcode == RESUME_CHECK_JIT || orig_opcode == RESUME);
668+
oparg = (oparg & ~255) | executor->vm_data.oparg;
669+
opcode = orig_opcode;
670+
}
671+
649672
int rewind_oparg = oparg;
650673
while (rewind_oparg > 255) {
651674
rewind_oparg >>= 8;
@@ -699,19 +722,6 @@ _PyJit_translate_single_bytecode_to_trace(
699722
goto full;
700723
}
701724

702-
if (stop_tracing_opcode == _DEOPT) {
703-
// gh-143183: It's important we rewind to the last known proper target.
704-
// The current target might be garbage as stop tracing usually indicates
705-
// we are in something that we can't trace.
706-
DPRINTF(2, "Told to stop tracing\n");
707-
goto unsupported;
708-
}
709-
else if (stop_tracing_opcode != 0) {
710-
assert(stop_tracing_opcode == _EXIT_TRACE);
711-
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
712-
goto done;
713-
}
714-
715725
assert(stop_tracing_opcode == 0);
716726

717727
#ifdef Py_DEBUG

0 commit comments

Comments
 (0)