mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-143183: Rewind stop tracing to previous target (GH-143187)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
parent
713684de53
commit
daa9aa4c0a
3 changed files with 51 additions and 12 deletions
|
|
@ -3306,6 +3306,48 @@ class B: ...
|
|||
for i in range(TIER2_THRESHOLD * 10):
|
||||
f1()
|
||||
|
||||
def test_143183(self):
|
||||
# https://github.com/python/cpython/issues/143183
|
||||
|
||||
result = script_helper.run_python_until_end('-c', textwrap.dedent(f"""
|
||||
def f1():
|
||||
class AsyncIter:
|
||||
def __init__(self):
|
||||
self.limit = 0
|
||||
self.count = 0
|
||||
|
||||
def __aiter__(self):
|
||||
return self
|
||||
|
||||
async def __anext__(self):
|
||||
if self.count >= self.limit:
|
||||
...
|
||||
self.count += 1j
|
||||
|
||||
class AsyncCtx:
|
||||
async def async_for_driver():
|
||||
try:
|
||||
for _ in range({TIER2_THRESHOLD}):
|
||||
try:
|
||||
async for _ in AsyncIter():
|
||||
...
|
||||
except TypeError:
|
||||
...
|
||||
except Exception:
|
||||
...
|
||||
|
||||
c = async_for_driver()
|
||||
while True:
|
||||
try:
|
||||
c.send(None)
|
||||
except StopIteration:
|
||||
break
|
||||
|
||||
for _ in range({TIER2_THRESHOLD // 40}):
|
||||
f1()
|
||||
"""), PYTHON_JIT="1")
|
||||
self.assertEqual(result[0].rc, 0, result)
|
||||
|
||||
def global_identity(x):
|
||||
return x
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Fix a bug in the JIT when dealing with unsupported control-flow or operations.
|
||||
|
|
@ -625,6 +625,7 @@ _PyJit_translate_single_bytecode_to_trace(
|
|||
int trace_length = _tstate->jit_tracer_state.prev_state.code_curr_size;
|
||||
_PyUOpInstruction *trace = _tstate->jit_tracer_state.code_buffer;
|
||||
int max_length = _tstate->jit_tracer_state.prev_state.code_max_size;
|
||||
int exit_op = stop_tracing_opcode == 0 ? _EXIT_TRACE : stop_tracing_opcode;
|
||||
|
||||
_Py_CODEUNIT *this_instr = _tstate->jit_tracer_state.prev_state.instr;
|
||||
_Py_CODEUNIT *target_instr = this_instr;
|
||||
|
|
@ -691,8 +692,11 @@ _PyJit_translate_single_bytecode_to_trace(
|
|||
}
|
||||
|
||||
if (stop_tracing_opcode != 0) {
|
||||
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
|
||||
goto done;
|
||||
// gh-143183: It's important we rewind to the last known proper target.
|
||||
// The current target might be garbage as stop tracing usually indicates
|
||||
// we are in something that we can't trace.
|
||||
DPRINTF(2, "Told to stop tracing\n");
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
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(
|
|||
}
|
||||
#endif
|
||||
|
||||
if (opcode == ENTER_EXECUTOR) {
|
||||
goto full;
|
||||
}
|
||||
|
||||
if (!_tstate->jit_tracer_state.prev_state.dependencies_still_valid) {
|
||||
goto full;
|
||||
}
|
||||
|
|
@ -720,11 +720,6 @@ _PyJit_translate_single_bytecode_to_trace(
|
|||
|
||||
if (oparg > 0xFFFF) {
|
||||
DPRINTF(2, "Unsupported: oparg too large\n");
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
// TODO (gh-140277): The constituent use one extra stack slot. So we need to check for headroom.
|
||||
if (opcode == BINARY_OP_SUBSCR_GETITEM && old_stack_level + 1 > old_code->co_stacksize) {
|
||||
unsupported:
|
||||
{
|
||||
// Rewind to previous instruction and replace with _EXIT_TRACE.
|
||||
|
|
@ -738,7 +733,7 @@ _PyJit_translate_single_bytecode_to_trace(
|
|||
int32_t old_target = (int32_t)uop_get_target(curr);
|
||||
curr++;
|
||||
trace_length++;
|
||||
curr->opcode = _EXIT_TRACE;
|
||||
curr->opcode = exit_op;
|
||||
curr->format = UOP_FORMAT_TARGET;
|
||||
curr->target = old_target;
|
||||
}
|
||||
|
|
@ -746,6 +741,7 @@ _PyJit_translate_single_bytecode_to_trace(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (opcode == NOP) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue