summaryrefslogtreecommitdiffstats
path: root/Python/executor_cases.c.h
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-04-26 17:08:50 (GMT)
committerGitHub <noreply@github.com>2024-04-26 17:08:50 (GMT)
commit3e06c7f719b99cc7f5e8889319cff4980e41d3e8 (patch)
tree042c06326ca8b8866405375d8cf6b1f587cfa28d /Python/executor_cases.c.h
parent63add11704078390909a485b57a7de6a0358fc2b (diff)
downloadcpython-3e06c7f719b99cc7f5e8889319cff4980e41d3e8.zip
cpython-3e06c7f719b99cc7f5e8889319cff4980e41d3e8.tar.gz
cpython-3e06c7f719b99cc7f5e8889319cff4980e41d3e8.tar.bz2
GH-118095: Add dynamic exit support and FOR_ITER_GEN support to tier 2 (GH-118279)
Diffstat (limited to 'Python/executor_cases.c.h')
-rw-r--r--Python/executor_cases.c.h61
1 files changed, 60 insertions, 1 deletions
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 1eb3da9..280cca1 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -2769,7 +2769,32 @@
break;
}
- /* _FOR_ITER_GEN is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
+ case _FOR_ITER_GEN_FRAME: {
+ PyObject *iter;
+ _PyInterpreterFrame *gen_frame;
+ oparg = CURRENT_OPARG();
+ iter = stack_pointer[-1];
+ PyGenObject *gen = (PyGenObject *)iter;
+ if (Py_TYPE(gen) != &PyGen_Type) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ if (gen->gi_frame_state >= FRAME_EXECUTING) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ STAT_INC(FOR_ITER, hit);
+ gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyFrame_StackPush(gen_frame, Py_None);
+ gen->gi_frame_state = FRAME_EXECUTING;
+ gen->gi_exc_state.previous_item = tstate->exc_info;
+ tstate->exc_info = &gen->gi_exc_state;
+ // oparg is the return offset from the next instruction.
+ frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
+ stack_pointer[0] = (PyObject *)gen_frame;
+ stack_pointer += 1;
+ break;
+ }
/* _BEFORE_ASYNC_WITH is not a viable micro-op for tier 2 because it has both popping and not-popping errors */
@@ -4187,6 +4212,40 @@
break;
}
+ case _DYNAMIC_EXIT: {
+ oparg = CURRENT_OPARG();
+ tstate->previous_executor = (PyObject *)current_executor;
+ _PyExitData *exit = (_PyExitData *)&current_executor->exits[oparg];
+ _Py_CODEUNIT *target = frame->instr_ptr;
+ _PyExecutorObject *executor;
+ if (target->op.code == ENTER_EXECUTOR) {
+ PyCodeObject *code = (PyCodeObject *)frame->f_executable;
+ executor = code->co_executors->executors[target->op.arg];
+ Py_INCREF(executor);
+ }
+ else {
+ if (!backoff_counter_triggers(exit->temperature)) {
+ exit->temperature = advance_backoff_counter(exit->temperature);
+ GOTO_TIER_ONE(target);
+ }
+ int optimized = _PyOptimizer_Optimize(frame, target, stack_pointer, &executor);
+ if (optimized <= 0) {
+ exit->temperature = restart_backoff_counter(exit->temperature);
+ if (optimized < 0) {
+ Py_DECREF(current_executor);
+ tstate->previous_executor = Py_None;
+ GOTO_UNWIND();
+ }
+ GOTO_TIER_ONE(target);
+ }
+ else {
+ exit->temperature = initial_temperature_backoff_counter();
+ }
+ }
+ GOTO_TIER_TWO(executor);
+ break;
+ }
+
case _START_EXECUTOR: {
PyObject *executor = (PyObject *)CURRENT_OPERAND();
Py_DECREF(tstate->previous_executor);