Skip to content

Commit fad1c67

Browse files
committed
Handle RETURN_GENERATOR in tier 2
1 parent a6647d1 commit fad1c67

11 files changed

+120
-59
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_ids.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

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

Python/bytecodes.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -837,12 +837,7 @@ dummy_func(
837837
_PyFrame_StackPush(frame, retval);
838838
LOAD_SP();
839839
LOAD_IP(frame->return_offset);
840-
#if LLTRACE && TIER_ONE
841-
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
842-
if (lltrace < 0) {
843-
goto exit_unwind;
844-
}
845-
#endif
840+
LLTRACE_RESUME_FRAME();
846841
}
847842

848843
macro(RETURN_VALUE) =
@@ -3186,12 +3181,7 @@ dummy_func(
31863181
tstate->py_recursion_remaining--;
31873182
LOAD_SP();
31883183
LOAD_IP(0);
3189-
#if LLTRACE && TIER_ONE
3190-
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
3191-
if (lltrace < 0) {
3192-
goto exit_unwind;
3193-
}
3194-
#endif
3184+
LLTRACE_RESUME_FRAME();
31953185
}
31963186

31973187
macro(CALL_BOUND_METHOD_EXACT_ARGS) =
@@ -3877,7 +3867,7 @@ dummy_func(
38773867
}
38783868
}
38793869

3880-
tier1 inst(RETURN_GENERATOR, (--)) {
3870+
inst(RETURN_GENERATOR, (-- res)) {
38813871
assert(PyFunction_Check(frame->f_funcobj));
38823872
PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
38833873
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
@@ -3887,19 +3877,21 @@ dummy_func(
38873877
assert(EMPTY());
38883878
_PyFrame_SetStackPointer(frame, stack_pointer);
38893879
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
3890-
frame->instr_ptr = next_instr;
3880+
frame->instr_ptr++;
38913881
_PyFrame_Copy(frame, gen_frame);
38923882
assert(frame->frame_obj == NULL);
38933883
gen->gi_frame_state = FRAME_CREATED;
38943884
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
38953885
_Py_LeaveRecursiveCallPy(tstate);
3886+
res = (PyObject *)gen;
3887+
38963888
assert(frame != &entry_frame);
38973889
_PyInterpreterFrame *prev = frame->previous;
38983890
_PyThreadState_PopFrame(tstate, frame);
38993891
frame = tstate->current_frame = prev;
3900-
_PyFrame_StackPush(frame, (PyObject *)gen);
39013892
LOAD_IP(frame->return_offset);
3902-
goto resume_frame;
3893+
LOAD_SP();
3894+
LLTRACE_RESUME_FRAME();
39033895
}
39043896

39053897
inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) {

Python/ceval_macros.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@
8686
#define PRE_DISPATCH_GOTO() ((void)0)
8787
#endif
8888

89+
#if LLTRACE
90+
#define LLTRACE_RESUME_FRAME() \
91+
do { \
92+
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); \
93+
if (lltrace < 0) { \
94+
goto exit_unwind; \
95+
} \
96+
} while (0)
97+
#else
98+
#define LLTRACE_RESUME_FRAME() ((void)0)
99+
#endif
100+
89101
#ifdef Py_GIL_DISABLED
90102
#define QSBR_QUIESCENT_STATE(tstate) _Py_qsbr_quiescent_state(((_PyThreadStateImpl *)tstate)->qsbr)
91103
#else

Python/executor_cases.c.h

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

Python/generated_cases.c.h

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

Python/optimizer.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,8 @@ translate_bytecode_to_trace(
690690
// Reserve space for nuops (+ _SET_IP + _EXIT_TRACE)
691691
int nuops = expansion->nuops;
692692
RESERVE(nuops);
693-
if (expansion->uops[nuops-1].uop == _POP_FRAME) {
693+
int16_t last_op = expansion->uops[nuops-1].uop;
694+
if (last_op == _POP_FRAME || last_op == _RETURN_GENERATOR) {
694695
// Check for trace stack underflow now:
695696
// We can't bail e.g. in the middle of
696697
// LOAD_CONST + _POP_FRAME.
@@ -749,7 +750,7 @@ translate_bytecode_to_trace(
749750
Py_FatalError("garbled expansion");
750751
}
751752

752-
if (uop == _POP_FRAME) {
753+
if (uop == _POP_FRAME || uop == _RETURN_GENERATOR) {
753754
TRACE_STACK_POP();
754755
/* Set the operand to the function or code object returned to,
755756
* to assist optimization passes. (See _PUSH_FRAME below.)

Python/optimizer_analysis.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ eliminate_pop_guard(_PyUOpInstruction *this_instr, bool exit)
369369
static PyCodeObject *
370370
get_code(_PyUOpInstruction *op)
371371
{
372-
assert(op->opcode == _PUSH_FRAME || op->opcode == _POP_FRAME);
372+
assert(op->opcode == _PUSH_FRAME || op->opcode == _POP_FRAME || op->opcode == _RETURN_GENERATOR);
373373
PyCodeObject *co = NULL;
374374
uint64_t operand = op->operand;
375375
if (operand == 0) {

Python/optimizer_bytecodes.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,28 @@ dummy_func(void) {
651651
}
652652
}
653653

654+
op(_RETURN_GENERATOR, ( -- res)) {
655+
SYNC_SP();
656+
ctx->frame->stack_pointer = stack_pointer;
657+
frame_pop(ctx);
658+
stack_pointer = ctx->frame->stack_pointer;
659+
OUT_OF_SPACE_IF_NULL(res = sym_new_unknown(ctx));
660+
661+
/* Stack space handling */
662+
assert(corresponding_check_stack == NULL);
663+
assert(co != NULL);
664+
int framesize = co->co_framesize;
665+
assert(framesize > 0);
666+
assert(framesize <= curr_space);
667+
curr_space -= framesize;
668+
669+
co = get_code(this_instr);
670+
if (co == NULL) {
671+
// might be impossible, but bailing is still safe
672+
goto done;
673+
}
674+
}
675+
654676
op(_CHECK_STACK_SPACE, ( --)) {
655677
assert(corresponding_check_stack == NULL);
656678
corresponding_check_stack = this_instr;

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)