Skip to content
Merged
Prev Previous commit
Next Next commit
FOR_ITER_LIST Tier 2; fix a reservation bug
  • Loading branch information
gvanrossum committed Jul 12, 2023
commit 020c4c77a4f03450a5eb7daf52db03077cb52901
31 changes: 26 additions & 5 deletions Python/optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,26 +474,47 @@ translate_bytecode_to_trace(

case JUMP_FORWARD:
{
// Reserve 2 entries (SAVE_IP + EXIT_TRACE)
if (trace_length + 2 > max_length) {
DPRINTF(1, "Ran out of space for JUMP_FORWARD\n");
goto done;
}
// This will emit two SAVE_IP instructions; leave it to the optimizer
instr += oparg;
break;
}

case FOR_ITER_LIST:
case FOR_ITER_RANGE:
{
int check_op, exhausted_op, next_op;
switch (opcode) {
case FOR_ITER_LIST:
check_op = _ITER_CHECK_LIST;
exhausted_op = _ITER_EXHAUSTED_LIST;
next_op = _ITER_NEXT_LIST;
break;
case FOR_ITER_RANGE:
check_op = _ITER_CHECK_RANGE;
exhausted_op = _ITER_EXHAUSTED_RANGE;
next_op = _ITER_NEXT_RANGE;
break;
default:
assert(0);
Comment thread
gvanrossum marked this conversation as resolved.
Outdated
}
// Assume jump unlikely (can a for-loop exit be likely?)
// Reserve 9 entries (4 here, 3 stub, plus SAVE_IP + EXIT_TRACE)
if (trace_length + 9 > max_length) {
DPRINTF(1, "Ran out of space for FOR_ITER_RANGE\n");
goto done;
DPRINTF(1, "Ran out of space for %s\n", uop_name(opcode));
goto done;
}
_Py_CODEUNIT *target_instr = // +1 at the end skips over END_FOR
instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + oparg + 1;
max_length -= 3; // Really the start of the stubs
ADD_TO_TRACE(_ITER_CHECK_RANGE, 0);
ADD_TO_TRACE(_ITER_EXHAUSTED_RANGE, 0);
ADD_TO_TRACE(check_op, 0);
ADD_TO_TRACE(exhausted_op, 0);
ADD_TO_TRACE(_POP_JUMP_IF_TRUE, max_length);
ADD_TO_TRACE(_ITER_NEXT_RANGE, 0);
ADD_TO_TRACE(next_op, 0);

ADD_TO_STUB(max_length + 0, POP_TOP, 0);
ADD_TO_STUB(max_length + 1, SAVE_IP, INSTR_IP(target_instr, code));
Expand Down