Skip to content

Commit 6f8b0e7

Browse files
authored
Add a macro for "inlining" new frames (GH-99490)
1 parent a0d940d commit 6f8b0e7

File tree

3 files changed

+28
-86
lines changed

3 files changed

+28
-86
lines changed

Python/bytecodes.c

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,8 @@ dummy_func(
467467
for (int i = 2; i < code->co_nlocalsplus; i++) {
468468
new_frame->localsplus[i] = NULL;
469469
}
470-
_PyFrame_SetStackPointer(frame, stack_pointer);
471470
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
472-
frame->prev_instr = next_instr - 1;
473-
new_frame->previous = frame;
474-
frame = cframe.current_frame = new_frame;
475-
CALL_STAT_INC(inlined_py_calls);
476-
goto start_frame;
471+
DISPATCH_INLINED(new_frame);
477472
}
478473

479474
// stack effect: (__0 -- )
@@ -1938,13 +1933,8 @@ dummy_func(
19381933
for (int i = 1; i < code->co_nlocalsplus; i++) {
19391934
new_frame->localsplus[i] = NULL;
19401935
}
1941-
_PyFrame_SetStackPointer(frame, stack_pointer);
19421936
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
1943-
frame->prev_instr = next_instr - 1;
1944-
new_frame->previous = frame;
1945-
frame = cframe.current_frame = new_frame;
1946-
CALL_STAT_INC(inlined_py_calls);
1947-
goto start_frame;
1937+
DISPATCH_INLINED(new_frame);
19481938
}
19491939

19501940
// error: LOAD_ATTR has irregular stack effect
@@ -1979,13 +1969,8 @@ dummy_func(
19791969
for (int i = 2; i < code->co_nlocalsplus; i++) {
19801970
new_frame->localsplus[i] = NULL;
19811971
}
1982-
_PyFrame_SetStackPointer(frame, stack_pointer);
19831972
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
1984-
frame->prev_instr = next_instr - 1;
1985-
new_frame->previous = frame;
1986-
frame = cframe.current_frame = new_frame;
1987-
CALL_STAT_INC(inlined_py_calls);
1988-
goto start_frame;
1973+
DISPATCH_INLINED(new_frame);
19891974
}
19901975

19911976
// stack effect: (__0, __1 -- )
@@ -2685,18 +2670,14 @@ dummy_func(
26852670
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER);
26862671
STAT_INC(FOR_ITER, hit);
26872672
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
2688-
_PyFrame_SetStackPointer(frame, stack_pointer);
26892673
frame->yield_offset = oparg;
2690-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
2691-
assert(_Py_OPCODE(*next_instr) == END_FOR);
2692-
frame->prev_instr = next_instr - 1;
26932674
_PyFrame_StackPush(gen_frame, Py_NewRef(Py_None));
26942675
gen->gi_frame_state = FRAME_EXECUTING;
26952676
gen->gi_exc_state.previous_item = tstate->exc_info;
26962677
tstate->exc_info = &gen->gi_exc_state;
2697-
gen_frame->previous = frame;
2698-
frame = cframe.current_frame = gen_frame;
2699-
goto start_frame;
2678+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
2679+
assert(_Py_OPCODE(*next_instr) == END_FOR);
2680+
DISPATCH_INLINED(gen_frame);
27002681
}
27012682

27022683
// stack effect: ( -- __0)
@@ -2978,13 +2959,8 @@ dummy_func(
29782959
if (new_frame == NULL) {
29792960
goto error;
29802961
}
2981-
_PyFrame_SetStackPointer(frame, stack_pointer);
29822962
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
2983-
frame->prev_instr = next_instr - 1;
2984-
new_frame->previous = frame;
2985-
cframe.current_frame = frame = new_frame;
2986-
CALL_STAT_INC(inlined_py_calls);
2987-
goto start_frame;
2963+
DISPATCH_INLINED(new_frame);
29882964
}
29892965
/* Callable is not a normal Python function */
29902966
PyObject *res;
@@ -3032,7 +3008,6 @@ dummy_func(
30323008
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
30333009
STAT_INC(CALL, hit);
30343010
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func);
3035-
CALL_STAT_INC(inlined_py_calls);
30363011
STACK_SHRINK(argcount);
30373012
for (int i = 0; i < argcount; i++) {
30383013
new_frame->localsplus[i] = stack_pointer[i];
@@ -3041,12 +3016,8 @@ dummy_func(
30413016
new_frame->localsplus[i] = NULL;
30423017
}
30433018
STACK_SHRINK(2-is_meth);
3044-
_PyFrame_SetStackPointer(frame, stack_pointer);
30453019
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
3046-
frame->prev_instr = next_instr - 1;
3047-
new_frame->previous = frame;
3048-
frame = cframe.current_frame = new_frame;
3049-
goto start_frame;
3020+
DISPATCH_INLINED(new_frame);
30503021
}
30513022

30523023
// stack effect: (__0, __array[oparg] -- )
@@ -3067,7 +3038,6 @@ dummy_func(
30673038
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
30683039
STAT_INC(CALL, hit);
30693040
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func);
3070-
CALL_STAT_INC(inlined_py_calls);
30713041
STACK_SHRINK(argcount);
30723042
for (int i = 0; i < argcount; i++) {
30733043
new_frame->localsplus[i] = stack_pointer[i];
@@ -3081,12 +3051,8 @@ dummy_func(
30813051
new_frame->localsplus[i] = NULL;
30823052
}
30833053
STACK_SHRINK(2-is_meth);
3084-
_PyFrame_SetStackPointer(frame, stack_pointer);
30853054
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
3086-
frame->prev_instr = next_instr - 1;
3087-
new_frame->previous = frame;
3088-
frame = cframe.current_frame = new_frame;
3089-
goto start_frame;
3055+
DISPATCH_INLINED(new_frame);
30903056
}
30913057

30923058
// stack effect: (__0, __array[oparg] -- )

Python/ceval.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
712712
DISPATCH_GOTO(); \
713713
}
714714

715+
#define DISPATCH_INLINED(NEW_FRAME) \
716+
do { \
717+
_PyFrame_SetStackPointer(frame, stack_pointer); \
718+
frame->prev_instr = next_instr - 1; \
719+
(NEW_FRAME)->previous = frame; \
720+
frame = cframe.current_frame = (NEW_FRAME); \
721+
CALL_STAT_INC(inlined_py_calls); \
722+
goto start_frame; \
723+
} while (0)
724+
715725
#define CHECK_EVAL_BREAKER() \
716726
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \
717727
if (_Py_atomic_load_relaxed_int32(eval_breaker)) { \

Python/generated_cases.c.h

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

0 commit comments

Comments
 (0)