diff options
author | Mark Shannon <mark@hotpy.org> | 2024-04-26 17:08:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-26 17:08:50 (GMT) |
commit | 3e06c7f719b99cc7f5e8889319cff4980e41d3e8 (patch) | |
tree | 042c06326ca8b8866405375d8cf6b1f587cfa28d /Python/executor_cases.c.h | |
parent | 63add11704078390909a485b57a7de6a0358fc2b (diff) | |
download | cpython-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.h | 61 |
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 *)¤t_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); |