summaryrefslogtreecommitdiffstats
path: root/Python/generated_cases.c.h
diff options
context:
space:
mode:
authormpage <mpage@meta.com>2024-12-11 23:18:22 (GMT)
committerGitHub <noreply@github.com>2024-12-11 23:18:22 (GMT)
commitc84928ed6de105696be24859e03f3ab27e11daf6 (patch)
treec533074edffdb8ae55dfa197ce8d63417f28949a /Python/generated_cases.c.h
parente8f4e272cc828f2b79fa17fc6b9786bdddab7ce4 (diff)
downloadcpython-c84928ed6de105696be24859e03f3ab27e11daf6.zip
cpython-c84928ed6de105696be24859e03f3ab27e11daf6.tar.gz
cpython-c84928ed6de105696be24859e03f3ab27e11daf6.tar.bz2
gh-115999: Specialize `CALL_KW` in free-threaded builds (#127713)
* Enable specialization of CALL_KW * Fix bug pushing frame in _PY_FRAME_KW `_PY_FRAME_KW` pushes a pointer to the new frame onto the stack for consumption by the next uop. When pushing the frame fails, we do not want to push the result, `NULL`, to the stack because it is not a valid stackref. This works in the default build because `PyStackRef_NULL` and `NULL` are the same value, so the `PyStackRef_XCLOSE()` in the error handler ignores it. In the free-threaded build the values are not the same; `PyStackRef_XCLOSE()` will attempt to decref a null pointer.
Diffstat (limited to 'Python/generated_cases.c.h')
-rw-r--r--Python/generated_cases.c.h24
1 files changed, 10 insertions, 14 deletions
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 33f32ab..fc0f555 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -1895,7 +1895,7 @@
callable = &stack_pointer[-3 - oparg];
uint16_t counter = read_u16(&this_instr[1].cache);
(void)counter;
- #if ENABLE_SPECIALIZATION
+ #if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -1905,7 +1905,7 @@
}
OPCODE_DEFERRED_INC(CALL_KW);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
- #endif /* ENABLE_SPECIALIZATION */
+ #endif /* ENABLE_SPECIALIZATION_FT */
}
/* Skip 2 cache entries */
// _MAYBE_EXPAND_METHOD_KW
@@ -2093,7 +2093,7 @@
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
_PyFrame_SetStackPointer(frame, stack_pointer);
- new_frame = _PyEvalFramePushAndInit(
+ _PyInterpreterFrame *temp = _PyEvalFramePushAndInit(
tstate, callable[0], locals,
args, positional_args, kwnames_o, frame
);
@@ -2101,12 +2101,12 @@
PyStackRef_CLOSE(kwnames);
// The frame has stolen all the arguments from the stack,
// so there is no need to clean them up.
- stack_pointer[-3 - oparg].bits = (uintptr_t)new_frame;
- stack_pointer += -2 - oparg;
+ stack_pointer += -3 - oparg;
assert(WITHIN_STACK_BOUNDS());
- if (new_frame == NULL) {
+ if (temp == NULL) {
goto error;
}
+ new_frame = temp;
}
// _SAVE_RETURN_OFFSET
{
@@ -2123,8 +2123,6 @@
// Eventually this should be the only occurrence of this code.
assert(tstate->interp->eval_frame == NULL);
_PyInterpreterFrame *temp = new_frame;
- stack_pointer += -1;
- assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
CALL_STAT_INC(inlined_py_calls);
@@ -2271,7 +2269,7 @@
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
_PyFrame_SetStackPointer(frame, stack_pointer);
- new_frame = _PyEvalFramePushAndInit(
+ _PyInterpreterFrame *temp = _PyEvalFramePushAndInit(
tstate, callable[0], locals,
args, positional_args, kwnames_o, frame
);
@@ -2279,12 +2277,12 @@
PyStackRef_CLOSE(kwnames);
// The frame has stolen all the arguments from the stack,
// so there is no need to clean them up.
- stack_pointer[-3 - oparg].bits = (uintptr_t)new_frame;
- stack_pointer += -2 - oparg;
+ stack_pointer += -3 - oparg;
assert(WITHIN_STACK_BOUNDS());
- if (new_frame == NULL) {
+ if (temp == NULL) {
goto error;
}
+ new_frame = temp;
}
// _SAVE_RETURN_OFFSET
{
@@ -2301,8 +2299,6 @@
// Eventually this should be the only occurrence of this code.
assert(tstate->interp->eval_frame == NULL);
_PyInterpreterFrame *temp = new_frame;
- stack_pointer += -1;
- assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
assert(new_frame->previous == frame || new_frame->previous->previous == frame);
CALL_STAT_INC(inlined_py_calls);