From 00525a08712055e1498c8535ed25419899b1b0fd Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sat, 30 Sep 2023 10:31:59 +0100 Subject: [PATCH] remove prev_instr and return_offset from frame --- Include/internal/pycore_frame.h | 39 ++++---------------------- Include/internal/pycore_runtime.h | 1 - Include/internal/pycore_runtime_init.h | 1 - Objects/frameobject.c | 7 ----- Objects/typeobject.c | 1 - Python/bytecodes.c | 36 ++++-------------------- Python/ceval.c | 10 +------ Python/ceval_macros.h | 13 +++------ Python/executor.c | 4 +-- Python/executor_cases.c.h | 7 +---- Python/frame.c | 3 -- Python/generated_cases.c.h | 32 --------------------- Python/optimizer.c | 2 +- Python/traceback.c | 11 +------- 14 files changed, 20 insertions(+), 147 deletions(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 291684b33a3e276..edf67db2e5cd52a 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -62,19 +62,15 @@ typedef struct _PyInterpreterFrame { // 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_instr; _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 */ - /* The return_offset determines where a `RETURN` should go in the caller, - * relative to `prev_instr`. - * It is only meaningful to the callee, - * so it needs to be set in any CALL (to a Python function) - * or SEND (to a coroutine or generator). - * If there is no callee, then it is meaningless. */ + /* The yield_offset determines where a `YIELD_VALUE` should go in the caller, + * relative to `instr_ptr`. + * It must be set by SEND, SEND_GEN, FOR_ITER_GEN and used by YIELD_VALUE. + */ uint16_t yield_offset; - uint16_t return_offset; /* The new_return_offset determines where a `RETURN` should go in the caller, * relative to `instr_ptr`. * It is only meaningful to the callee, @@ -90,40 +86,21 @@ typedef struct _PyInterpreterFrame { #define _PyInterpreterFrame_LASTI(IF) \ ((int)(((IF)->instr_ptr) - _PyCode_CODE(_PyFrame_GetCode(IF)))) -#define _OldPyInterpreterFrame_LASTI(IF) \ - ((int)((IF)->prev_instr - _PyCode_CODE(_PyFrame_GetCode(IF)))) - static inline PyCodeObject *_PyFrame_GetCode(_PyInterpreterFrame *f) { assert(PyCode_Check(f->f_executable)); return (PyCodeObject *)f->f_executable; } - static void dump_frame_ip(const char* title, _PyInterpreterFrame *frame) { if (frame) { - fprintf(stderr, "%s: frame=%p frame->prev_instr=%p frame->instr_ptr=%p ", - title, frame, frame->prev_instr, frame->instr_ptr); + fprintf(stderr, "%s: frame=%p frame->instr_ptr=%p ", + title, frame, frame->instr_ptr); fprintf(stderr, "new_return_offset=%d yield_offset=%d \n", frame->new_return_offset, frame->yield_offset); } } - -static void -check_lasti_values(_PyInterpreterFrame *f, bool raise, const char* filename, int line) { - int new_addr = _PyInterpreterFrame_LASTI(f) * sizeof(_Py_CODEUNIT); - int addr = _OldPyInterpreterFrame_LASTI(f) * sizeof(_Py_CODEUNIT); - int new = PyCode_Addr2Line(_PyFrame_GetCode(f), new_addr); - int old = PyCode_Addr2Line(_PyFrame_GetCode(f), addr); - - if (old != new) { - fprintf(stderr, "f=%p f->prev_instr=%p f->instr_ptr=%p old=%d new=%d\n", f, f->prev_instr, f->instr_ptr, old, new); - fprintf(stderr, "%s : %d\n", filename, line); - } - if (true || raise) assert(old == new); -} - static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { return f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus; } @@ -175,9 +152,7 @@ _PyFrame_Initialize( frame->stacktop = code->co_nlocalsplus; frame->frame_obj = NULL; frame->prev_traced_instr = NULL; - frame->prev_instr = _PyCode_CODE(code) - 1; frame->instr_ptr = _PyCode_CODE(code); - frame->return_offset = 0; frame->new_return_offset = 0; frame->yield_offset = 0; frame->owner = FRAME_OWNED_BY_THREAD; @@ -342,10 +317,8 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int frame->stacktop = code->co_nlocalsplus + stackdepth; frame->frame_obj = NULL; frame->prev_traced_instr = NULL; - frame->prev_instr = _PyCode_CODE(code) + previous_instr; frame->instr_ptr = _PyCode_CODE(code) + previous_instr + 1; frame->owner = FRAME_OWNED_BY_THREAD; - frame->return_offset = 0; frame->new_return_offset = 0; frame->yield_offset = 0; return frame; diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index a5bc285d9b3cc3b..a09dfe445953dd8 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -88,7 +88,6 @@ typedef struct _Py_DebugOffsets { struct _interpreter_frame { off_t previous; off_t executable; - off_t prev_instr; off_t instr_ptr; off_t localsplus; off_t owner; diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 85c9ef847c55998..1355b95912718c5 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -58,7 +58,6 @@ extern PyTypeObject _PyExc_MemoryError; .interpreter_frame = { \ .previous = offsetof(_PyInterpreterFrame, previous), \ .executable = offsetof(_PyInterpreterFrame, f_executable), \ - .prev_instr = offsetof(_PyInterpreterFrame, prev_instr), \ .instr_ptr = offsetof(_PyInterpreterFrame, instr_ptr), \ .localsplus = offsetof(_PyInterpreterFrame, localsplus), \ .owner = offsetof(_PyInterpreterFrame, owner), \ diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 9ec11952cc843f2..d061aeedaa8babd 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -64,7 +64,6 @@ frame_getlineno(PyFrameObject *f, void *closure) static PyObject * frame_getlasti(PyFrameObject *f, void *closure) { - check_lasti_values(f->f_frame, false, __FILE__, __LINE__); int lasti = _PyInterpreterFrame_LASTI(f->f_frame); if (lasti < 0) { return PyLong_FromLong(-1); @@ -739,7 +738,6 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore int64_t best_stack = OVERFLOWED; int best_addr = -1; - check_lasti_values(f->f_frame, false, __FILE__, __LINE__); int64_t start_stack = stacks[_PyInterpreterFrame_LASTI(f->f_frame)]; int err = -1; const char *msg = "cannot find bytecode for specified line"; @@ -821,7 +819,6 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore } /* Finally set the new lasti and return OK. */ f->f_lineno = 0; - f->f_frame->prev_instr = _PyCode_CODE(code) + best_addr; f->f_frame->instr_ptr = _PyCode_CODE(code) + best_addr; return 0; } @@ -1080,7 +1077,6 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; f->f_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; // This frame needs to be "complete", so pretend that the first RESUME ran: - f->f_frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; f->f_frame->instr_ptr = _PyCode_CODE(code) + code->_co_firsttraceable + 1; assert(!_PyFrame_IsIncomplete(f->f_frame)); Py_DECREF(func); @@ -1122,7 +1118,6 @@ frame_init_get_vars(_PyInterpreterFrame *frame) // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt // here: PyCodeObject *co = _PyFrame_GetCode(frame); - check_lasti_values(frame, false, __FILE__, __LINE__); int lasti = _PyInterpreterFrame_LASTI(frame); if (!(lasti < 0 && _PyCode_CODE(co)->op.code == COPY_FREE_VARS && PyFunction_Check(frame->f_funcobj))) @@ -1139,7 +1134,6 @@ frame_init_get_vars(_PyInterpreterFrame *frame) frame->localsplus[offset + i] = Py_NewRef(o); } // COPY_FREE_VARS doesn't have inline CACHEs, either: - frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)); frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)); } @@ -1514,7 +1508,6 @@ int PyFrame_GetLasti(PyFrameObject *frame) { assert(!_PyFrame_IsIncomplete(frame->f_frame)); - check_lasti_values(frame->f_frame, false, __FILE__, __LINE__); int lasti = _PyInterpreterFrame_LASTI(frame->f_frame); if (lasti < 0) { return -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index fd8008d339f55b2..893d8420bba4c4c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -10466,7 +10466,6 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, if (firstarg != NULL && (_PyLocals_GetKind(co->co_localspluskinds, 0) & CO_FAST_CELL)) { // "firstarg" is a cell here unless (very unlikely) super() // was called from the C-API before the first MAKE_CELL op. - check_lasti_values(cframe, false, __FILE__, __LINE__); if (_PyInterpreterFrame_LASTI(cframe) >= 0) { // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need // to use _PyOpcode_Deopt here: diff --git a/Python/bytecodes.c b/Python/bytecodes.c index bbea4cee98fbe6d..b4b1726607205fa 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -182,7 +182,6 @@ dummy_func( tstate, oparg > 0, frame, next_instr-1); stack_pointer = _PyFrame_GetStackPointer(frame); ERROR_IF(err, error); - assert(frame->prev_instr == frame->instr_ptr); if (frame->instr_ptr != next_instr-1) { /* Instrumentation has jumped */ next_instr = frame->instr_ptr; @@ -657,7 +656,6 @@ dummy_func( new_frame->localsplus[0] = container; new_frame->localsplus[1] = sub; SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -792,7 +790,6 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; @@ -810,7 +807,7 @@ dummy_func( macro(RETURN_VALUE) = _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr + _SAVE_CURRENT_IP + // Sets frame->instr_ptr _POP_FRAME; inst(INSTRUMENTED_RETURN_VALUE, (retval --)) { @@ -827,7 +824,6 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); @@ -837,7 +833,7 @@ dummy_func( macro(RETURN_CONST) = LOAD_CONST + _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr + _SAVE_CURRENT_IP + // Sets frame->instr_ptr _POP_FRAME; inst(INSTRUMENTED_RETURN_CONST, (--)) { @@ -855,7 +851,6 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); @@ -994,7 +989,6 @@ dummy_func( gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); - frame->return_offset = oparg; frame->yield_offset = next_instr - frame->instr_ptr; frame->new_return_offset = next_instr - frame->instr_ptr + oparg; DISPATCH_INLINED(gen_frame); @@ -1035,7 +1029,6 @@ dummy_func( gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); - frame->return_offset = oparg; frame->yield_offset = next_instr - frame->instr_ptr; frame->new_return_offset = next_instr - frame->instr_ptr + oparg; DISPATCH_INLINED(gen_frame); @@ -1075,14 +1068,12 @@ dummy_func( gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); _PyInterpreterFrame *gen_frame = frame; - gen_frame->prev_instr = next_instr - 1; gen_frame->instr_ptr = next_instr; 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->prev_instr = frame->instr_ptr - 1; goto resume_frame; } @@ -1096,7 +1087,6 @@ dummy_func( if (oparg) { PyObject *lasti = values[0]; if (PyLong_Check(lasti)) { - frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); assert(!_PyErr_Occurred(tstate)); frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); } @@ -2013,7 +2003,6 @@ dummy_func( STACK_SHRINK(1); new_frame->localsplus[0] = owner; SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); } @@ -2041,7 +2030,6 @@ dummy_func( new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); } @@ -2316,7 +2304,6 @@ dummy_func( _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; int original_oparg = executor->vm_data.oparg | (oparg & 0xfffff00); JUMPBY(1-original_oparg); - frame->prev_instr = next_instr - 1; frame->instr_ptr = next_instr; Py_INCREF(executor); frame = executor->execute(executor, frame, stack_pointer); @@ -2685,7 +2672,6 @@ dummy_func( SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); - frame->return_offset = oparg; frame->yield_offset = next_instr - frame->instr_ptr; frame->new_return_offset = oparg + next_instr - frame->instr_ptr; DISPATCH_INLINED(gen_frame); @@ -2995,7 +2981,6 @@ dummy_func( goto error; } SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); } @@ -3028,7 +3013,6 @@ dummy_func( } ERROR_IF(res == NULL, error); - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = 0; CHECK_EVAL_BREAKER(); @@ -3087,7 +3071,6 @@ dummy_func( op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- unused)) { // Write it out explicitly because it's subtly different. // Eventually this should be the only occurrence of this code. - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; assert(tstate->interp->eval_frame == NULL); @@ -3115,7 +3098,7 @@ dummy_func( _CHECK_STACK_SPACE + _INIT_CALL_PY_EXACT_ARGS + _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr + _SAVE_CURRENT_IP + // Sets frame->instr_ptr _PUSH_FRAME; macro(CALL_PY_EXACT_ARGS) = @@ -3125,7 +3108,7 @@ dummy_func( _CHECK_STACK_SPACE + _INIT_CALL_PY_EXACT_ARGS + _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr + _SAVE_CURRENT_IP + // Sets frame->instr_ptr _PUSH_FRAME; inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) { @@ -3159,7 +3142,6 @@ dummy_func( // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -3238,8 +3220,6 @@ dummy_func( init_frame->localsplus[i+1] = args[i]; } SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; STACK_SHRINK(oparg+2); @@ -3611,7 +3591,6 @@ dummy_func( if (new_frame == NULL) { goto error; } - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -3711,7 +3690,6 @@ dummy_func( if (new_frame == NULL) { goto error; } - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -3979,25 +3957,21 @@ dummy_func( } op(_SET_IP, (--)) { - frame->prev_instr = ip_offset + oparg; frame->instr_ptr = ip_offset + oparg; } op(_SAVE_CURRENT_IP, (--)) { #if TIER_ONE - frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; #endif #if TIER_TWO // Relies on a preceding _SET_IP - frame->prev_instr--; #endif } op(_EXIT_TRACE, (--)) { - frame->prev_instr--; // Back up to just before destination - frame->instr_ptr--; + frame->instr_ptr--; // Back up to just before destination _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(self); return frame; diff --git a/Python/ceval.c b/Python/ceval.c index 4b2083c40b86165..e29f750063fc0ef 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -690,11 +690,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int entry_frame.f_builtins = (PyObject*)0xaaa4; #endif entry_frame.f_executable = Py_None; - entry_frame.prev_instr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS; entry_frame.instr_ptr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1; entry_frame.stacktop = 0; entry_frame.owner = FRAME_OWNED_BY_CSTACK; - entry_frame.return_offset = 0; entry_frame.yield_offset = 0; entry_frame.new_return_offset = 0; /* Push frame */ @@ -717,7 +715,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Because this avoids the RESUME, * we need to update instrumentation */ _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - assert (frame->instr_ptr == frame->prev_instr + 1); monitor_throw(tstate, frame, frame->instr_ptr - 1); /* TO DO -- Monitor throw entry. */ goto resume_with_error; @@ -781,10 +778,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #include "generated_cases.c.h" - /* INSTRUMENTED_LINE has to be here, rather than in bytecodes.c, - * because it needs to capture frame->prev_instr before it is updated, - * as happens in the standard instruction prologue. - */ #if USE_COMPUTED_GOTOS TARGET_INSTRUMENTED_LINE: #else @@ -793,7 +786,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int { DUMP_FRAME("INSTRUMENTED_LINE"); _Py_CODEUNIT *prev = frame->prev_traced_instr; - _Py_CODEUNIT *here = frame->instr_ptr = frame->prev_instr = frame->prev_traced_instr = next_instr; + _Py_CODEUNIT *here = frame->instr_ptr = frame->prev_traced_instr = next_instr; _PyFrame_SetStackPointer(frame, stack_pointer); int original_opcode = _Py_call_instrumentation_line( tstate, frame, here, prev); @@ -908,7 +901,6 @@ if (VERBOSE) fprintf(stderr, "Exception Handler: %d\n", handler); Py_XDECREF(v); } if (lasti) { - check_lasti_values(frame, false, __FILE__, __LINE__); int frame_lasti = _PyInterpreterFrame_LASTI(frame); PyObject *lasti = PyLong_FromLong(frame_lasti); if (lasti == NULL) { diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index f14574812e08397..01fcf65d28e883b 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -62,8 +62,7 @@ #ifdef Py_STATS #define INSTRUCTION_START(op) \ do { \ - frame->instr_ptr = next_instr; \ - frame->prev_instr = next_instr++; \ + frame->instr_ptr = next_instr++; \ OPCODE_EXE_INC(op); \ if (_Py_stats) _Py_stats->opcode_stats[lastopcode].pair_count[op]++; \ lastopcode = op; \ @@ -71,10 +70,9 @@ #else #define INSTRUCTION_START(op) \ do { \ -if (VERBOSE) fprintf(stderr, "--- %s: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d yield_offset=%d\n", _PyOpcode_OpName[op], frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset, frame->yield_offset); \ - frame->instr_ptr = next_instr; \ - frame->prev_instr = next_instr++; \ -if (VERBOSE) fprintf(stderr, "=== %s: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d yield_offset=%d\n", _PyOpcode_OpName[op], frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset, frame->yield_offset); \ +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++; \ +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 @@ -114,7 +112,6 @@ if (VERBOSE) fprintf(stderr, "=== %s: frame=%p frame->prev_instr=%p frame->instr do { \ assert(tstate->interp->eval_frame == NULL); \ _PyFrame_SetStackPointer(frame, stack_pointer); \ - frame->prev_instr = next_instr - 1; \ (NEW_FRAME)->previous = frame; \ frame = tstate->current_frame = (NEW_FRAME); \ CALL_STAT_INC(inlined_py_calls); \ @@ -396,10 +393,8 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { #if TIER_ONE #define LOAD_IP() do { \ - assert(frame->prev_instr + 1 == frame->instr_ptr); \ frame->instr_ptr += frame->new_return_offset; \ frame->new_return_offset = 0; \ -if (VERBOSE) fprintf(stderr, "LOAD_IP: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); \ next_instr = frame->instr_ptr; \ } while (0) diff --git a/Python/executor.c b/Python/executor.c index 45f6982ae0075f8..c659da666b6f1bd 100644 --- a/Python/executor.c +++ b/Python/executor.c @@ -49,7 +49,6 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject #define DPRINTF(level, ...) #endif - assert(frame->prev_instr + 1 == frame->instr_ptr); DPRINTF(3, "Entering _PyUopExecute for %s (%s:%d) at byte offset %ld\n", PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_qualname), @@ -123,8 +122,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject // On DEOPT_IF we just repeat the last instruction. // This presumes nothing was popped from the stack (nor pushed). DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand); - frame->prev_instr--; // Back up to just before destination - frame->instr_ptr--; + frame->instr_ptr--; // Back up to just before destination _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(self); return frame; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 23e3fa533f0d416..53fe6675692dce6 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -692,7 +692,6 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; @@ -3105,27 +3104,23 @@ } case _SET_IP: { - frame->prev_instr = ip_offset + oparg; frame->instr_ptr = ip_offset + oparg; break; } case _SAVE_CURRENT_IP: { #if TIER_ONE - frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; #endif #if TIER_TWO // Relies on a preceding _SET_IP - frame->prev_instr--; #endif break; } case _EXIT_TRACE: { - frame->prev_instr--; // Back up to just before destination - frame->instr_ptr--; + frame->instr_ptr--; // Back up to just before destination _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(self); return frame; diff --git a/Python/frame.c b/Python/frame.c index 2909bacfc564234..2865b2eab603c27 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -90,7 +90,6 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) // This may be a newly-created generator or coroutine frame. Since it's // dead anyways, just pretend that the first RESUME ran: PyCodeObject *code = _PyFrame_GetCode(frame); - frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; frame->instr_ptr = _PyCode_CODE(code) + code->_co_firsttraceable + 1; } assert(!_PyFrame_IsIncomplete(frame)); @@ -158,14 +157,12 @@ PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame) int PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame) { - check_lasti_values(frame, false, __FILE__, __LINE__); return _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); } int PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame) { - check_lasti_values(frame, false, __FILE__, __LINE__); int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); return PyCode_Addr2Line(_PyFrame_GetCode(frame), addr); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 0a33bb1331b49d1..b8ca2bea3c1ecbd 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -58,7 +58,6 @@ tstate, oparg > 0, frame, next_instr-1); stack_pointer = _PyFrame_GetStackPointer(frame); if (err) goto error; - assert(frame->prev_instr == frame->instr_ptr); if (frame->instr_ptr != next_instr-1) { /* Instrumentation has jumped */ next_instr = frame->instr_ptr; @@ -802,7 +801,6 @@ new_frame->localsplus[0] = container; new_frame->localsplus[1] = sub; SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -990,13 +988,11 @@ // _SAVE_CURRENT_IP { #if TIER_ONE - frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; #endif #if TIER_TWO // Relies on a preceding _SET_IP - frame->prev_instr--; #endif } // _POP_FRAME @@ -1013,7 +1009,6 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; @@ -1047,7 +1042,6 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); @@ -1065,13 +1059,11 @@ // _SAVE_CURRENT_IP { #if TIER_ONE - frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; #endif #if TIER_TWO // Relies on a preceding _SET_IP - frame->prev_instr--; #endif } // _POP_FRAME @@ -1087,7 +1079,6 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; @@ -1120,7 +1111,6 @@ _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; frame->instr_ptr += frame->new_return_offset; frame->new_return_offset = 0; _PyFrame_StackPush(frame, retval); @@ -1278,7 +1268,6 @@ gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); - frame->return_offset = oparg; frame->yield_offset = next_instr - frame->instr_ptr; frame->new_return_offset = next_instr - frame->instr_ptr + oparg; DISPATCH_INLINED(gen_frame); @@ -1326,7 +1315,6 @@ gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); - frame->return_offset = oparg; frame->yield_offset = next_instr - frame->instr_ptr; frame->new_return_offset = next_instr - frame->instr_ptr + oparg; DISPATCH_INLINED(gen_frame); @@ -1370,14 +1358,12 @@ gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); _PyInterpreterFrame *gen_frame = frame; - gen_frame->prev_instr = next_instr - 1; gen_frame->instr_ptr = next_instr; 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->prev_instr = frame->instr_ptr - 1; goto resume_frame; } @@ -1399,7 +1385,6 @@ if (oparg) { PyObject *lasti = values[0]; if (PyLong_Check(lasti)) { - frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); assert(!_PyErr_Occurred(tstate)); frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); } @@ -2612,7 +2597,6 @@ STACK_SHRINK(1); new_frame->localsplus[0] = owner; SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); } @@ -2645,7 +2629,6 @@ new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); } @@ -3022,7 +3005,6 @@ _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; int original_oparg = executor->vm_data.oparg | (oparg & 0xfffff00); JUMPBY(1-original_oparg); - frame->prev_instr = next_instr - 1; frame->instr_ptr = next_instr; Py_INCREF(executor); frame = executor->execute(executor, frame, stack_pointer); @@ -3464,7 +3446,6 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); - frame->return_offset = oparg; frame->yield_offset = next_instr - frame->instr_ptr; frame->new_return_offset = oparg + next_instr - frame->instr_ptr; DISPATCH_INLINED(gen_frame); @@ -3832,7 +3813,6 @@ goto error; } SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); } @@ -3865,7 +3845,6 @@ } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = 0; STACK_SHRINK(oparg); @@ -3941,13 +3920,11 @@ next_instr += 3; { #if TIER_ONE - frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; #endif #if TIER_TWO // Relies on a preceding _SET_IP - frame->prev_instr--; #endif } // _PUSH_FRAME @@ -3956,7 +3933,6 @@ { // Write it out explicitly because it's subtly different. // Eventually this should be the only occurrence of this code. - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; assert(tstate->interp->eval_frame == NULL); @@ -4023,13 +3999,11 @@ next_instr += 3; { #if TIER_ONE - frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; #endif #if TIER_TWO // Relies on a preceding _SET_IP - frame->prev_instr--; #endif } // _PUSH_FRAME @@ -4038,7 +4012,6 @@ { // Write it out explicitly because it's subtly different. // Eventually this should be the only occurrence of this code. - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; assert(tstate->interp->eval_frame == NULL); @@ -4097,7 +4070,6 @@ // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -4218,8 +4190,6 @@ init_frame->localsplus[i+1] = args[i]; } SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; STACK_SHRINK(oparg+2); @@ -4730,7 +4700,6 @@ if (new_frame == NULL) { goto error; } - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); @@ -4842,7 +4811,6 @@ if (new_frame == NULL) { goto error; } - frame->return_offset = 0; frame->yield_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; DISPATCH_INLINED(new_frame); diff --git a/Python/optimizer.c b/Python/optimizer.c index fbdbf7291784c4b..6562fd967e25b0b 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -238,7 +238,7 @@ counter_execute(_PyExecutorObject *self, _PyInterpreterFrame *frame, PyObject ** { ((_PyCounterExecutorObject *)self)->optimizer->count++; _PyFrame_SetStackPointer(frame, stack_pointer); - frame->prev_instr = ((_PyCounterExecutorObject *)self)->next_instr - 1; + frame->instr_ptr = ((_PyCounterExecutorObject *)self)->next_instr; // ??? Py_DECREF(self); return frame; } diff --git a/Python/traceback.c b/Python/traceback.c index a229fd468543bf1..7e791d0a59bd828 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -234,16 +234,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) { assert(tb_next == NULL || PyTraceBack_Check(tb_next)); assert(frame != NULL); - int new_addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT); - int addr = _OldPyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT); - int newline = PyCode_Addr2Line(_PyFrame_GetCode(frame->f_frame), new_addr); - int line = PyCode_Addr2Line(_PyFrame_GetCode(frame->f_frame), addr); -if (true || line != newline) { - if (VERBOSE) fprintf(stderr, "frame=%p frame->prev_instr=%p frame->instr_ptr=%p frame->new_return_offset=%d frame->yield_offset=%d line=%d newline=%d %s\n", - frame->f_frame, frame->f_frame->prev_instr, frame->f_frame->instr_ptr, frame->f_frame->new_return_offset, frame->f_frame->yield_offset, line, newline, newline - line ? "XXX" : ""); - if (VERBOSE) fprintf(stderr, "_PyFrame_GetCode(frame->f_frame)=%p addr = %d new_addr = %d\n", _PyFrame_GetCode(frame->f_frame), addr, new_addr); -} - assert(line == newline); + int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT); return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, PyFrame_GetLineNumber(frame)); }