Skip to content

Commit

Permalink
remove prev_instr and return_offset from frame
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel committed Sep 30, 2023
1 parent c9a9601 commit 00525a0
Show file tree
Hide file tree
Showing 14 changed files with 20 additions and 147 deletions.
39 changes: 6 additions & 33 deletions Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -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), \
Expand Down
7 changes: 0 additions & 7 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)))
Expand All @@ -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));
}

Expand Down Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
36 changes: 5 additions & 31 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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 --)) {
Expand All @@ -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);
Expand All @@ -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, (--)) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) =
Expand All @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 00525a0

Please sign in to comment.