summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2025-05-04 09:05:35 (GMT)
committerGitHub <noreply@github.com>2025-05-04 09:05:35 (GMT)
commitac7d5ba96eb780b13877456b118ff1183bc6c4b3 (patch)
tree6ab67a7735fb68da63b2924e51eb0b1e09d15271 /Python/bytecodes.c
parent1d9406e426d95eb088e4a474fccf294cc106b2b6 (diff)
downloadcpython-ac7d5ba96eb780b13877456b118ff1183bc6c4b3.zip
cpython-ac7d5ba96eb780b13877456b118ff1183bc6c4b3.tar.gz
cpython-ac7d5ba96eb780b13877456b118ff1183bc6c4b3.tar.bz2
GH-133231: Changes to executor management to support proposed `sys._jit` module (GH-133287)
* Track the current executor, not the previous one, on the thread-state. * Batch executors for deallocation to avoid having to constantly incref executors; this is an ad-hoc form of deferred reference counting.
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index f145bde..5a52efa 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -1169,6 +1169,17 @@ dummy_func(
tstate->current_frame = frame->previous;
assert(!_PyErr_Occurred(tstate));
PyObject *result = PyStackRef_AsPyObjectSteal(retval);
+#if !Py_TAIL_CALL_INTERP
+ assert(frame == &entry.frame);
+#endif
+#ifdef _Py_TIER2
+ _PyStackRef executor = frame->localsplus[0];
+ assert(tstate->current_executor == NULL);
+ if (!PyStackRef_IsNull(executor)) {
+ tstate->current_executor = PyStackRef_AsPyObjectBorrow(executor);
+ PyStackRef_CLOSE(executor);
+ }
+#endif
LLTRACE_RESUME_FRAME();
return result;
}
@@ -2912,8 +2923,7 @@ dummy_func(
}
else {
this_instr[1].counter = initial_jump_backoff_counter();
- assert(tstate->previous_executor == NULL);
- tstate->previous_executor = Py_None;
+ assert(tstate->current_executor == NULL);
GOTO_TIER_TWO(executor);
}
}
@@ -2965,7 +2975,7 @@ dummy_func(
assert(executor->vm_data.index == INSTR_OFFSET() - 1);
assert(executor->vm_data.code == code);
assert(executor->vm_data.valid);
- assert(tstate->previous_executor == NULL);
+ assert(tstate->current_executor == NULL);
/* If the eval breaker is set then stay in tier 1.
* This avoids any potentially infinite loops
* involving _RESUME_CHECK */
@@ -2978,8 +2988,6 @@ dummy_func(
}
DISPATCH_GOTO();
}
- tstate->previous_executor = Py_None;
- Py_INCREF(executor);
GOTO_TIER_TWO(executor);
#else
Py_FatalError("ENTER_EXECUTOR is not supported in this build");
@@ -5254,7 +5262,6 @@ dummy_func(
exit->temperature = initial_temperature_backoff_counter();
Py_CLEAR(exit->executor);
}
- tstate->previous_executor = (PyObject *)current_executor;
if (exit->executor == NULL) {
_Py_BackoffCounter temperature = exit->temperature;
if (!backoff_counter_triggers(temperature)) {
@@ -5277,7 +5284,6 @@ dummy_func(
}
exit->executor = executor;
}
- Py_INCREF(exit->executor);
GOTO_TIER_TWO(exit->executor);
}
@@ -5316,7 +5322,6 @@ dummy_func(
}
tier2 op(_START_EXECUTOR, (executor/4 --)) {
- Py_CLEAR(tstate->previous_executor);
#ifndef _Py_JIT
current_executor = (_PyExecutorObject*)executor;
#endif
@@ -5337,12 +5342,10 @@ dummy_func(
}
tier2 op(_DEOPT, (--)) {
- tstate->previous_executor = (PyObject *)current_executor;
GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET());
}
tier2 op(_ERROR_POP_N, (target/2 --)) {
- tstate->previous_executor = (PyObject *)current_executor;
assert(oparg == 0);
frame->instr_ptr = _PyFrame_GetBytecode(frame) + target;
SYNC_SP();
@@ -5463,6 +5466,17 @@ dummy_func(
if (frame->owner == FRAME_OWNED_BY_INTERPRETER) {
/* Restore previous frame and exit */
tstate->current_frame = frame->previous;
+#if !Py_TAIL_CALL_INTERP
+ assert(frame == &entry.frame);
+#endif
+#ifdef _Py_TIER2
+ _PyStackRef executor = frame->localsplus[0];
+ assert(tstate->current_executor == NULL);
+ if (!PyStackRef_IsNull(executor)) {
+ tstate->current_executor = PyStackRef_AsPyObjectBorrow(executor);
+ PyStackRef_CLOSE(executor);
+ }
+#endif
return NULL;
}
next_instr = frame->instr_ptr;