summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-08-17 10:16:03 (GMT)
committerGitHub <noreply@github.com>2023-08-17 10:16:03 (GMT)
commit006e44f9502308ec3d14424ad8bd774046f2be8e (patch)
tree91ab71678a0fb5f5ba410c371f28ded8a1c82d0d
parent33e6e3fec02ff3035dec52692542d3dd10124bef (diff)
downloadcpython-006e44f9502308ec3d14424ad8bd774046f2be8e.zip
cpython-006e44f9502308ec3d14424ad8bd774046f2be8e.tar.gz
cpython-006e44f9502308ec3d14424ad8bd774046f2be8e.tar.bz2
GH-108035: Remove the `_PyCFrame` struct as it is no longer needed for performance. (GH-108036)
-rw-r--r--Include/cpython/pystate.h25
-rw-r--r--Include/internal/pycore_frame.h2
-rw-r--r--Include/internal/pycore_runtime.h2
-rw-r--r--Include/internal/pycore_runtime_init.h6
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst4
-rw-r--r--Modules/_xxsubinterpretersmodule.c2
-rw-r--r--Objects/genobject.c8
-rw-r--r--Objects/typevarobject.c2
-rw-r--r--Python/bytecodes.c34
-rw-r--r--Python/ceval.c22
-rw-r--r--Python/ceval_macros.h2
-rw-r--r--Python/executor.c2
-rw-r--r--Python/executor_cases.c.h3
-rw-r--r--Python/frame.c2
-rw-r--r--Python/generated_cases.c.h33
-rw-r--r--Python/instrumentation.c2
-rw-r--r--Python/intrinsics.c4
-rw-r--r--Python/pylifecycle.c2
-rw-r--r--Python/pystate.c6
-rw-r--r--Python/sysmodule.c4
-rw-r--r--Python/traceback.c2
21 files changed, 66 insertions, 103 deletions
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
index 56e473c..2a53838 100644
--- a/Include/cpython/pystate.h
+++ b/Include/cpython/pystate.h
@@ -29,24 +29,6 @@ typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *);
#define PyTrace_C_RETURN 6
#define PyTrace_OPCODE 7
-// Internal structure: you should not use it directly, but use public functions
-// like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing().
-typedef struct _PyCFrame {
- /* This struct will be threaded through the C stack
- * allowing fast access to per-thread state that needs
- * to be accessed quickly by the interpreter, but can
- * be modified outside of the interpreter.
- *
- * WARNING: This makes data on the C stack accessible from
- * heap objects. Care must be taken to maintain stack
- * discipline and make sure that instances of this struct cannot
- * accessed outside of their lifetime.
- */
- /* Pointer to the currently executing frame (it can be NULL) */
- struct _PyInterpreterFrame *current_frame;
- struct _PyCFrame *previous;
-} _PyCFrame;
-
typedef struct _err_stackitem {
/* This struct represents a single execution context where we might
* be currently handling an exception. It is a per-coroutine state
@@ -123,9 +105,8 @@ struct _ts {
int tracing;
int what_event; /* The event currently being monitored, if any. */
- /* Pointer to current _PyCFrame in the C stack frame of the currently,
- * or most recently, executing _PyEval_EvalFrameDefault. */
- _PyCFrame *cframe;
+ /* Pointer to currently executing frame. */
+ struct _PyInterpreterFrame *current_frame;
Py_tracefunc c_profilefunc;
Py_tracefunc c_tracefunc;
@@ -211,8 +192,6 @@ struct _ts {
/* The thread's exception stack entry. (Always the last entry.) */
_PyErr_StackItem exc_state;
- /* The bottom-most frame on the stack. */
- _PyCFrame root_cframe;
};
/* WASI has limited call stack. Python's recursion limit depends on code
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index 5ff20ef..0dc2a18 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -196,7 +196,7 @@ _PyFrame_GetFirstComplete(_PyInterpreterFrame *frame)
static inline _PyInterpreterFrame *
_PyThreadState_GetFrame(PyThreadState *tstate)
{
- return _PyFrame_GetFirstComplete(tstate->cframe->current_frame);
+ return _PyFrame_GetFirstComplete(tstate->current_frame);
}
/* For use by _PyFrame_GetFrameObject
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
index 0ec86ee..63b4850 100644
--- a/Include/internal/pycore_runtime.h
+++ b/Include/internal/pycore_runtime.h
@@ -80,7 +80,7 @@ typedef struct _Py_DebugOffsets {
off_t prev;
off_t next;
off_t interp;
- off_t cframe;
+ off_t current_frame;
off_t thread_id;
off_t native_thread_id;
} thread_state;
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index e89d368..ea29c69 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -45,7 +45,7 @@ extern PyTypeObject _PyExc_MemoryError;
.prev = offsetof(PyThreadState, prev), \
.next = offsetof(PyThreadState, next), \
.interp = offsetof(PyThreadState, interp), \
- .cframe = offsetof(PyThreadState, cframe), \
+ .current_frame = offsetof(PyThreadState, current_frame), \
.thread_id = offsetof(PyThreadState, thread_id), \
.native_thread_id = offsetof(PyThreadState, native_thread_id), \
}, \
@@ -56,10 +56,6 @@ extern PyTypeObject _PyExc_MemoryError;
.localsplus = offsetof(_PyInterpreterFrame, localsplus), \
.owner = offsetof(_PyInterpreterFrame, owner), \
}, \
- .cframe = { \
- .current_frame = offsetof(_PyCFrame, current_frame), \
- .previous = offsetof(_PyCFrame, previous), \
- }, \
.code_object = { \
.filename = offsetof(PyCodeObject, co_filename), \
.name = offsetof(PyCodeObject, co_name), \
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst
new file mode 100644
index 0000000..fc2369d
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst
@@ -0,0 +1,4 @@
+Remove the ``_PyCFrame`` struct, moving the pointer to the current intepreter frame
+back to the threadstate, as it was for 3.10 and earlier. The ``_PyCFrame``
+existed as a performance optimization for tracing. Since PEP 669 has been
+implemented, this optimization no longer applies.
diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c
index 31373f8..ea91e70 100644
--- a/Modules/_xxsubinterpretersmodule.c
+++ b/Modules/_xxsubinterpretersmodule.c
@@ -369,7 +369,7 @@ _is_running(PyInterpreterState *interp)
}
assert(!PyErr_Occurred());
- struct _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+ struct _PyInterpreterFrame *frame = tstate->current_frame;
if (frame == NULL) {
return 0;
}
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 65782be..10c55ef 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -476,9 +476,9 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
will be reported correctly to the user. */
/* XXX We should probably be updating the current frame
somewhere in ceval.c. */
- _PyInterpreterFrame *prev = tstate->cframe->current_frame;
+ _PyInterpreterFrame *prev = tstate->current_frame;
frame->previous = prev;
- tstate->cframe->current_frame = frame;
+ tstate->current_frame = frame;
/* Close the generator that we are currently iterating with
'yield from' or awaiting on with 'await'. */
PyFrameState state = gen->gi_frame_state;
@@ -486,7 +486,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
typ, val, tb);
gen->gi_frame_state = state;
- tstate->cframe->current_frame = prev;
+ tstate->current_frame = prev;
frame->previous = NULL;
} else {
/* `yf` is an iterator or a coroutine-like object. */
@@ -938,7 +938,7 @@ _Py_MakeCoro(PyFunctionObject *func)
if (origin_depth == 0) {
((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
} else {
- _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+ _PyInterpreterFrame *frame = tstate->current_frame;
assert(frame);
assert(_PyFrame_IsIncomplete(frame));
frame = _PyFrame_GetFirstComplete(frame->previous);
diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c
index e09e6a6..66122e3 100644
--- a/Objects/typevarobject.c
+++ b/Objects/typevarobject.c
@@ -107,7 +107,7 @@ make_union(PyObject *self, PyObject *other)
static PyObject *
caller(void)
{
- _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame;
+ _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
if (f == NULL) {
Py_RETURN_NONE;
}
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index ae2923c..6f17472 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -72,7 +72,6 @@ dummy_func(
_PyInterpreterFrame *frame,
unsigned char opcode,
unsigned int oparg,
- _PyCFrame cframe,
_Py_CODEUNIT *next_instr,
PyObject **stack_pointer,
PyObject *kwnames,
@@ -134,8 +133,7 @@ dummy_func(
}
inst(RESUME, (--)) {
- assert(tstate->cframe == &cframe);
- assert(frame == cframe.current_frame);
+ assert(frame == tstate->current_frame);
/* Possibly combine this with eval breaker */
if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) {
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
@@ -752,9 +750,8 @@ dummy_func(
inst(INTERPRETER_EXIT, (retval --)) {
assert(frame == &entry_frame);
assert(_PyFrame_IsIncomplete(frame));
- /* Restore previous cframe and return. */
- tstate->cframe = cframe.previous;
- assert(tstate->cframe->current_frame == frame->previous);
+ /* Restore previous frame and return. */
+ tstate->current_frame = frame->previous;
assert(!_PyErr_Occurred(tstate));
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
return retval;
@@ -768,7 +765,7 @@ dummy_func(
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -787,7 +784,7 @@ dummy_func(
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -803,7 +800,7 @@ dummy_func(
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -823,7 +820,7 @@ dummy_func(
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -1019,7 +1016,7 @@ dummy_func(
gen->gi_exc_state.previous_item = NULL;
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *gen_frame = frame;
- frame = cframe.current_frame = frame->previous;
+ frame = tstate->current_frame = frame->previous;
gen_frame->previous = NULL;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
@@ -1038,7 +1035,7 @@ dummy_func(
gen->gi_exc_state.previous_item = NULL;
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *gen_frame = frame;
- frame = cframe.current_frame = frame->previous;
+ frame = tstate->current_frame = frame->previous;
gen_frame->previous = NULL;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
@@ -2207,10 +2204,10 @@ dummy_func(
OBJECT_STAT_INC(optimization_attempts);
frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
if (frame == NULL) {
- frame = cframe.current_frame;
+ frame = tstate->current_frame;
goto resume_with_error;
}
- assert(frame == cframe.current_frame);
+ assert(frame == tstate->current_frame);
here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1);
goto resume_frame;
}
@@ -2238,7 +2235,7 @@ dummy_func(
Py_INCREF(executor);
frame = executor->execute(executor, frame, stack_pointer);
if (frame == NULL) {
- frame = cframe.current_frame;
+ frame = tstate->current_frame;
goto resume_with_error;
}
goto resume_frame;
@@ -2993,12 +2990,11 @@ dummy_func(
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->previous = frame;
CALL_STAT_INC(inlined_py_calls);
+ frame = tstate->current_frame = new_frame;
#if TIER_ONE
- frame = cframe.current_frame = new_frame;
goto start_frame;
#endif
#if TIER_TWO
- frame = tstate->cframe->current_frame = new_frame;
ERROR_IF(_Py_EnterRecursivePy(tstate), exit_unwind);
stack_pointer = _PyFrame_GetStackPointer(frame);
ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive;
@@ -3135,7 +3131,7 @@ dummy_func(
/* Link frames */
init_frame->previous = shim;
shim->previous = frame;
- frame = cframe.current_frame = init_frame;
+ frame = tstate->current_frame = init_frame;
CALL_STAT_INC(inlined_py_calls);
/* Account for pushing the extra frame.
* We don't check recursion depth here,
@@ -3598,7 +3594,7 @@ dummy_func(
assert(frame != &entry_frame);
_PyInterpreterFrame *prev = frame->previous;
_PyThreadState_PopFrame(tstate, frame);
- frame = cframe.current_frame = prev;
+ frame = tstate->current_frame = prev;
_PyFrame_StackPush(frame, (PyObject *)gen);
goto resume_frame;
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 26e741e..1e2262c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -656,17 +656,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
int lltrace = 0;
#endif
- _PyCFrame cframe;
_PyInterpreterFrame entry_frame;
PyObject *kwnames = NULL; // Borrowed reference. Reset by CALL instructions.
- /* WARNING: Because the _PyCFrame lives on the C stack,
- * but can be accessed from a heap allocated object (tstate)
- * strict stack discipline must be maintained.
- */
- _PyCFrame *prev_cframe = tstate->cframe;
- cframe.previous = prev_cframe;
- tstate->cframe = &cframe;
+
#ifdef Py_DEBUG
/* Set these to invalid but identifiable values for debugging. */
@@ -682,9 +675,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
entry_frame.owner = FRAME_OWNED_BY_CSTACK;
entry_frame.return_offset = 0;
/* Push frame */
- entry_frame.previous = prev_cframe->current_frame;
+ entry_frame.previous = tstate->current_frame;
frame->previous = &entry_frame;
- cframe.current_frame = frame;
+ tstate->current_frame = frame;
tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1);
if (_Py_EnterRecursiveCallTstate(tstate, "")) {
@@ -924,13 +917,12 @@ exit_unwind:
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->return_offset = 0;
if (frame == &entry_frame) {
- /* Restore previous cframe and exit */
- tstate->cframe = cframe.previous;
- assert(tstate->cframe->current_frame == frame->previous);
+ /* Restore previous frame and exit */
+ tstate->current_frame = frame->previous;
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
return NULL;
}
@@ -2297,7 +2289,7 @@ int
PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
{
PyThreadState *tstate = _PyThreadState_GET();
- _PyInterpreterFrame *current_frame = tstate->cframe->current_frame;
+ _PyInterpreterFrame *current_frame = tstate->current_frame;
int result = cf->cf_flags != 0;
if (current_frame != NULL) {
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index 5e2db1e..08f19cd 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -109,7 +109,7 @@
_PyFrame_SetStackPointer(frame, stack_pointer); \
frame->prev_instr = next_instr - 1; \
(NEW_FRAME)->previous = frame; \
- frame = cframe.current_frame = (NEW_FRAME); \
+ frame = tstate->current_frame = (NEW_FRAME); \
CALL_STAT_INC(inlined_py_calls); \
goto start_frame; \
} while (0)
diff --git a/Python/executor.c b/Python/executor.c
index 5a571e6..88c039d 100644
--- a/Python/executor.c
+++ b/Python/executor.c
@@ -111,7 +111,7 @@ pop_1_exit_unwind:
STACK_SHRINK(1);
error:
// On ERROR_IF we return NULL as the frame.
- // The caller recovers the frame from cframe.current_frame.
+ // The caller recovers the frame from tstate->current_frame.
DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
_PyFrame_SetStackPointer(frame, stack_pointer);
Py_DECREF(self);
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index b3dd313..9fbf026 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -2212,12 +2212,11 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->previous = frame;
CALL_STAT_INC(inlined_py_calls);
+ frame = tstate->current_frame = new_frame;
#if TIER_ONE
- frame = cframe.current_frame = new_frame;
goto start_frame;
#endif
#if TIER_TWO
- frame = tstate->cframe->current_frame = new_frame;
if (_Py_EnterRecursivePy(tstate)) goto pop_1_exit_unwind;
stack_pointer = _PyFrame_GetStackPointer(frame);
ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive;
diff --git a/Python/frame.c b/Python/frame.c
index 581e4f9..fbfa543 100644
--- a/Python/frame.c
+++ b/Python/frame.c
@@ -124,7 +124,7 @@ _PyFrame_ClearExceptCode(_PyInterpreterFrame *frame)
_PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED);
// GH-99729: Clearing this frame can expose the stack (via finalizers). It's
// crucial that this frame has been unlinked, and is no longer visible:
- assert(_PyThreadState_GET()->cframe->current_frame != frame);
+ assert(_PyThreadState_GET()->current_frame != frame);
if (frame->frame_obj) {
PyFrameObject *f = frame->frame_obj;
frame->frame_obj = NULL;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 11d560a..80af8a7 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -8,8 +8,7 @@
}
TARGET(RESUME) {
- assert(tstate->cframe == &cframe);
- assert(frame == cframe.current_frame);
+ assert(frame == tstate->current_frame);
/* Possibly combine this with eval breaker */
if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) {
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
@@ -961,9 +960,8 @@
retval = stack_pointer[-1];
assert(frame == &entry_frame);
assert(_PyFrame_IsIncomplete(frame));
- /* Restore previous cframe and return. */
- tstate->cframe = cframe.previous;
- assert(tstate->cframe->current_frame == frame->previous);
+ /* Restore previous frame and return. */
+ tstate->current_frame = frame->previous;
assert(!_PyErr_Occurred(tstate));
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
return retval;
@@ -980,7 +978,7 @@
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -1002,7 +1000,7 @@
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -1019,7 +1017,7 @@
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -1039,7 +1037,7 @@
assert(frame != &entry_frame);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame *dying = frame;
- frame = cframe.current_frame = dying->previous;
+ frame = tstate->current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
@@ -1263,7 +1261,7 @@
gen->gi_exc_state.previous_item = NULL;
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *gen_frame = frame;
- frame = cframe.current_frame = frame->previous;
+ frame = tstate->current_frame = frame->previous;
gen_frame->previous = NULL;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
@@ -1284,7 +1282,7 @@
gen->gi_exc_state.previous_item = NULL;
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *gen_frame = frame;
- frame = cframe.current_frame = frame->previous;
+ frame = tstate->current_frame = frame->previous;
gen_frame->previous = NULL;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
@@ -2911,10 +2909,10 @@
OBJECT_STAT_INC(optimization_attempts);
frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
if (frame == NULL) {
- frame = cframe.current_frame;
+ frame = tstate->current_frame;
goto resume_with_error;
}
- assert(frame == cframe.current_frame);
+ assert(frame == tstate->current_frame);
here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1);
goto resume_frame;
}
@@ -2933,7 +2931,7 @@
Py_INCREF(executor);
frame = executor->execute(executor, frame, stack_pointer);
if (frame == NULL) {
- frame = cframe.current_frame;
+ frame = tstate->current_frame;
goto resume_with_error;
}
goto resume_frame;
@@ -3830,12 +3828,11 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->previous = frame;
CALL_STAT_INC(inlined_py_calls);
+ frame = tstate->current_frame = new_frame;
#if TIER_ONE
- frame = cframe.current_frame = new_frame;
goto start_frame;
#endif
#if TIER_TWO
- frame = tstate->cframe->current_frame = new_frame;
if (_Py_EnterRecursivePy(tstate)) goto pop_1_exit_unwind;
stack_pointer = _PyFrame_GetStackPointer(frame);
ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive;
@@ -4014,7 +4011,7 @@
/* Link frames */
init_frame->previous = shim;
shim->previous = frame;
- frame = cframe.current_frame = init_frame;
+ frame = tstate->current_frame = init_frame;
CALL_STAT_INC(inlined_py_calls);
/* Account for pushing the extra frame.
* We don't check recursion depth here,
@@ -4636,7 +4633,7 @@
assert(frame != &entry_frame);
_PyInterpreterFrame *prev = frame->previous;
_PyThreadState_PopFrame(tstate, frame);
- frame = cframe.current_frame = prev;
+ frame = tstate->current_frame = prev;
_PyFrame_StackPush(frame, (PyObject *)gen);
goto resume_frame;
}
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 48befed..a7a5b4a 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -1677,7 +1677,7 @@ instrument_all_executing_code_objects(PyInterpreterState *interp) {
PyThreadState* ts = PyInterpreterState_ThreadHead(interp);
HEAD_UNLOCK(runtime);
while (ts) {
- _PyInterpreterFrame *frame = ts->cframe->current_frame;
+ _PyInterpreterFrame *frame = ts->current_frame;
while (frame) {
if (frame->owner != FRAME_OWNED_BY_CSTACK) {
if (_Py_Instrument(_PyFrame_GetCode(frame), interp)) {
diff --git a/Python/intrinsics.c b/Python/intrinsics.c
index 61a8e75..5267c10 100644
--- a/Python/intrinsics.c
+++ b/Python/intrinsics.c
@@ -120,7 +120,7 @@ import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
static PyObject *
import_star(PyThreadState* tstate, PyObject *from)
{
- _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+ _PyInterpreterFrame *frame = tstate->current_frame;
if (_PyFrame_FastToLocalsWithError(frame) < 0) {
return NULL;
}
@@ -142,7 +142,7 @@ import_star(PyThreadState* tstate, PyObject *from)
static PyObject *
stopiteration_error(PyThreadState* tstate, PyObject *exc)
{
- _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+ _PyInterpreterFrame *frame = tstate->current_frame;
assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
assert(PyExceptionInstance_Check(exc));
const char *msg = NULL;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 0de3abf..9063396 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -2147,7 +2147,7 @@ Py_EndInterpreter(PyThreadState *tstate)
if (tstate != _PyThreadState_GET()) {
Py_FatalError("thread is not current");
}
- if (tstate->cframe->current_frame != NULL) {
+ if (tstate->current_frame != NULL) {
Py_FatalError("thread still has a frame");
}
interp->finalizing = 1;
diff --git a/Python/pystate.c b/Python/pystate.c
index 3a05cb0..01651d7 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1310,7 +1310,7 @@ init_threadstate(PyThreadState *tstate,
// This is cleared when PyGILState_Ensure() creates the thread state.
tstate->gilstate_counter = 1;
- tstate->cframe = &tstate->root_cframe;
+ tstate->current_frame = NULL;
tstate->datastack_chunk = NULL;
tstate->datastack_top = NULL;
tstate->datastack_limit = NULL;
@@ -1452,7 +1452,7 @@ PyThreadState_Clear(PyThreadState *tstate)
int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;
- if (verbose && tstate->cframe->current_frame != NULL) {
+ if (verbose && tstate->current_frame != NULL) {
/* bpo-20526: After the main thread calls
_PyInterpreterState_SetFinalizing() in Py_FinalizeEx()
(or in Py_EndInterpreter() for subinterpreters),
@@ -1953,7 +1953,7 @@ _PyThread_CurrentFrames(void)
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
PyThreadState *t;
for (t = i->threads.head; t != NULL; t = t->next) {
- _PyInterpreterFrame *frame = t->cframe->current_frame;
+ _PyInterpreterFrame *frame = t->current_frame;
frame = _PyFrame_GetFirstComplete(frame);
if (frame == NULL) {
continue;
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index be026d9..f829011 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1954,7 +1954,7 @@ sys__getframe_impl(PyObject *module, int depth)
/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
{
PyThreadState *tstate = _PyThreadState_GET();
- _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+ _PyInterpreterFrame *frame = tstate->current_frame;
if (frame != NULL) {
while (depth > 0) {
@@ -2270,7 +2270,7 @@ sys__getframemodulename_impl(PyObject *module, int depth)
if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
return NULL;
}
- _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame;
+ _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
f = f->previous;
}
diff --git a/Python/traceback.c b/Python/traceback.c
index ca524b1..bddb876 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -1207,7 +1207,7 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header)
PUTS(fd, "Stack (most recent call first):\n");
}
- frame = tstate->cframe->current_frame;
+ frame = tstate->current_frame;
if (frame == NULL) {
PUTS(fd, " <no Python frame>\n");
return;