The Wayback Machine - https://web.archive.org/web/20211103162904/https://github.com/python/cpython/pull/27933/files
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-44990: Change layout of evaluation frames. "Layout B" #27933

Merged
merged 6 commits into from Aug 25, 2021
Merged
@@ -29,10 +29,9 @@ typedef struct _interpreter_frame {
PyObject *generator;
struct _interpreter_frame *previous;
int f_lasti; /* Last instruction if called */
int stackdepth; /* Depth of value stack */
int nlocalsplus;
PyFrameState f_state; /* What state the frame is in */
PyObject *stack[1];
int stacktop; /* Offset of TOS from localsplus */
PyFrameState f_state; /* What state the frame is in */
PyObject *localsplus[1];
} InterpreterFrame;

static inline int _PyFrame_IsRunnable(InterpreterFrame *f) {
@@ -47,6 +46,26 @@ static inline int _PyFrameHasCompleted(InterpreterFrame *f) {
return f->f_state > FRAME_EXECUTING;
}

static inline PyObject **_PyFrame_Stackbase(InterpreterFrame *f) {
return f->localsplus + f->f_code->co_nlocalsplus;
}

static inline PyObject *_PyFrame_StackPeek(InterpreterFrame *f) {
assert(f->stacktop > f->f_code->co_nlocalsplus);
return f->localsplus[f->stacktop-1];
}

static inline PyObject *_PyFrame_StackPop(InterpreterFrame *f) {
assert(f->stacktop > f->f_code->co_nlocalsplus);
f->stacktop--;
return f->localsplus[f->stacktop];
}

static inline void _PyFrame_StackPush(InterpreterFrame *f, PyObject *value) {
f->localsplus[f->stacktop] = value;
f->stacktop++;
}

#define FRAME_SPECIALS_SIZE ((sizeof(InterpreterFrame)-1)/sizeof(PyObject *))

InterpreterFrame *
@@ -61,8 +80,7 @@ _PyFrame_InitializeSpecials(
frame->f_builtins = Py_NewRef(con->fc_builtins);
frame->f_globals = Py_NewRef(con->fc_globals);
frame->f_locals = Py_XNewRef(locals);
frame->nlocalsplus = nlocalsplus;
frame->stackdepth = 0;
frame->stacktop = nlocalsplus;
frame->frame_obj = NULL;
frame->generator = NULL;
frame->f_lasti = -1;
@@ -75,7 +93,19 @@ _PyFrame_InitializeSpecials(
static inline PyObject**
_PyFrame_GetLocalsArray(InterpreterFrame *frame)
{
return ((PyObject **)frame) - frame->nlocalsplus;
return frame->localsplus;
}

static inline PyObject**
_PyFrame_GetStackPointer(InterpreterFrame *frame)
{
return frame->localsplus+frame->stacktop;
}

static inline void
_PyFrame_SetStackPointer(InterpreterFrame *frame, PyObject **stack_pointer)
{
frame->stacktop = (int)(stack_pointer - frame->localsplus);
}

/* For use by _PyFrame_GetFrameObject
@@ -397,9 +397,7 @@ first_line_not_before(int *lines, int len, int line)
static void
frame_stack_pop(PyFrameObject *f)
{
assert(f->f_frame->stackdepth > 0);
f->f_frame->stackdepth--;
PyObject *v = f->f_frame->stack[f->f_frame->stackdepth];
PyObject *v = _PyFrame_StackPop(f->f_frame);
Py_DECREF(v);
}

@@ -633,14 +631,10 @@ frame_dealloc(PyFrameObject *f)
Py_CLEAR(frame->f_builtins);
Py_CLEAR(frame->f_locals);
PyObject **locals = _PyFrame_GetLocalsArray(frame);
for (int i = 0; i < co->co_nlocalsplus; i++) {
for (int i = 0; i < frame->stacktop; i++) {
Py_CLEAR(locals[i]);
}
/* stack */
for (int i = 0; i < frame->stackdepth; i++) {
Py_CLEAR(frame->stack[i]);
}
PyMem_Free(locals);
PyMem_Free(frame);
}
Py_CLEAR(f->f_back);
Py_CLEAR(f->f_trace);
@@ -686,17 +680,13 @@ frame_tp_clear(PyFrameObject *f)

Py_CLEAR(f->f_trace);

/* locals */
/* locals and stack */
PyObject **locals = _PyFrame_GetLocalsArray(f->f_frame);
for (int i = 0; i < f->f_frame->nlocalsplus; i++) {
assert(f->f_frame->stacktop >= 0);
for (int i = 0; i < f->f_frame->stacktop; i++) {
Py_CLEAR(locals[i]);
}

/* stack */
for (int i = 0; i < f->f_frame->stackdepth; i++) {
Py_CLEAR(f->f_frame->stack[i]);
}
f->f_frame->stackdepth = 0;
f->f_frame->stacktop = 0;
return 0;
}

@@ -190,8 +190,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult,
/* Push arg onto the frame's value stack */
result = arg ? arg : Py_None;
Py_INCREF(result);
frame->stack[frame->stackdepth] = result;
frame->stackdepth++;
_PyFrame_StackPush(frame, result);

frame->previous = tstate->frame;

@@ -350,8 +349,7 @@ _PyGen_yf(PyGenObject *gen)

if (code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)] != YIELD_FROM)
return NULL;
assert(frame->stackdepth > 0);
yf = frame->stack[frame->stackdepth-1];
yf = _PyFrame_StackPeek(frame);
Py_INCREF(yf);
}

@@ -469,9 +467,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
if (!ret) {
PyObject *val;
/* Pop subiterator from stack */
assert(gen->gi_xframe->stackdepth > 0);
gen->gi_xframe->stackdepth--;
ret = gen->gi_xframe->stack[gen->gi_xframe->stackdepth];
ret = _PyFrame_StackPop(gen->gi_xframe);
assert(ret == yf);
Py_DECREF(ret);
/* Termination repetition of YIELD_FROM */
@@ -8874,7 +8874,7 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co,
return -1;
}

assert(f->f_frame->nlocalsplus > 0);
assert(f->f_frame->f_code->co_nlocalsplus > 0);
PyObject *firstarg = _PyFrame_GetLocalsArray(f->f_frame)[0];
// The first argument might be a cell.
if (firstarg != NULL && (_PyLocals_GetKind(co->co_localspluskinds, 0) & CO_FAST_CELL)) {