Skip to content

Commit daa9aa4

Browse files
gh-143183: Rewind stop tracing to previous target (GH-143187)
Co-authored-by: Kumar Aditya <[email protected]>
1 parent 713684d commit daa9aa4

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3306,6 +3306,48 @@ class B: ...
33063306
for i in range(TIER2_THRESHOLD * 10):
33073307
f1()
33083308

3309+
def test_143183(self):
3310+
# https://github.com/python/cpython/issues/143183
3311+
3312+
result = script_helper.run_python_until_end('-c', textwrap.dedent(f"""
3313+
def f1():
3314+
class AsyncIter:
3315+
def __init__(self):
3316+
self.limit = 0
3317+
self.count = 0
3318+
3319+
def __aiter__(self):
3320+
return self
3321+
3322+
async def __anext__(self):
3323+
if self.count >= self.limit:
3324+
...
3325+
self.count += 1j
3326+
3327+
class AsyncCtx:
3328+
async def async_for_driver():
3329+
try:
3330+
for _ in range({TIER2_THRESHOLD}):
3331+
try:
3332+
async for _ in AsyncIter():
3333+
...
3334+
except TypeError:
3335+
...
3336+
except Exception:
3337+
...
3338+
3339+
c = async_for_driver()
3340+
while True:
3341+
try:
3342+
c.send(None)
3343+
except StopIteration:
3344+
break
3345+
3346+
for _ in range({TIER2_THRESHOLD // 40}):
3347+
f1()
3348+
"""), PYTHON_JIT="1")
3349+
self.assertEqual(result[0].rc, 0, result)
3350+
33093351
def global_identity(x):
33103352
return x
33113353

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug in the JIT when dealing with unsupported control-flow or operations.

Python/optimizer.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ _PyJit_translate_single_bytecode_to_trace(
625625
int trace_length = _tstate->jit_tracer_state.prev_state.code_curr_size;
626626
_PyUOpInstruction *trace = _tstate->jit_tracer_state.code_buffer;
627627
int max_length = _tstate->jit_tracer_state.prev_state.code_max_size;
628+
int exit_op = stop_tracing_opcode == 0 ? _EXIT_TRACE : stop_tracing_opcode;
628629

629630
_Py_CODEUNIT *this_instr = _tstate->jit_tracer_state.prev_state.instr;
630631
_Py_CODEUNIT *target_instr = this_instr;
@@ -691,8 +692,11 @@ _PyJit_translate_single_bytecode_to_trace(
691692
}
692693

693694
if (stop_tracing_opcode != 0) {
694-
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
695-
goto done;
695+
// gh-143183: It's important we rewind to the last known proper target.
696+
// The current target might be garbage as stop tracing usually indicates
697+
// we are in something that we can't trace.
698+
DPRINTF(2, "Told to stop tracing\n");
699+
goto unsupported;
696700
}
697701

698702
DPRINTF(2, "%p %d: %s(%d) %d %d\n", old_code, target, _PyOpcode_OpName[opcode], oparg, needs_guard_ip, old_stack_level);
@@ -703,10 +707,6 @@ _PyJit_translate_single_bytecode_to_trace(
703707
}
704708
#endif
705709

706-
if (opcode == ENTER_EXECUTOR) {
707-
goto full;
708-
}
709-
710710
if (!_tstate->jit_tracer_state.prev_state.dependencies_still_valid) {
711711
goto full;
712712
}
@@ -720,11 +720,6 @@ _PyJit_translate_single_bytecode_to_trace(
720720

721721
if (oparg > 0xFFFF) {
722722
DPRINTF(2, "Unsupported: oparg too large\n");
723-
goto unsupported;
724-
}
725-
726-
// TODO (gh-140277): The constituent use one extra stack slot. So we need to check for headroom.
727-
if (opcode == BINARY_OP_SUBSCR_GETITEM && old_stack_level + 1 > old_code->co_stacksize) {
728723
unsupported:
729724
{
730725
// Rewind to previous instruction and replace with _EXIT_TRACE.
@@ -738,14 +733,15 @@ _PyJit_translate_single_bytecode_to_trace(
738733
int32_t old_target = (int32_t)uop_get_target(curr);
739734
curr++;
740735
trace_length++;
741-
curr->opcode = _EXIT_TRACE;
736+
curr->opcode = exit_op;
742737
curr->format = UOP_FORMAT_TARGET;
743738
curr->target = old_target;
744739
}
745740
goto done;
746741
}
747742
}
748743

744+
749745
if (opcode == NOP) {
750746
return 1;
751747
}

0 commit comments

Comments
 (0)