From f1abf92847a24408806317f6875889a96c5b6752 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 20 Jan 2025 15:42:50 +0000 Subject: [PATCH] Add new frame owner type for interpreter entry frames --- Include/internal/pycore_frame.h | 5 +++-- Modules/_testexternalinspection.c | 2 +- Objects/frameobject.c | 2 +- Python/bytecodes.c | 12 ++++-------- Python/ceval.c | 10 +++++----- Python/ceval_macros.h | 4 ++-- Python/executor_cases.c.h | 8 ++------ Python/frame.c | 4 ++-- Python/gc.c | 2 +- Python/generated_cases.c.h | 20 ++++++-------------- Python/instrumentation.c | 2 +- Python/traceback.c | 6 +++--- Tools/gdb/libpython.py | 4 ++-- 13 files changed, 33 insertions(+), 48 deletions(-) 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 4f0040df4f3017..447f919314e16f 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -2142,7 +2142,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 c0ef767a9dd68b..913c09af294c31 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 e2eaca2c90fa76..111a594b6c4c8e 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 dc90f75f2645e1..afc447cb89fe69 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5035,9 +5035,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()); @@ -5089,9 +5087,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); @@ -5134,7 +5130,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; @@ -7217,9 +7213,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()); @@ -7272,7 +7266,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) @@ -8394,9 +8388,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 17e5346be5ed3d..7b74c37463fc68 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1898,7 +1898,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) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy