mirror of
https://github.com/python/cpython.git
synced 2025-10-20 08:23:47 +00:00
GH-136410: Faster side exits by using a cold exit stub (GH-136411)
This commit is contained in:
parent
718e0c89ba
commit
e7b55f564d
15 changed files with 387 additions and 267 deletions
84
Python/executor_cases.c.h
generated
84
Python/executor_cases.c.h
generated
|
@ -7113,9 +7113,8 @@
|
|||
case _EXIT_TRACE: {
|
||||
PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
|
||||
_PyExitData *exit = (_PyExitData *)exit_p;
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
_Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
|
||||
#if defined(Py_DEBUG) && !defined(_Py_JIT)
|
||||
_Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
|
||||
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
||||
if (frame->lltrace >= 2) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
|
@ -7128,36 +7127,7 @@
|
|||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
}
|
||||
#endif
|
||||
if (exit->executor && !exit->executor->vm_data.valid) {
|
||||
exit->temperature = initial_temperature_backoff_counter();
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_CLEAR(exit->executor);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
}
|
||||
if (exit->executor == NULL) {
|
||||
_Py_BackoffCounter temperature = exit->temperature;
|
||||
if (!backoff_counter_triggers(temperature)) {
|
||||
exit->temperature = advance_backoff_counter(temperature);
|
||||
GOTO_TIER_ONE(target);
|
||||
}
|
||||
_PyExecutorObject *executor;
|
||||
if (target->op.code == ENTER_EXECUTOR) {
|
||||
executor = code->co_executors->executors[target->op.arg];
|
||||
Py_INCREF(executor);
|
||||
}
|
||||
else {
|
||||
int chain_depth = current_executor->vm_data.chain_depth + 1;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int optimized = _PyOptimizer_Optimize(frame, target, &executor, chain_depth);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (optimized <= 0) {
|
||||
exit->temperature = restart_backoff_counter(temperature);
|
||||
GOTO_TIER_ONE(optimized < 0 ? NULL : target);
|
||||
}
|
||||
exit->temperature = initial_temperature_backoff_counter();
|
||||
}
|
||||
exit->executor = executor;
|
||||
}
|
||||
tstate->jit_exit = exit;
|
||||
GOTO_TIER_TWO(exit->executor);
|
||||
break;
|
||||
}
|
||||
|
@ -7438,7 +7408,19 @@
|
|||
#ifndef _Py_JIT
|
||||
current_executor = (_PyExecutorObject*)executor;
|
||||
#endif
|
||||
assert(((_PyExecutorObject *)executor)->vm_data.valid);
|
||||
assert(tstate->jit_exit == NULL || tstate->jit_exit->executor == current_executor);
|
||||
tstate->current_executor = (PyObject *)executor;
|
||||
if (!current_executor->vm_data.valid) {
|
||||
assert(tstate->jit_exit->executor == current_executor);
|
||||
assert(tstate->current_executor == executor);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyExecutor_ClearExit(tstate->jit_exit);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7487,4 +7469,40 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _COLD_EXIT: {
|
||||
_PyExitData *exit = tstate->jit_exit;
|
||||
assert(exit != NULL);
|
||||
_Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
|
||||
_Py_BackoffCounter temperature = exit->temperature;
|
||||
if (!backoff_counter_triggers(temperature)) {
|
||||
exit->temperature = advance_backoff_counter(temperature);
|
||||
GOTO_TIER_ONE(target);
|
||||
}
|
||||
_PyExecutorObject *executor;
|
||||
if (target->op.code == ENTER_EXECUTOR) {
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
executor = code->co_executors->executors[target->op.arg];
|
||||
Py_INCREF(executor);
|
||||
}
|
||||
else {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
assert(tstate->current_executor == (PyObject *)previous_executor);
|
||||
int chain_depth = previous_executor->vm_data.chain_depth + 1;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int optimized = _PyOptimizer_Optimize(frame, target, &executor, chain_depth);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (optimized <= 0) {
|
||||
exit->temperature = restart_backoff_counter(temperature);
|
||||
GOTO_TIER_ONE(optimized < 0 ? NULL : target);
|
||||
}
|
||||
exit->temperature = initial_temperature_backoff_counter();
|
||||
}
|
||||
assert(tstate->jit_exit == exit);
|
||||
exit->executor = executor;
|
||||
GOTO_TIER_TWO(exit->executor);
|
||||
break;
|
||||
}
|
||||
|
||||
#undef TIER_TWO
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue