https://github.com/python/cpython/commit/f5b6356a11bde64ac1e08478dd5ee7c47da653d8
commit: f5b6356a11bde64ac1e08478dd5ee7c47da653d8
branch: main
author: Mark Shannon <[email protected]>
committer: markshannon <[email protected]>
date: 2025-01-21T10:15:02Z
summary:
GH-128563: Add new frame owner type for interpreter entry frames (GH-129078)
Add new frame owner type for interpreter entry frames
files:
M Include/internal/pycore_frame.h
M Modules/_testexternalinspection.c
M Objects/frameobject.c
M Python/bytecodes.c
M Python/ceval.c
M Python/ceval_macros.h
M Python/executor_cases.c.h
M Python/frame.c
M Python/gc.c
M Python/generated_cases.c.h
M Python/instrumentation.c
M Python/traceback.c
M Tools/gdb/libpython.py
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index 96ae4dd22ecb43..77a922630cde08 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -56,7 +56,8 @@ enum _frameowner {
FRAME_OWNED_BY_THREAD = 0,
FRAME_OWNED_BY_GENERATOR = 1,
FRAME_OWNED_BY_FRAME_OBJECT = 2,
- FRAME_OWNED_BY_CSTACK = 3,
+ FRAME_OWNED_BY_INTERPRETER = 3,
+ FRAME_OWNED_BY_CSTACK = 4,
};
typedef struct _PyInterpreterFrame {
@@ -264,7 +265,7 @@ _PyFrame_SetStackPointer(_PyInterpreterFrame *frame,
_PyStackRef *stack_pointer)
static inline bool
_PyFrame_IsIncomplete(_PyInterpreterFrame *frame)
{
- if (frame->owner == FRAME_OWNED_BY_CSTACK) {
+ if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
return true;
}
return frame->owner != FRAME_OWNED_BY_GENERATOR &&
diff --git a/Modules/_testexternalinspection.c
b/Modules/_testexternalinspection.c
index 0807d1e47b6736..8a92d5cdd894be 100644
--- a/Modules/_testexternalinspection.c
+++ b/Modules/_testexternalinspection.c
@@ -508,7 +508,7 @@ parse_frame_object(
return -1;
}
- if (owner == FRAME_OWNED_BY_CSTACK) {
+ if (owner >= FRAME_OWNED_BY_INTERPRETER) {
return 0;
}
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index bf5067bba58f71..d6b4065e1302bc 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -2133,7 +2133,7 @@ _PyFrame_IsEntryFrame(PyFrameObject *frame)
assert(frame != NULL);
_PyInterpreterFrame *f = frame->f_frame;
assert(!_PyFrame_IsIncomplete(f));
- return f->previous && f->previous->owner == FRAME_OWNED_BY_CSTACK;
+ return f->previous && f->previous->owner == FRAME_OWNED_BY_INTERPRETER;
}
PyCodeObject *
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index b2745c3400ffc9..8bda4501df5f74 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -1090,7 +1090,7 @@ dummy_func(
}
tier1 inst(INTERPRETER_EXIT, (retval --)) {
- assert(frame == &entry_frame);
+ assert(frame->owner == FRAME_OWNED_BY_INTERPRETER);
assert(_PyFrame_IsIncomplete(frame));
/* Restore previous frame and return. */
tstate->current_frame = frame->previous;
@@ -1105,9 +1105,7 @@ dummy_func(
// retval is popped from the stack, but res
// is pushed to a different frame, the callers' frame.
inst(RETURN_VALUE, (retval -- res)) {
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
_PyStackRef temp = retval;
DEAD(retval);
SAVE_STACK();
@@ -1205,7 +1203,7 @@ dummy_func(
PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
PyObject *retval_o;
- assert(frame != &entry_frame);
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
if ((tstate->interp->eval_frame == NULL) &&
(Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) ==
&PyCoro_Type) &&
((PyGenObject *)receiver_o)->gi_frame_state < FRAME_EXECUTING)
@@ -1278,9 +1276,7 @@ dummy_func(
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed
close()
// or throw() call.
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
frame->instr_ptr++;
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
diff --git a/Python/ceval.c b/Python/ceval.c
index 28b0b4c6de39a7..813d980acf5aab 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -178,7 +178,7 @@ lltrace_instruction(_PyInterpreterFrame *frame,
int opcode,
int oparg)
{
- if (frame->owner == FRAME_OWNED_BY_CSTACK) {
+ if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
return;
}
dump_stack(frame, stack_pointer);
@@ -229,12 +229,12 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
}
static int
-maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, _PyInterpreterFrame
*skip_frame, PyObject *globals)
+maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, PyObject *globals)
{
if (globals == NULL) {
return 0;
}
- if (frame == skip_frame) {
+ if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
return 0;
}
int r = PyDict_Contains(globals, &_Py_ID(__lltrace__));
@@ -818,7 +818,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate,
_PyInterpreterFrame *frame, int
entry_frame.f_executable = PyStackRef_None;
entry_frame.instr_ptr = (_Py_CODEUNIT
*)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1;
entry_frame.stackpointer = entry_frame.localsplus;
- entry_frame.owner = FRAME_OWNED_BY_CSTACK;
+ entry_frame.owner = FRAME_OWNED_BY_INTERPRETER;
entry_frame.visited = 0;
entry_frame.return_offset = 0;
/* Push frame */
@@ -880,7 +880,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate,
_PyInterpreterFrame *frame, int
stack_pointer = _PyFrame_GetStackPointer(frame);
#ifdef LLTRACE
- lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
+ lltrace = maybe_lltrace_resume_frame(frame, GLOBALS());
if (lltrace < 0) {
goto exit_unwind;
}
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index c37e1cf3afa60e..6a982ee2ca5d9a 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -89,7 +89,7 @@
#if LLTRACE
#define LLTRACE_RESUME_FRAME() \
do { \
- lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); \
+ lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \
if (lltrace < 0) { \
goto exit_unwind; \
} \
@@ -238,7 +238,7 @@ GETITEM(PyObject *v, Py_ssize_t i) {
#endif
#define WITHIN_STACK_BOUNDS() \
- (frame == &entry_frame || (STACK_LEVEL() >= 0 && STACK_LEVEL() <=
STACK_SIZE()))
+ (frame->owner == FRAME_OWNED_BY_INTERPRETER || (STACK_LEVEL() >= 0 &&
STACK_LEVEL() <= STACK_SIZE()))
/* Data access macros */
#define FRAME_CO_CONSTS (_PyFrame_GetCode(frame)->co_consts)
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 049073162b6c5f..0d6719a5c40bdd 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -1441,9 +1441,7 @@
_PyStackRef retval;
_PyStackRef res;
retval = stack_pointer[-1];
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
_PyStackRef temp = retval;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -1579,9 +1577,7 @@
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed
close()
// or throw() call.
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
frame->instr_ptr++;
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
diff --git a/Python/frame.c b/Python/frame.c
index 6eb32bcce0b799..68ac2acbaee342 100644
--- a/Python/frame.c
+++ b/Python/frame.c
@@ -48,7 +48,7 @@ _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
static void
take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
{
- assert(frame->owner != FRAME_OWNED_BY_CSTACK);
+ assert(frame->owner < FRAME_OWNED_BY_INTERPRETER);
assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
Py_ssize_t size = ((char*)frame->stackpointer) - (char *)frame;
memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
@@ -69,7 +69,7 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
_PyInterpreterFrame *prev = _PyFrame_GetFirstComplete(frame->previous);
frame->previous = NULL;
if (prev) {
- assert(prev->owner != FRAME_OWNED_BY_CSTACK);
+ assert(prev->owner < FRAME_OWNED_BY_INTERPRETER);
/* Link PyFrameObjects.f_back and remove link through
_PyInterpreterFrame.previous */
PyFrameObject *back = _PyFrame_GetFrameObject(prev);
if (back == NULL) {
diff --git a/Python/gc.c b/Python/gc.c
index 5b9588c8741b97..3fe0b7f814544d 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -1476,7 +1476,7 @@ mark_stacks(PyInterpreterState *interp, PyGC_Head
*visited, int visited_space, b
while (ts) {
_PyInterpreterFrame *frame = ts->current_frame;
while (frame) {
- if (frame->owner == FRAME_OWNED_BY_CSTACK) {
+ if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
frame = frame->previous;
continue;
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index f25c9a97176a52..a8dbcabde538d5 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -5046,9 +5046,7 @@
// _RETURN_VALUE
{
retval = val;
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
_PyStackRef temp = retval;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -5100,9 +5098,7 @@
// NOTE: It's important that YIELD_VALUE never raises an
exception!
// The compiler treats any exception raised here as a failed
close()
// or throw() call.
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
frame->instr_ptr++;
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
@@ -5145,7 +5141,7 @@
INSTRUCTION_STATS(INTERPRETER_EXIT);
_PyStackRef retval;
retval = stack_pointer[-1];
- assert(frame == &entry_frame);
+ assert(frame->owner == FRAME_OWNED_BY_INTERPRETER);
assert(_PyFrame_IsIncomplete(frame));
/* Restore previous frame and return. */
tstate->current_frame = frame->previous;
@@ -7309,9 +7305,7 @@
_PyStackRef retval;
_PyStackRef res;
retval = stack_pointer[-1];
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
_PyStackRef temp = retval;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -7364,7 +7358,7 @@
v = stack_pointer[-1];
PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver);
PyObject *retval_o;
- assert(frame != &entry_frame);
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
if ((tstate->interp->eval_frame == NULL) &&
(Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o)
== &PyCoro_Type) &&
((PyGenObject *)receiver_o)->gi_frame_state <
FRAME_EXECUTING)
@@ -8486,9 +8480,7 @@
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed
close()
// or throw() call.
- #if TIER_ONE
- assert(frame != &entry_frame);
- #endif
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
frame->instr_ptr++;
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 8968ff2c691272..d20195d426fc00 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -1946,7 +1946,7 @@ instrument_all_executing_code_objects(PyInterpreterState
*interp) {
while (ts) {
_PyInterpreterFrame *frame = ts->current_frame;
while (frame) {
- if (frame->owner != FRAME_OWNED_BY_CSTACK) {
+ if (frame->owner < FRAME_OWNED_BY_INTERPRETER) {
if (instrument_lock_held(_PyFrame_GetCode(frame), interp)) {
return -1;
}
diff --git a/Python/traceback.c b/Python/traceback.c
index e819909b6045c3..62387f12392265 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -890,7 +890,7 @@ _Py_DumpASCII(int fd, PyObject *text)
static void
dump_frame(int fd, _PyInterpreterFrame *frame)
{
- assert(frame->owner != FRAME_OWNED_BY_CSTACK);
+ assert(frame->owner < FRAME_OWNED_BY_INTERPRETER);
PyCodeObject *code =_PyFrame_GetCode(frame);
PUTS(fd, " File ");
@@ -965,7 +965,7 @@ dump_traceback(int fd, PyThreadState *tstate, int
write_header)
unsigned int depth = 0;
while (1) {
- if (frame->owner == FRAME_OWNED_BY_CSTACK) {
+ if (frame->owner == FRAME_OWNED_BY_INTERPRETER) {
/* Trampoline frame */
frame = frame->previous;
if (frame == NULL) {
@@ -973,7 +973,7 @@ dump_traceback(int fd, PyThreadState *tstate, int
write_header)
}
/* Can't have more than one shim frame in a row */
- assert(frame->owner != FRAME_OWNED_BY_CSTACK);
+ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
}
if (MAX_FRAME_DEPTH <= depth) {
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
index 698ecbd3b549aa..e0d92e21dc42b3 100755
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -99,7 +99,7 @@ def interp_frame_has_tlbc_index():
Py_TPFLAGS_TYPE_SUBCLASS = (1 << 31)
#From pycore_frame.h
-FRAME_OWNED_BY_CSTACK = 3
+FRAME_OWNED_BY_INTERPRETER = 3
MAX_OUTPUT_LEN=1024
@@ -1113,7 +1113,7 @@ def _f_lasti(self):
return int(instr_ptr - first_instr)
def is_shim(self):
- return self._f_special("owner", int) == FRAME_OWNED_BY_CSTACK
+ return self._f_special("owner", int) == FRAME_OWNED_BY_INTERPRETER
def previous(self):
return self._f_special("previous", PyFramePtr)
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]