gh-100758: Refactor initialisation of frame headers into a single function (_PyFrame_Initialize) (GH-100759)

This commit is contained in:
Irit Katriel 2023-01-06 14:55:56 +00:00 committed by GitHub
parent 78068126a1
commit 15c44789bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 21 additions and 53 deletions

View file

@ -110,9 +110,9 @@ void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
when frame is linked into the frame stack. when frame is linked into the frame stack.
*/ */
static inline void static inline void
_PyFrame_InitializeSpecials( _PyFrame_Initialize(
_PyInterpreterFrame *frame, PyFunctionObject *func, _PyInterpreterFrame *frame, PyFunctionObject *func,
PyObject *locals, PyCodeObject *code) PyObject *locals, PyCodeObject *code, int null_locals_from)
{ {
frame->f_funcobj = (PyObject *)func; frame->f_funcobj = (PyObject *)func;
frame->f_code = (PyCodeObject *)Py_NewRef(code); frame->f_code = (PyCodeObject *)Py_NewRef(code);
@ -124,6 +124,10 @@ _PyFrame_InitializeSpecials(
frame->prev_instr = _PyCode_CODE(code) - 1; frame->prev_instr = _PyCode_CODE(code) - 1;
frame->yield_offset = 0; frame->yield_offset = 0;
frame->owner = FRAME_OWNED_BY_THREAD; frame->owner = FRAME_OWNED_BY_THREAD;
for (int i = null_locals_from; i < code->co_nlocalsplus; i++) {
frame->localsplus[i] = NULL;
}
} }
/* Gets the pointer to the locals array /* Gets the pointer to the locals array
@ -224,14 +228,14 @@ void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
* Must be guarded by _PyThreadState_HasStackSpace() * Must be guarded by _PyThreadState_HasStackSpace()
* Consumes reference to func. */ * Consumes reference to func. */
static inline _PyInterpreterFrame * static inline _PyInterpreterFrame *
_PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func) _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_locals_from)
{ {
CALL_STAT_INC(frames_pushed); CALL_STAT_INC(frames_pushed);
PyCodeObject *code = (PyCodeObject *)func->func_code; PyCodeObject *code = (PyCodeObject *)func->func_code;
_PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top; _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top;
tstate->datastack_top += code->co_framesize; tstate->datastack_top += code->co_framesize;
assert(tstate->datastack_top < tstate->datastack_limit); assert(tstate->datastack_top < tstate->datastack_limit);
_PyFrame_InitializeSpecials(new_frame, func, NULL, code); _PyFrame_Initialize(new_frame, func, NULL, code, null_locals_from);
return new_frame; return new_frame;
} }

View file

@ -1011,12 +1011,9 @@ static void
init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals) init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals)
{ {
PyCodeObject *code = (PyCodeObject *)func->func_code; PyCodeObject *code = (PyCodeObject *)func->func_code;
_PyFrame_InitializeSpecials(frame, (PyFunctionObject*)Py_NewRef(func), _PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func),
Py_XNewRef(locals), code); Py_XNewRef(locals), code, 0);
frame->previous = NULL; frame->previous = NULL;
for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) {
frame->localsplus[i] = NULL;
}
} }
PyFrameObject* PyFrameObject*

View file

@ -448,13 +448,10 @@ dummy_func(
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
STAT_INC(BINARY_SUBSCR, hit); STAT_INC(BINARY_SUBSCR, hit);
Py_INCREF(getitem); Py_INCREF(getitem);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2);
STACK_SHRINK(2); STACK_SHRINK(2);
new_frame->localsplus[0] = container; new_frame->localsplus[0] = container;
new_frame->localsplus[1] = sub; new_frame->localsplus[1] = sub;
for (int i = 2; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
@ -1714,14 +1711,11 @@ dummy_func(
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
Py_INCREF(fget); Py_INCREF(fget);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1);
SET_TOP(NULL); SET_TOP(NULL);
int shrink_stack = !(oparg & 1); int shrink_stack = !(oparg & 1);
STACK_SHRINK(shrink_stack); STACK_SHRINK(shrink_stack);
new_frame->localsplus[0] = owner; new_frame->localsplus[0] = owner;
for (int i = 1; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
@ -1749,15 +1743,12 @@ dummy_func(
PyObject *name = GETITEM(names, oparg >> 1); PyObject *name = GETITEM(names, oparg >> 1);
Py_INCREF(f); Py_INCREF(f);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2);
SET_TOP(NULL); SET_TOP(NULL);
int shrink_stack = !(oparg & 1); int shrink_stack = !(oparg & 1);
STACK_SHRINK(shrink_stack); STACK_SHRINK(shrink_stack);
new_frame->localsplus[0] = owner; new_frame->localsplus[0] = owner;
new_frame->localsplus[1] = Py_NewRef(name); new_frame->localsplus[1] = Py_NewRef(name);
for (int i = 2; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
@ -2672,14 +2663,11 @@ dummy_func(
DEOPT_IF(code->co_argcount != argcount, CALL); DEOPT_IF(code->co_argcount != argcount, CALL);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount);
STACK_SHRINK(argcount); STACK_SHRINK(argcount);
for (int i = 0; i < argcount; i++) { for (int i = 0; i < argcount; i++) {
new_frame->localsplus[i] = stack_pointer[i]; new_frame->localsplus[i] = stack_pointer[i];
} }
for (int i = argcount; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
STACK_SHRINK(2-is_meth); STACK_SHRINK(2-is_meth);
JUMPBY(INLINE_CACHE_ENTRIES_CALL); JUMPBY(INLINE_CACHE_ENTRIES_CALL);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
@ -2702,7 +2690,7 @@ dummy_func(
DEOPT_IF(argcount < minargs, CALL); DEOPT_IF(argcount < minargs, CALL);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount);
STACK_SHRINK(argcount); STACK_SHRINK(argcount);
for (int i = 0; i < argcount; i++) { for (int i = 0; i < argcount; i++) {
new_frame->localsplus[i] = stack_pointer[i]; new_frame->localsplus[i] = stack_pointer[i];
@ -2712,9 +2700,6 @@ dummy_func(
i - minargs); i - minargs);
new_frame->localsplus[i] = Py_NewRef(def); new_frame->localsplus[i] = Py_NewRef(def);
} }
for (int i = code->co_argcount; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
STACK_SHRINK(2-is_meth); STACK_SHRINK(2-is_meth);
JUMPBY(INLINE_CACHE_ENTRIES_CALL); JUMPBY(INLINE_CACHE_ENTRIES_CALL);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);

View file

@ -1974,11 +1974,8 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
if (frame == NULL) { if (frame == NULL) {
goto fail; goto fail;
} }
_PyFrame_InitializeSpecials(frame, func, locals, code); _PyFrame_Initialize(frame, func, locals, code, 0);
PyObject **localsarray = &frame->localsplus[0]; PyObject **localsarray = &frame->localsplus[0];
for (int i = 0; i < code->co_nlocalsplus; i++) {
localsarray[i] = NULL;
}
if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) { if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) {
assert(frame->owner != FRAME_OWNED_BY_GENERATOR); assert(frame->owner != FRAME_OWNED_BY_GENERATOR);
_PyEvalFrameClearAndPop(tstate, frame); _PyEvalFrameClearAndPop(tstate, frame);

View file

@ -564,13 +564,10 @@
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
STAT_INC(BINARY_SUBSCR, hit); STAT_INC(BINARY_SUBSCR, hit);
Py_INCREF(getitem); Py_INCREF(getitem);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2);
STACK_SHRINK(2); STACK_SHRINK(2);
new_frame->localsplus[0] = container; new_frame->localsplus[0] = container;
new_frame->localsplus[1] = sub; new_frame->localsplus[1] = sub;
for (int i = 2; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
@ -1941,14 +1938,11 @@
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
Py_INCREF(fget); Py_INCREF(fget);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1);
SET_TOP(NULL); SET_TOP(NULL);
int shrink_stack = !(oparg & 1); int shrink_stack = !(oparg & 1);
STACK_SHRINK(shrink_stack); STACK_SHRINK(shrink_stack);
new_frame->localsplus[0] = owner; new_frame->localsplus[0] = owner;
for (int i = 1; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
@ -1975,15 +1969,12 @@
PyObject *name = GETITEM(names, oparg >> 1); PyObject *name = GETITEM(names, oparg >> 1);
Py_INCREF(f); Py_INCREF(f);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2);
SET_TOP(NULL); SET_TOP(NULL);
int shrink_stack = !(oparg & 1); int shrink_stack = !(oparg & 1);
STACK_SHRINK(shrink_stack); STACK_SHRINK(shrink_stack);
new_frame->localsplus[0] = owner; new_frame->localsplus[0] = owner;
new_frame->localsplus[1] = Py_NewRef(name); new_frame->localsplus[1] = Py_NewRef(name);
for (int i = 2; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
@ -3011,14 +3002,11 @@
DEOPT_IF(code->co_argcount != argcount, CALL); DEOPT_IF(code->co_argcount != argcount, CALL);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount);
STACK_SHRINK(argcount); STACK_SHRINK(argcount);
for (int i = 0; i < argcount; i++) { for (int i = 0; i < argcount; i++) {
new_frame->localsplus[i] = stack_pointer[i]; new_frame->localsplus[i] = stack_pointer[i];
} }
for (int i = argcount; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
STACK_SHRINK(2-is_meth); STACK_SHRINK(2-is_meth);
JUMPBY(INLINE_CACHE_ENTRIES_CALL); JUMPBY(INLINE_CACHE_ENTRIES_CALL);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
@ -3040,7 +3028,7 @@
DEOPT_IF(argcount < minargs, CALL); DEOPT_IF(argcount < minargs, CALL);
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount);
STACK_SHRINK(argcount); STACK_SHRINK(argcount);
for (int i = 0; i < argcount; i++) { for (int i = 0; i < argcount; i++) {
new_frame->localsplus[i] = stack_pointer[i]; new_frame->localsplus[i] = stack_pointer[i];
@ -3050,9 +3038,6 @@
i - minargs); i - minargs);
new_frame->localsplus[i] = Py_NewRef(def); new_frame->localsplus[i] = Py_NewRef(def);
} }
for (int i = code->co_argcount; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
}
STACK_SHRINK(2-is_meth); STACK_SHRINK(2-is_meth);
JUMPBY(INLINE_CACHE_ENTRIES_CALL); JUMPBY(INLINE_CACHE_ENTRIES_CALL);
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);