bpo-44878: _PyEval_EvalFrameDefault readability improvements (GH-27725)

* Move a few variable declarations to point of definition.

* Factor out tracing of function entry into helper function.
This commit is contained in:
Mark Shannon 2021-08-11 11:47:52 +01:00 committed by GitHub
parent 1841c70f2b
commit 3f3d5dcac3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1392,56 +1392,9 @@ eval_frame_handle_pending(PyThreadState *tstate)
#define BUILTINS() frame->f_builtins
#define LOCALS() frame->f_locals
PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag)
static int
trace_function_entry(PyThreadState *tstate, InterpreterFrame *frame)
{
_Py_EnsureTstateNotNULL(tstate);
#if USE_COMPUTED_GOTOS
/* Import the static jump table */
#include "opcode_targets.h"
#endif
#ifdef DXPAIRS
int lastopcode = 0;
#endif
PyObject **stack_pointer; /* Next free slot in value stack */
_Py_CODEUNIT *next_instr;
int opcode; /* Current opcode */
int oparg; /* Current opcode argument, if any */
PyObject **localsplus;
PyObject *retval = NULL; /* Return value */
_Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker;
PyCodeObject *co;
_Py_CODEUNIT *first_instr;
PyObject *names;
PyObject *consts;
#ifdef LLTRACE
_Py_IDENTIFIER(__ltrace__);
#endif
if (_Py_EnterRecursiveCall(tstate, "")) {
return NULL;
}
CFrame cframe;
/* WARNING: Because the CFrame lives on the C stack,
* but can be accessed from a heap allocated object (tstate)
* strict stack discipline must be maintained.
*/
CFrame *prev_cframe = tstate->cframe;
cframe.use_tracing = prev_cframe->use_tracing;
cframe.previous = prev_cframe;
tstate->cframe = &cframe;
/* push frame */
tstate->frame = frame;
co = frame->f_code;
if (cframe.use_tracing) {
if (tstate->c_tracefunc != NULL) {
/* tstate->c_tracefunc, if defined, is a
function that will be called on *every* entry
@ -1461,7 +1414,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
tstate, frame,
PyTrace_CALL, Py_None)) {
/* Trace function raised an error */
goto exit_eval_frame;
return -1;
}
}
if (tstate->c_profilefunc != NULL) {
@ -1472,14 +1425,58 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
tstate, frame,
PyTrace_CALL, Py_None)) {
/* Profile function raised an error */
goto exit_eval_frame;
return -1;
}
}
return 0;
}
PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag)
{
_Py_EnsureTstateNotNULL(tstate);
#if USE_COMPUTED_GOTOS
/* Import the static jump table */
#include "opcode_targets.h"
#endif
#ifdef DXPAIRS
int lastopcode = 0;
#endif
int opcode; /* Current opcode */
int oparg; /* Current opcode argument, if any */
PyObject *retval = NULL; /* Return value */
_Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker;
if (_Py_EnterRecursiveCall(tstate, "")) {
return NULL;
}
CFrame cframe;
/* WARNING: Because the CFrame lives on the C stack,
* but can be accessed from a heap allocated object (tstate)
* strict stack discipline must be maintained.
*/
CFrame *prev_cframe = tstate->cframe;
cframe.use_tracing = prev_cframe->use_tracing;
cframe.previous = prev_cframe;
tstate->cframe = &cframe;
/* push frame */
tstate->frame = frame;
if (cframe.use_tracing) {
if (trace_function_entry(tstate, frame)) {
goto exit_eval_frame;
}
}
if (PyDTrace_FUNCTION_ENTRY_ENABLED())
dtrace_function_entry(frame);
PyCodeObject *co = frame->f_code;
/* Increment the warmup counter and quicken if warm enough
* _Py_Quicken is idempotent so we don't worry about overflow */
if (!PyCodeObject_IsWarmedUp(co)) {
@ -1492,10 +1489,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
}
names = co->co_names;
consts = co->co_consts;
localsplus = _PyFrame_GetLocalsArray(frame);
first_instr = co->co_firstinstr;
PyObject *names = co->co_names;
PyObject *consts = co->co_consts;
PyObject **localsplus = _PyFrame_GetLocalsArray(frame);
_Py_CODEUNIT *first_instr = co->co_firstinstr;
/*
frame->f_lasti refers to the index of the last instruction,
unless it's -1 in which case next_instr should be first_instr.
@ -1512,8 +1509,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
to the beginning of the combined pair.)
*/
assert(frame->f_lasti >= -1);
next_instr = first_instr + frame->f_lasti + 1;
stack_pointer = frame->stack + frame->stackdepth;
_Py_CODEUNIT *next_instr = first_instr + frame->f_lasti + 1;
PyObject **stack_pointer = frame->stack + frame->stackdepth;
/* Set stackdepth to -1.
* Update when returning or calling trace function.
Having f_stackdepth <= 0 ensures that invalid
@ -1524,6 +1521,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
frame->f_state = FRAME_EXECUTING;
#ifdef LLTRACE
_Py_IDENTIFIER(__ltrace__);
{
int r = _PyDict_ContainsId(GLOBALS(), &PyId___ltrace__);
if (r < 0) {