mirror of
https://github.com/python/cpython.git
synced 2025-08-30 13:38:43 +00:00
gh-109094: replace frame->prev_instr by frame->instr_ptr (#109095)
This commit is contained in:
parent
573eff3e2e
commit
67a91f78e4
23 changed files with 249 additions and 164 deletions
4
Python/abstract_interp_cases.c.h
generated
4
Python/abstract_interp_cases.c.h
generated
|
@ -920,6 +920,10 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _SAVE_RETURN_OFFSET: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _EXIT_TRACE: {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -183,9 +183,9 @@ dummy_func(
|
|||
tstate, oparg > 0, frame, next_instr-1);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
ERROR_IF(err, error);
|
||||
if (frame->prev_instr != next_instr-1) {
|
||||
if (frame->instr_ptr != next_instr-1) {
|
||||
/* Instrumentation has jumped */
|
||||
next_instr = frame->prev_instr;
|
||||
next_instr = frame->instr_ptr;
|
||||
DISPATCH();
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +657,8 @@ dummy_func(
|
|||
new_frame->localsplus[0] = container;
|
||||
new_frame->localsplus[1] = sub;
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -790,10 +791,9 @@ dummy_func(
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(frame->return_offset);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -819,8 +819,8 @@ dummy_func(
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_IP(frame->return_offset);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -843,8 +843,8 @@ dummy_func(
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_IP(frame->return_offset);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -980,7 +980,8 @@ 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
|
||||
DISPATCH_INLINED(gen_frame);
|
||||
}
|
||||
if (Py_IsNone(v) && PyIter_Check(receiver)) {
|
||||
|
@ -1018,13 +1019,15 @@ 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
|
||||
DISPATCH_INLINED(gen_frame);
|
||||
}
|
||||
|
||||
inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) {
|
||||
assert(frame != &entry_frame);
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
gen->gi_frame_state = FRAME_SUSPENDED;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
|
||||
|
@ -1039,6 +1042,9 @@ dummy_func(
|
|||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
/* We don't know which of these is relevant here, so keep them equal */
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -1048,6 +1054,7 @@ dummy_func(
|
|||
// or throw() call.
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
assert(frame != &entry_frame);
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
gen->gi_frame_state = FRAME_SUSPENDED;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
|
||||
|
@ -1058,6 +1065,9 @@ dummy_func(
|
|||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
/* We don't know which of these is relevant here, so keep them equal */
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -1071,7 +1081,7 @@ dummy_func(
|
|||
if (oparg) {
|
||||
PyObject *lasti = values[0];
|
||||
if (PyLong_Check(lasti)) {
|
||||
frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti);
|
||||
frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti);
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
}
|
||||
else {
|
||||
|
@ -2009,7 +2019,8 @@ dummy_func(
|
|||
STACK_SHRINK(1);
|
||||
new_frame->localsplus[0] = owner;
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -2036,7 +2047,8 @@ 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -2304,13 +2316,14 @@ 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);
|
||||
if (frame == NULL) {
|
||||
frame = tstate->current_frame;
|
||||
goto resume_with_error;
|
||||
}
|
||||
next_instr = frame->instr_ptr;
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -2476,7 +2489,7 @@ dummy_func(
|
|||
}
|
||||
|
||||
inst(INSTRUMENTED_FOR_ITER, ( -- )) {
|
||||
_Py_CODEUNIT *here = next_instr-1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
_Py_CODEUNIT *target;
|
||||
PyObject *iter = TOP();
|
||||
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
|
||||
|
@ -2672,7 +2685,8 @@ 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_FOR_ITER == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg;
|
||||
DISPATCH_INLINED(gen_frame);
|
||||
}
|
||||
|
||||
|
@ -2983,7 +2997,8 @@ dummy_func(
|
|||
goto error;
|
||||
}
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
|
@ -3070,7 +3085,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;
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
STORE_SP();
|
||||
new_frame->previous = frame;
|
||||
|
@ -3078,7 +3092,7 @@ dummy_func(
|
|||
frame = tstate->current_frame = new_frame;
|
||||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(0);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -3095,7 +3109,7 @@ dummy_func(
|
|||
_CHECK_FUNCTION_EXACT_ARGS +
|
||||
_CHECK_STACK_SPACE +
|
||||
_INIT_CALL_PY_EXACT_ARGS +
|
||||
_SAVE_CURRENT_IP + // Sets frame->prev_instr
|
||||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
||||
macro(CALL_PY_EXACT_ARGS) =
|
||||
|
@ -3104,7 +3118,7 @@ dummy_func(
|
|||
_CHECK_FUNCTION_EXACT_ARGS +
|
||||
_CHECK_STACK_SPACE +
|
||||
_INIT_CALL_PY_EXACT_ARGS +
|
||||
_SAVE_CURRENT_IP + // Sets frame->prev_instr
|
||||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
||||
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) {
|
||||
|
@ -3138,7 +3152,8 @@ 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -3203,7 +3218,7 @@ dummy_func(
|
|||
Py_DECREF(tp);
|
||||
_PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked(
|
||||
tstate, (PyCodeObject *)&_Py_InitCleanup, 1);
|
||||
assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK);
|
||||
assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[0].op.code == EXIT_INIT_CHECK);
|
||||
/* Push self onto stack of shim */
|
||||
Py_INCREF(self);
|
||||
shim->localsplus[0] = self;
|
||||
|
@ -3215,8 +3230,8 @@ 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||
STACK_SHRINK(oparg+2);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
/* Link frames */
|
||||
|
@ -3585,7 +3600,8 @@ dummy_func(
|
|||
if (new_frame == NULL) {
|
||||
goto error;
|
||||
}
|
||||
frame->return_offset = 0;
|
||||
assert(next_instr - frame->instr_ptr == 1);
|
||||
frame->return_offset = 1;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
|
@ -3681,7 +3697,8 @@ dummy_func(
|
|||
if (new_frame == NULL) {
|
||||
goto error;
|
||||
}
|
||||
frame->return_offset = 0;
|
||||
assert(next_instr - frame->instr_ptr == 1);
|
||||
frame->return_offset = 1;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
result = PyObject_Call(func, callargs, kwargs);
|
||||
|
@ -3744,6 +3761,7 @@ dummy_func(
|
|||
assert(EMPTY());
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
|
||||
frame->instr_ptr = next_instr;
|
||||
_PyFrame_Copy(frame, gen_frame);
|
||||
assert(frame->frame_obj == NULL);
|
||||
gen->gi_frame_state = FRAME_CREATED;
|
||||
|
@ -3754,6 +3772,7 @@ dummy_func(
|
|||
_PyThreadState_PopFrame(tstate, frame);
|
||||
frame = tstate->current_frame = prev;
|
||||
_PyFrame_StackPush(frame, (PyObject *)gen);
|
||||
LOAD_IP(frame->return_offset);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -3836,18 +3855,20 @@ dummy_func(
|
|||
}
|
||||
|
||||
inst(INSTRUMENTED_JUMP_FORWARD, ( -- )) {
|
||||
INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP);
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
INSTRUMENTED_JUMP(here, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
|
||||
}
|
||||
|
||||
inst(INSTRUMENTED_JUMP_BACKWARD, ( -- )) {
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
CHECK_EVAL_BREAKER();
|
||||
INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP);
|
||||
INSTRUMENTED_JUMP(here, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
|
||||
}
|
||||
|
||||
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
|
||||
PyObject *cond = POP();
|
||||
assert(PyBool_Check(cond));
|
||||
_Py_CODEUNIT *here = next_instr - 1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int flag = Py_IsTrue(cond);
|
||||
int offset = flag * oparg;
|
||||
#if ENABLE_SPECIALIZATION
|
||||
|
@ -3859,7 +3880,7 @@ dummy_func(
|
|||
inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
|
||||
PyObject *cond = POP();
|
||||
assert(PyBool_Check(cond));
|
||||
_Py_CODEUNIT *here = next_instr - 1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int flag = Py_IsFalse(cond);
|
||||
int offset = flag * oparg;
|
||||
#if ENABLE_SPECIALIZATION
|
||||
|
@ -3870,7 +3891,7 @@ dummy_func(
|
|||
|
||||
inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) {
|
||||
PyObject *value = POP();
|
||||
_Py_CODEUNIT *here = next_instr - 1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int flag = Py_IsNone(value);
|
||||
int offset;
|
||||
if (flag) {
|
||||
|
@ -3888,7 +3909,7 @@ dummy_func(
|
|||
|
||||
inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) {
|
||||
PyObject *value = POP();
|
||||
_Py_CODEUNIT *here = next_instr-1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int offset;
|
||||
int nflag = Py_IsNone(value);
|
||||
if (nflag) {
|
||||
|
@ -3943,16 +3964,20 @@ dummy_func(
|
|||
|
||||
op(_SET_IP, (--)) {
|
||||
TIER_TWO_ONLY
|
||||
frame->prev_instr = ip_offset + oparg;
|
||||
frame->instr_ptr = ip_offset + oparg;
|
||||
}
|
||||
|
||||
op(_SAVE_CURRENT_IP, (--)) {
|
||||
TIER_ONE_ONLY
|
||||
frame->prev_instr = next_instr - 1;
|
||||
op(_SAVE_RETURN_OFFSET, (--)) {
|
||||
#if TIER_ONE
|
||||
frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
frame->return_offset = oparg;
|
||||
#endif
|
||||
}
|
||||
|
||||
op(_EXIT_TRACE, (--)) {
|
||||
frame->prev_instr--; // Back up to just before destination
|
||||
TIER_TWO_ONLY
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
||||
|
|
|
@ -640,7 +640,9 @@ static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = {
|
|||
/* Put a NOP at the start, so that the IP points into
|
||||
* the code, rather than before it */
|
||||
{ .op.code = NOP, .op.arg = 0 },
|
||||
{ .op.code = INTERPRETER_EXIT, .op.arg = 0 },
|
||||
{ .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on return */
|
||||
{ .op.code = NOP, .op.arg = 0 },
|
||||
{ .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on yield */
|
||||
{ .op.code = RESUME, .op.arg = 0 }
|
||||
};
|
||||
|
||||
|
@ -698,7 +700,7 @@ _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;
|
||||
|
@ -722,7 +724,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
/* Because this avoids the RESUME,
|
||||
* we need to update instrumentation */
|
||||
_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
||||
monitor_throw(tstate, frame, frame->prev_instr);
|
||||
monitor_throw(tstate, frame, frame->instr_ptr);
|
||||
/* TO DO -- Monitor throw entry. */
|
||||
goto resume_with_error;
|
||||
}
|
||||
|
@ -733,19 +735,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
_Py_CODEUNIT *next_instr;
|
||||
PyObject **stack_pointer;
|
||||
|
||||
/* Sets the above local variables from the frame */
|
||||
#define SET_LOCALS_FROM_FRAME() \
|
||||
/* Jump back to the last instruction executed... */ \
|
||||
next_instr = frame->prev_instr + 1; \
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
|
||||
start_frame:
|
||||
if (_Py_EnterRecursivePy(tstate)) {
|
||||
goto exit_unwind;
|
||||
}
|
||||
|
||||
next_instr = frame->instr_ptr;
|
||||
resume_frame:
|
||||
SET_LOCALS_FROM_FRAME();
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
|
||||
#ifdef LLTRACE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
|
@ -774,7 +772,7 @@ resume_frame:
|
|||
#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,
|
||||
* because it needs to capture frame->instr_ptr before it is updated,
|
||||
* as happens in the standard instruction prologue.
|
||||
*/
|
||||
#if USE_COMPUTED_GOTOS
|
||||
|
@ -783,8 +781,8 @@ resume_frame:
|
|||
case INSTRUMENTED_LINE:
|
||||
#endif
|
||||
{
|
||||
_Py_CODEUNIT *prev = frame->prev_instr;
|
||||
_Py_CODEUNIT *here = frame->prev_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);
|
||||
|
@ -793,7 +791,7 @@ resume_frame:
|
|||
next_instr = here+1;
|
||||
goto error;
|
||||
}
|
||||
next_instr = frame->prev_instr;
|
||||
next_instr = frame->instr_ptr;
|
||||
if (next_instr != here) {
|
||||
DISPATCH();
|
||||
}
|
||||
|
@ -908,7 +906,8 @@ exception_unwind:
|
|||
Python main loop. */
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
PUSH(exc);
|
||||
JUMPTO(handler);
|
||||
next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + handler;
|
||||
|
||||
if (monitor_handled(tstate, frame, next_instr, exc) < 0) {
|
||||
goto exception_unwind;
|
||||
}
|
||||
|
@ -939,7 +938,8 @@ exit_unwind:
|
|||
}
|
||||
|
||||
resume_with_error:
|
||||
SET_LOCALS_FROM_FRAME();
|
||||
next_instr = frame->instr_ptr;
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
|
|
@ -62,13 +62,16 @@
|
|||
#ifdef Py_STATS
|
||||
#define INSTRUCTION_START(op) \
|
||||
do { \
|
||||
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; \
|
||||
} while (0)
|
||||
#else
|
||||
#define INSTRUCTION_START(op) (frame->prev_instr = next_instr++)
|
||||
#define INSTRUCTION_START(op) \
|
||||
do { \
|
||||
frame->instr_ptr = next_instr++; \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if USE_COMPUTED_GOTOS
|
||||
|
@ -107,7 +110,6 @@
|
|||
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); \
|
||||
|
@ -146,7 +148,6 @@ GETITEM(PyObject *v, Py_ssize_t i) {
|
|||
opcode = word.op.code; \
|
||||
oparg = word.op.arg; \
|
||||
} while (0)
|
||||
#define JUMPTO(x) (next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + (x))
|
||||
|
||||
/* JUMPBY makes the generator identify the instruction as a jump. SKIP_OVER is
|
||||
* for advancing to the next instruction, taking into account cache entries
|
||||
|
@ -381,8 +382,9 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) {
|
|||
|
||||
#if TIER_ONE
|
||||
|
||||
#define LOAD_IP() \
|
||||
do { next_instr = frame->prev_instr+1; } while (0)
|
||||
#define LOAD_IP(OFFSET) do { \
|
||||
next_instr = frame->instr_ptr + (OFFSET); \
|
||||
} while (0)
|
||||
|
||||
#define STORE_SP() \
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer)
|
||||
|
@ -395,7 +397,7 @@ stack_pointer = _PyFrame_GetStackPointer(frame);
|
|||
|
||||
#if TIER_TWO
|
||||
|
||||
#define LOAD_IP() \
|
||||
#define LOAD_IP(UNUSED) \
|
||||
do { ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; } while (0)
|
||||
|
||||
#define STORE_SP() \
|
||||
|
|
|
@ -62,7 +62,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
|
|||
PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_qualname),
|
||||
PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_filename),
|
||||
_PyFrame_GetCode(frame)->co_firstlineno,
|
||||
2 * (long)(frame->prev_instr + 1 -
|
||||
2 * (long)(frame->instr_ptr -
|
||||
(_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive));
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
@ -131,6 +131,7 @@ error:
|
|||
// The caller recovers the frame from tstate->current_frame.
|
||||
DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
|
||||
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
||||
frame->return_offset = 0; // Don't leave this random
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
|
@ -140,7 +141,7 @@ deoptimize:
|
|||
// This presumes nothing was popped from the stack (nor pushed).
|
||||
DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
|
||||
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
||||
frame->prev_instr--; // Back up to just before destination
|
||||
frame->return_offset = 0; // Dispatch to frame->instr_ptr
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
return frame;
|
||||
|
|
20
Python/executor_cases.c.h
generated
20
Python/executor_cases.c.h
generated
|
@ -692,10 +692,9 @@
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(frame->return_offset);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -2587,7 +2586,6 @@
|
|||
STACK_SHRINK(1);
|
||||
// Write it out explicitly because it's subtly different.
|
||||
// Eventually this should be the only occurrence of this code.
|
||||
frame->return_offset = 0;
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
STORE_SP();
|
||||
new_frame->previous = frame;
|
||||
|
@ -2595,7 +2593,7 @@
|
|||
frame = tstate->current_frame = new_frame;
|
||||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(0);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -3271,12 +3269,22 @@
|
|||
|
||||
case _SET_IP: {
|
||||
TIER_TWO_ONLY
|
||||
frame->prev_instr = ip_offset + oparg;
|
||||
frame->instr_ptr = ip_offset + oparg;
|
||||
break;
|
||||
}
|
||||
|
||||
case _SAVE_RETURN_OFFSET: {
|
||||
#if TIER_ONE
|
||||
frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
frame->return_offset = oparg;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case _EXIT_TRACE: {
|
||||
frame->prev_instr--; // Back up to just before destination
|
||||
TIER_TWO_ONLY
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
||||
|
|
|
@ -90,7 +90,7 @@ 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));
|
||||
assert(f->f_back == NULL);
|
||||
|
|
107
Python/generated_cases.c.h
generated
107
Python/generated_cases.c.h
generated
|
@ -61,9 +61,9 @@
|
|||
tstate, oparg > 0, frame, next_instr-1);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (err) goto error;
|
||||
if (frame->prev_instr != next_instr-1) {
|
||||
if (frame->instr_ptr != next_instr-1) {
|
||||
/* Instrumentation has jumped */
|
||||
next_instr = frame->prev_instr;
|
||||
next_instr = frame->instr_ptr;
|
||||
DISPATCH();
|
||||
}
|
||||
}
|
||||
|
@ -804,7 +804,8 @@
|
|||
new_frame->localsplus[0] = container;
|
||||
new_frame->localsplus[1] = sub;
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -999,10 +1000,9 @@
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(frame->return_offset);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -1028,8 +1028,8 @@
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_IP(frame->return_offset);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -1054,10 +1054,9 @@
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(frame->return_offset);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -1083,8 +1082,8 @@
|
|||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
frame->prev_instr += frame->return_offset;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
LOAD_IP(frame->return_offset);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1238,8 @@
|
|||
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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
|
||||
DISPATCH_INLINED(gen_frame);
|
||||
}
|
||||
if (Py_IsNone(v) && PyIter_Check(receiver)) {
|
||||
|
@ -1284,7 +1284,8 @@
|
|||
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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
|
||||
DISPATCH_INLINED(gen_frame);
|
||||
}
|
||||
|
||||
|
@ -1293,6 +1294,7 @@
|
|||
retval = stack_pointer[-1];
|
||||
assert(frame != &entry_frame);
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
gen->gi_frame_state = FRAME_SUSPENDED;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
|
||||
|
@ -1307,6 +1309,9 @@
|
|||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
/* We don't know which of these is relevant here, so keep them equal */
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -1318,6 +1323,7 @@
|
|||
// or throw() call.
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
assert(frame != &entry_frame);
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
gen->gi_frame_state = FRAME_SUSPENDED;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
|
||||
|
@ -1328,6 +1334,9 @@
|
|||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
_PyFrame_StackPush(frame, retval);
|
||||
/* We don't know which of these is relevant here, so keep them equal */
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -1349,7 +1358,7 @@
|
|||
if (oparg) {
|
||||
PyObject *lasti = values[0];
|
||||
if (PyLong_Check(lasti)) {
|
||||
frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti);
|
||||
frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti);
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
}
|
||||
else {
|
||||
|
@ -2578,7 +2587,8 @@
|
|||
STACK_SHRINK(1);
|
||||
new_frame->localsplus[0] = owner;
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -2610,7 +2620,8 @@
|
|||
new_frame->localsplus[0] = owner;
|
||||
new_frame->localsplus[1] = Py_NewRef(name);
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -2986,13 +2997,14 @@
|
|||
_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);
|
||||
if (frame == NULL) {
|
||||
frame = tstate->current_frame;
|
||||
goto resume_with_error;
|
||||
}
|
||||
next_instr = frame->instr_ptr;
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -3259,7 +3271,7 @@
|
|||
}
|
||||
|
||||
TARGET(INSTRUMENTED_FOR_ITER) {
|
||||
_Py_CODEUNIT *here = next_instr-1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
_Py_CODEUNIT *target;
|
||||
PyObject *iter = TOP();
|
||||
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
|
||||
|
@ -3427,7 +3439,8 @@
|
|||
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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_FOR_ITER == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg;
|
||||
DISPATCH_INLINED(gen_frame);
|
||||
}
|
||||
|
||||
|
@ -3815,7 +3828,8 @@
|
|||
goto error;
|
||||
}
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
|
@ -3915,11 +3929,15 @@
|
|||
new_frame->localsplus[i] = args[i];
|
||||
}
|
||||
}
|
||||
// _SAVE_CURRENT_IP
|
||||
// _SAVE_RETURN_OFFSET
|
||||
next_instr += 3;
|
||||
{
|
||||
TIER_ONE_ONLY
|
||||
frame->prev_instr = next_instr - 1;
|
||||
#if TIER_ONE
|
||||
frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
frame->return_offset = oparg;
|
||||
#endif
|
||||
}
|
||||
// _PUSH_FRAME
|
||||
STACK_SHRINK(oparg);
|
||||
|
@ -3927,7 +3945,6 @@
|
|||
{
|
||||
// Write it out explicitly because it's subtly different.
|
||||
// Eventually this should be the only occurrence of this code.
|
||||
frame->return_offset = 0;
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
STORE_SP();
|
||||
new_frame->previous = frame;
|
||||
|
@ -3935,7 +3952,7 @@
|
|||
frame = tstate->current_frame = new_frame;
|
||||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(0);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -3988,11 +4005,15 @@
|
|||
new_frame->localsplus[i] = args[i];
|
||||
}
|
||||
}
|
||||
// _SAVE_CURRENT_IP
|
||||
// _SAVE_RETURN_OFFSET
|
||||
next_instr += 3;
|
||||
{
|
||||
TIER_ONE_ONLY
|
||||
frame->prev_instr = next_instr - 1;
|
||||
#if TIER_ONE
|
||||
frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
frame->return_offset = oparg;
|
||||
#endif
|
||||
}
|
||||
// _PUSH_FRAME
|
||||
STACK_SHRINK(oparg);
|
||||
|
@ -4000,7 +4021,6 @@
|
|||
{
|
||||
// Write it out explicitly because it's subtly different.
|
||||
// Eventually this should be the only occurrence of this code.
|
||||
frame->return_offset = 0;
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
STORE_SP();
|
||||
new_frame->previous = frame;
|
||||
|
@ -4008,7 +4028,7 @@
|
|||
frame = tstate->current_frame = new_frame;
|
||||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP();
|
||||
LOAD_IP(0);
|
||||
#if LLTRACE && TIER_ONE
|
||||
lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS());
|
||||
if (lltrace < 0) {
|
||||
|
@ -4057,7 +4077,8 @@
|
|||
// 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;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
|
@ -4164,7 +4185,7 @@
|
|||
Py_DECREF(tp);
|
||||
_PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked(
|
||||
tstate, (PyCodeObject *)&_Py_InitCleanup, 1);
|
||||
assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK);
|
||||
assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[0].op.code == EXIT_INIT_CHECK);
|
||||
/* Push self onto stack of shim */
|
||||
Py_INCREF(self);
|
||||
shim->localsplus[0] = self;
|
||||
|
@ -4176,8 +4197,8 @@
|
|||
init_frame->localsplus[i+1] = args[i];
|
||||
}
|
||||
SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
|
||||
frame->prev_instr = next_instr - 1;
|
||||
frame->return_offset = 0;
|
||||
assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
|
||||
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
|
||||
STACK_SHRINK(oparg+2);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
/* Link frames */
|
||||
|
@ -4685,7 +4706,8 @@
|
|||
if (new_frame == NULL) {
|
||||
goto error;
|
||||
}
|
||||
frame->return_offset = 0;
|
||||
assert(next_instr - frame->instr_ptr == 1);
|
||||
frame->return_offset = 1;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
|
@ -4793,7 +4815,8 @@
|
|||
if (new_frame == NULL) {
|
||||
goto error;
|
||||
}
|
||||
frame->return_offset = 0;
|
||||
assert(next_instr - frame->instr_ptr == 1);
|
||||
frame->return_offset = 1;
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
result = PyObject_Call(func, callargs, kwargs);
|
||||
|
@ -4874,6 +4897,7 @@
|
|||
assert(EMPTY());
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
|
||||
frame->instr_ptr = next_instr;
|
||||
_PyFrame_Copy(frame, gen_frame);
|
||||
assert(frame->frame_obj == NULL);
|
||||
gen->gi_frame_state = FRAME_CREATED;
|
||||
|
@ -4884,6 +4908,7 @@
|
|||
_PyThreadState_PopFrame(tstate, frame);
|
||||
frame = tstate->current_frame = prev;
|
||||
_PyFrame_StackPush(frame, (PyObject *)gen);
|
||||
LOAD_IP(frame->return_offset);
|
||||
goto resume_frame;
|
||||
}
|
||||
|
||||
|
@ -5021,20 +5046,22 @@
|
|||
}
|
||||
|
||||
TARGET(INSTRUMENTED_JUMP_FORWARD) {
|
||||
INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP);
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
INSTRUMENTED_JUMP(here, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(INSTRUMENTED_JUMP_BACKWARD) {
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
CHECK_EVAL_BREAKER();
|
||||
INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP);
|
||||
INSTRUMENTED_JUMP(here, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) {
|
||||
PyObject *cond = POP();
|
||||
assert(PyBool_Check(cond));
|
||||
_Py_CODEUNIT *here = next_instr - 1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int flag = Py_IsTrue(cond);
|
||||
int offset = flag * oparg;
|
||||
#if ENABLE_SPECIALIZATION
|
||||
|
@ -5048,7 +5075,7 @@
|
|||
TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) {
|
||||
PyObject *cond = POP();
|
||||
assert(PyBool_Check(cond));
|
||||
_Py_CODEUNIT *here = next_instr - 1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int flag = Py_IsFalse(cond);
|
||||
int offset = flag * oparg;
|
||||
#if ENABLE_SPECIALIZATION
|
||||
|
@ -5061,7 +5088,7 @@
|
|||
|
||||
TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) {
|
||||
PyObject *value = POP();
|
||||
_Py_CODEUNIT *here = next_instr - 1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int flag = Py_IsNone(value);
|
||||
int offset;
|
||||
if (flag) {
|
||||
|
@ -5081,7 +5108,7 @@
|
|||
|
||||
TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) {
|
||||
PyObject *value = POP();
|
||||
_Py_CODEUNIT *here = next_instr-1;
|
||||
_Py_CODEUNIT *here = frame->instr_ptr;
|
||||
int offset;
|
||||
int nflag = Py_IsNone(value);
|
||||
if (nflag) {
|
||||
|
|
|
@ -1073,7 +1073,7 @@ _Py_call_instrumentation_jump(
|
|||
{
|
||||
assert(event == PY_MONITORING_EVENT_JUMP ||
|
||||
event == PY_MONITORING_EVENT_BRANCH);
|
||||
assert(frame->prev_instr == instr);
|
||||
assert(frame->instr_ptr == instr);
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
int to = (int)(target - _PyCode_CODE(code));
|
||||
PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT));
|
||||
|
@ -1086,9 +1086,9 @@ _Py_call_instrumentation_jump(
|
|||
if (err) {
|
||||
return NULL;
|
||||
}
|
||||
if (frame->prev_instr != instr) {
|
||||
if (frame->instr_ptr != instr) {
|
||||
/* The callback has caused a jump (by setting the line number) */
|
||||
return frame->prev_instr;
|
||||
return frame->instr_ptr;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
@ -1138,7 +1138,6 @@ _Py_Instrumentation_GetLine(PyCodeObject *code, int index)
|
|||
int
|
||||
_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev)
|
||||
{
|
||||
assert(frame->prev_instr == instr);
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
assert(is_version_up_to_date(code, tstate->interp));
|
||||
assert(instrumentation_cross_checks(tstate->interp, code));
|
||||
|
@ -1153,6 +1152,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
|
|||
int8_t line_delta = line_data->line_delta;
|
||||
int line = compute_line(code, i, line_delta);
|
||||
assert(line >= 0);
|
||||
assert(prev != NULL);
|
||||
int prev_index = (int)(prev - _PyCode_CODE(code));
|
||||
int prev_line = _Py_Instrumentation_GetLine(code, prev_index);
|
||||
if (prev_line == line) {
|
||||
|
|
|
@ -251,7 +251,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;
|
||||
}
|
||||
|
@ -701,11 +701,9 @@ pop_jump_if_bool:
|
|||
case OPARG_BOTTOM: // Second half of super-instr
|
||||
oparg = orig_oparg & 0xF;
|
||||
break;
|
||||
case OPARG_SET_IP: // uop=_SET_IP; oparg=next_instr-1
|
||||
// The number of caches is smuggled in via offset:
|
||||
assert(offset == _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]);
|
||||
oparg = INSTR_IP(instr + offset, code);
|
||||
uop = _SET_IP;
|
||||
case OPARG_SAVE_RETURN_OFFSET: // op=_SAVE_RETURN_OFFSET; oparg=return_offset
|
||||
oparg = offset;
|
||||
assert(uop == _SAVE_RETURN_OFFSET);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -2524,7 +2524,7 @@ static const PyBytesObject no_location = {
|
|||
};
|
||||
|
||||
const struct _PyCode_DEF(8) _Py_InitCleanup = {
|
||||
_PyVarObject_HEAD_INIT(&PyCode_Type, 4)
|
||||
_PyVarObject_HEAD_INIT(&PyCode_Type, 3)
|
||||
.co_consts = (PyObject *)&_Py_SINGLETON(tuple_empty),
|
||||
.co_names = (PyObject *)&_Py_SINGLETON(tuple_empty),
|
||||
.co_exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty),
|
||||
|
@ -2539,7 +2539,6 @@ const struct _PyCode_DEF(8) _Py_InitCleanup = {
|
|||
.co_stacksize = 2,
|
||||
.co_framesize = 2 + FRAME_SPECIALS_SIZE,
|
||||
.co_code_adaptive = {
|
||||
NOP, 0,
|
||||
EXIT_INIT_CHECK, 0,
|
||||
RETURN_VALUE, 0,
|
||||
RESUME, 0,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue