Skip to content

Commit 15c4478

Browse files
authored
gh-100758: Refactor initialisation of frame headers into a single function (_PyFrame_Initialize) (GH-100759)
1 parent 7806812 commit 15c4478

File tree

5 files changed

+21
-53
lines changed

5 files changed

+21
-53
lines changed

Include/internal/pycore_frame.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
110110
when frame is linked into the frame stack.
111111
*/
112112
static inline void
113-
_PyFrame_InitializeSpecials(
113+
_PyFrame_Initialize(
114114
_PyInterpreterFrame *frame, PyFunctionObject *func,
115-
PyObject *locals, PyCodeObject *code)
115+
PyObject *locals, PyCodeObject *code, int null_locals_from)
116116
{
117117
frame->f_funcobj = (PyObject *)func;
118118
frame->f_code = (PyCodeObject *)Py_NewRef(code);
@@ -124,6 +124,10 @@ _PyFrame_InitializeSpecials(
124124
frame->prev_instr = _PyCode_CODE(code) - 1;
125125
frame->yield_offset = 0;
126126
frame->owner = FRAME_OWNED_BY_THREAD;
127+
128+
for (int i = null_locals_from; i < code->co_nlocalsplus; i++) {
129+
frame->localsplus[i] = NULL;
130+
}
127131
}
128132

129133
/* Gets the pointer to the locals array
@@ -224,14 +228,14 @@ void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
224228
* Must be guarded by _PyThreadState_HasStackSpace()
225229
* Consumes reference to func. */
226230
static inline _PyInterpreterFrame *
227-
_PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func)
231+
_PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_locals_from)
228232
{
229233
CALL_STAT_INC(frames_pushed);
230234
PyCodeObject *code = (PyCodeObject *)func->func_code;
231235
_PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top;
232236
tstate->datastack_top += code->co_framesize;
233237
assert(tstate->datastack_top < tstate->datastack_limit);
234-
_PyFrame_InitializeSpecials(new_frame, func, NULL, code);
238+
_PyFrame_Initialize(new_frame, func, NULL, code, null_locals_from);
235239
return new_frame;
236240
}
237241

Objects/frameobject.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,12 +1011,9 @@ static void
10111011
init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals)
10121012
{
10131013
PyCodeObject *code = (PyCodeObject *)func->func_code;
1014-
_PyFrame_InitializeSpecials(frame, (PyFunctionObject*)Py_NewRef(func),
1015-
Py_XNewRef(locals), code);
1014+
_PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func),
1015+
Py_XNewRef(locals), code, 0);
10161016
frame->previous = NULL;
1017-
for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) {
1018-
frame->localsplus[i] = NULL;
1019-
}
10201017
}
10211018

10221019
PyFrameObject*

Python/bytecodes.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -448,13 +448,10 @@ dummy_func(
448448
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR);
449449
STAT_INC(BINARY_SUBSCR, hit);
450450
Py_INCREF(getitem);
451-
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem);
451+
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2);
452452
STACK_SHRINK(2);
453453
new_frame->localsplus[0] = container;
454454
new_frame->localsplus[1] = sub;
455-
for (int i = 2; i < code->co_nlocalsplus; i++) {
456-
new_frame->localsplus[i] = NULL;
457-
}
458455
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
459456
DISPATCH_INLINED(new_frame);
460457
}
@@ -1714,14 +1711,11 @@ dummy_func(
17141711
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR);
17151712
STAT_INC(LOAD_ATTR, hit);
17161713
Py_INCREF(fget);
1717-
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f);
1714+
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1);
17181715
SET_TOP(NULL);
17191716
int shrink_stack = !(oparg & 1);
17201717
STACK_SHRINK(shrink_stack);
17211718
new_frame->localsplus[0] = owner;
1722-
for (int i = 1; i < code->co_nlocalsplus; i++) {
1723-
new_frame->localsplus[i] = NULL;
1724-
}
17251719
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
17261720
DISPATCH_INLINED(new_frame);
17271721
}
@@ -1749,15 +1743,12 @@ dummy_func(
17491743

17501744
PyObject *name = GETITEM(names, oparg >> 1);
17511745
Py_INCREF(f);
1752-
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f);
1746+
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2);
17531747
SET_TOP(NULL);
17541748
int shrink_stack = !(oparg & 1);
17551749
STACK_SHRINK(shrink_stack);
17561750
new_frame->localsplus[0] = owner;
17571751
new_frame->localsplus[1] = Py_NewRef(name);
1758-
for (int i = 2; i < code->co_nlocalsplus; i++) {
1759-
new_frame->localsplus[i] = NULL;
1760-
}
17611752
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
17621753
DISPATCH_INLINED(new_frame);
17631754
}
@@ -2672,14 +2663,11 @@ dummy_func(
26722663
DEOPT_IF(code->co_argcount != argcount, CALL);
26732664
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
26742665
STAT_INC(CALL, hit);
2675-
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func);
2666+
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount);
26762667
STACK_SHRINK(argcount);
26772668
for (int i = 0; i < argcount; i++) {
26782669
new_frame->localsplus[i] = stack_pointer[i];
26792670
}
2680-
for (int i = argcount; i < code->co_nlocalsplus; i++) {
2681-
new_frame->localsplus[i] = NULL;
2682-
}
26832671
STACK_SHRINK(2-is_meth);
26842672
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
26852673
DISPATCH_INLINED(new_frame);
@@ -2702,7 +2690,7 @@ dummy_func(
27022690
DEOPT_IF(argcount < minargs, CALL);
27032691
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
27042692
STAT_INC(CALL, hit);
2705-
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func);
2693+
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount);
27062694
STACK_SHRINK(argcount);
27072695
for (int i = 0; i < argcount; i++) {
27082696
new_frame->localsplus[i] = stack_pointer[i];
@@ -2712,9 +2700,6 @@ dummy_func(
27122700
i - minargs);
27132701
new_frame->localsplus[i] = Py_NewRef(def);
27142702
}
2715-
for (int i = code->co_argcount; i < code->co_nlocalsplus; i++) {
2716-
new_frame->localsplus[i] = NULL;
2717-
}
27182703
STACK_SHRINK(2-is_meth);
27192704
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
27202705
DISPATCH_INLINED(new_frame);

Python/ceval.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,11 +1974,8 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
19741974
if (frame == NULL) {
19751975
goto fail;
19761976
}
1977-
_PyFrame_InitializeSpecials(frame, func, locals, code);
1977+
_PyFrame_Initialize(frame, func, locals, code, 0);
19781978
PyObject **localsarray = &frame->localsplus[0];
1979-
for (int i = 0; i < code->co_nlocalsplus; i++) {
1980-
localsarray[i] = NULL;
1981-
}
19821979
if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) {
19831980
assert(frame->owner != FRAME_OWNED_BY_GENERATOR);
19841981
_PyEvalFrameClearAndPop(tstate, frame);

Python/generated_cases.c.h

Lines changed: 5 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)