summaryrefslogtreecommitdiffstats
path: root/Python/optimizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/optimizer.c')
-rw-r--r--Python/optimizer.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/Python/optimizer.c b/Python/optimizer.c
index e5c70f7..02c9b39 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -567,8 +567,6 @@ translate_bytecode_to_trace(
top: // Jump here after _PUSH_FRAME or likely branches
for (;;) {
target = INSTR_IP(instr, code);
- RESERVE_RAW(2, "_CHECK_VALIDITY_AND_SET_IP");
- ADD_TO_TRACE(_CHECK_VALIDITY_AND_SET_IP, 0, (uintptr_t)instr, target);
// Need space for _DEOPT
max_length--;
@@ -597,6 +595,8 @@ top: // Jump here after _PUSH_FRAME or likely branches
}
}
assert(opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG);
+ RESERVE_RAW(2, "_CHECK_VALIDITY_AND_SET_IP");
+ ADD_TO_TRACE(_CHECK_VALIDITY_AND_SET_IP, 0, (uintptr_t)instr, target);
/* Special case the first instruction,
* so that we can guarantee forward progress */
@@ -814,6 +814,12 @@ top: // Jump here after _PUSH_FRAME or likely branches
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
goto done;
}
+ if (opcode == FOR_ITER_GEN) {
+ DPRINTF(2, "Bailing due to dynamic target\n");
+ ADD_TO_TRACE(uop, oparg, 0, target);
+ ADD_TO_TRACE(_DYNAMIC_EXIT, 0, 0, 0);
+ goto done;
+ }
// Increment IP to the return address
instr += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + 1;
TRACE_STACK_PUSH();
@@ -847,7 +853,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
}
DPRINTF(2, "Bail, new_code == NULL\n");
ADD_TO_TRACE(uop, oparg, 0, target);
- ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
+ ADD_TO_TRACE(_DYNAMIC_EXIT, 0, 0, 0);
goto done;
}
@@ -917,7 +923,7 @@ count_exits(_PyUOpInstruction *buffer, int length)
int exit_count = 0;
for (int i = 0; i < length; i++) {
int opcode = buffer[i].opcode;
- if (opcode == _SIDE_EXIT) {
+ if (opcode == _SIDE_EXIT || opcode == _DYNAMIC_EXIT) {
exit_count++;
}
}
@@ -1114,6 +1120,11 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil
dest->format = UOP_FORMAT_EXIT;
next_exit--;
}
+ if (opcode == _DYNAMIC_EXIT) {
+ executor->exits[next_exit].target = 0;
+ dest->oparg = next_exit;
+ next_exit--;
+ }
}
assert(next_exit == -1);
assert(dest == executor->trace);