diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index edf67db2e5cd52..b235a590714fdb 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -58,11 +58,6 @@ typedef struct _PyInterpreterFrame { PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ - // NOTE: This is not necessarily the last instruction started in the given - // frame. Rather, it is the code unit *prior to* the *next* instruction. For - // example, it may be an inline CACHE entry, an instruction we just jumped - // over, or (in the case of a newly-created frame) a totally invalid value: - _Py_CODEUNIT *prev_traced_instr; /* The instruction that is currently executing (possibly not started yet). */ _Py_CODEUNIT *instr_ptr; int stacktop; /* Offset of TOS from localsplus */ @@ -151,7 +146,6 @@ _PyFrame_Initialize( frame->f_locals = locals; frame->stacktop = code->co_nlocalsplus; frame->frame_obj = NULL; - frame->prev_traced_instr = NULL; frame->instr_ptr = _PyCode_CODE(code); frame->new_return_offset = 0; frame->yield_offset = 0; @@ -316,7 +310,6 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int frame->f_locals = NULL; frame->stacktop = code->co_nlocalsplus + stackdepth; frame->frame_obj = NULL; - frame->prev_traced_instr = NULL; frame->instr_ptr = _PyCode_CODE(code) + previous_instr + 1; frame->owner = FRAME_OWNED_BY_THREAD; frame->new_return_offset = 0; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 146533afd2e117..6b377240e02e4c 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -790,11 +790,10 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); LOAD_SP(); LOAD_IP(); + frame->yield_offset = 0; #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -822,8 +821,7 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; + frame->yield_offset = 0; _PyFrame_StackPush(frame, retval); goto resume_frame; } @@ -849,8 +847,7 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; + frame->yield_offset = 0; _PyFrame_StackPush(frame, retval); goto resume_frame; } @@ -1050,6 +1047,8 @@ dummy_func( frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); + frame->new_return_offset = frame->yield_offset; + frame->yield_offset = 0; goto resume_frame; } @@ -1070,8 +1069,8 @@ dummy_func( frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); - frame->instr_ptr += frame->yield_offset; - frame->new_return_offset = frame->yield_offset = 0; + frame->new_return_offset = frame->yield_offset; + frame->yield_offset = 0; goto resume_frame; } @@ -3009,8 +3008,6 @@ dummy_func( Py_DECREF(args[i]); } ERROR_IF(res == NULL, error); - frame->yield_offset = 0; - frame->new_return_offset = 0; CHECK_EVAL_BREAKER(); } @@ -3760,8 +3757,7 @@ dummy_func( _PyInterpreterFrame *prev = frame->previous; _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; + frame->yield_offset = 0; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; } @@ -3958,8 +3954,12 @@ dummy_func( op(_SAVE_CURRENT_IP, (--)) { #if TIER_ONE - assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; + if (frame->new_return_offset == 0) { + frame->new_return_offset = next_instr - frame->instr_ptr; + } + else { + assert(next_instr == frame->instr_ptr); + } #endif #if TIER_TWO // Relies on a preceding _SET_IP diff --git a/Python/ceval.c b/Python/ceval.c index 447df38cd1975b..480e7d07cfde24 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -785,8 +785,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #endif { DUMP_FRAME("INSTRUMENTED_LINE"); - _Py_CODEUNIT *prev = frame->prev_traced_instr; - _Py_CODEUNIT *here = frame->instr_ptr = frame->prev_traced_instr = next_instr; + _Py_CODEUNIT *prev = frame->instr_ptr; + _Py_CODEUNIT *here = frame->instr_ptr = next_instr; _PyFrame_SetStackPointer(frame, stack_pointer); int original_opcode = _Py_call_instrumentation_line( tstate, frame, here, prev); diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 01fcf65d28e883..679e554570dec6 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -72,6 +72,8 @@ do { \ if (VERBOSE) fprintf(stderr, "--- %s: frame=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d yield_offset=%d\n", _PyOpcode_OpName[op], frame, frame->instr_ptr, next_instr, frame->new_return_offset, frame->yield_offset); \ frame->instr_ptr = next_instr++; \ + frame->new_return_offset = 0; \ + assert(frame->yield_offset == 0); \ if (VERBOSE) fprintf(stderr, "=== %s: frame=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d yield_offset=%d\n", _PyOpcode_OpName[op], frame, frame->instr_ptr, next_instr, frame->new_return_offset, frame->yield_offset); \ } while(0) #endif @@ -352,6 +354,7 @@ do { \ do { \ _PyFrame_SetStackPointer(frame, stack_pointer); \ next_instr = _Py_call_instrumentation_jump(tstate, event, frame, src, dest); \ + frame->new_return_offset = frame->yield_offset = 0; \ stack_pointer = _PyFrame_GetStackPointer(frame); \ if (next_instr == NULL) { \ next_instr = (dest)+1; \ @@ -393,9 +396,7 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { #if TIER_ONE #define LOAD_IP() do { \ - frame->instr_ptr += frame->new_return_offset; \ - frame->new_return_offset = 0; \ - next_instr = frame->instr_ptr; \ + next_instr = frame->instr_ptr + frame->new_return_offset; \ } while (0) #define STORE_SP() \ diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index e6d9fac0803873..ef8c8cbe8aeb6c 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -692,11 +692,10 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); LOAD_SP(); LOAD_IP(); + frame->yield_offset = 0; #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -3108,8 +3107,12 @@ case _SAVE_CURRENT_IP: { #if TIER_ONE - assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; + if (frame->new_return_offset == 0) { + frame->new_return_offset = next_instr - frame->instr_ptr; + } + else { + assert(next_instr == frame->instr_ptr); + } #endif #if TIER_TWO // Relies on a preceding _SET_IP diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 8a131d2efe55dd..b2e300e1a33623 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -988,8 +988,12 @@ // _SAVE_CURRENT_IP { #if TIER_ONE - assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; + if (frame->new_return_offset == 0) { + frame->new_return_offset = next_instr - frame->instr_ptr; + } + else { + assert(next_instr == frame->instr_ptr); + } #endif #if TIER_TWO // Relies on a preceding _SET_IP @@ -1009,11 +1013,10 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); LOAD_SP(); LOAD_IP(); + frame->yield_offset = 0; #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -1040,8 +1043,7 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; + frame->yield_offset = 0; _PyFrame_StackPush(frame, retval); goto resume_frame; } @@ -1057,8 +1059,12 @@ // _SAVE_CURRENT_IP { #if TIER_ONE - assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; + if (frame->new_return_offset == 0) { + frame->new_return_offset = next_instr - frame->instr_ptr; + } + else { + assert(next_instr == frame->instr_ptr); + } #endif #if TIER_TWO // Relies on a preceding _SET_IP @@ -1077,11 +1083,10 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); LOAD_SP(); LOAD_IP(); + frame->yield_offset = 0; #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -1107,8 +1112,7 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; + frame->yield_offset = 0; _PyFrame_StackPush(frame, retval); goto resume_frame; } @@ -1336,6 +1340,8 @@ frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); + frame->new_return_offset = frame->yield_offset; + frame->yield_offset = 0; goto resume_frame; } @@ -1358,8 +1364,8 @@ frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); - frame->instr_ptr += frame->yield_offset; - frame->new_return_offset = frame->yield_offset = 0; + frame->new_return_offset = frame->yield_offset; + frame->yield_offset = 0; goto resume_frame; } @@ -3839,8 +3845,6 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - frame->yield_offset = 0; - frame->new_return_offset = 0; STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3914,8 +3918,12 @@ next_instr += 3; { #if TIER_ONE - assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; + if (frame->new_return_offset == 0) { + frame->new_return_offset = next_instr - frame->instr_ptr; + } + else { + assert(next_instr == frame->instr_ptr); + } #endif #if TIER_TWO // Relies on a preceding _SET_IP @@ -3993,8 +4001,12 @@ next_instr += 3; { #if TIER_ONE - assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; + if (frame->new_return_offset == 0) { + frame->new_return_offset = next_instr - frame->instr_ptr; + } + else { + assert(next_instr == frame->instr_ptr); + } #endif #if TIER_TWO // Relies on a preceding _SET_IP @@ -4897,8 +4909,7 @@ _PyInterpreterFrame *prev = frame->previous; _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; + frame->yield_offset = 0; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; }