summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c115
1 files changed, 57 insertions, 58 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index eb8b66f..971397c 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -945,48 +945,25 @@ dummy_func(
LLTRACE_RESUME_FRAME();
}
- inst(INSTRUMENTED_RETURN_VALUE, (retval --)) {
+ tier1 op(_RETURN_VALUE_EVENT, (val -- val)) {
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_RETURN,
- frame, this_instr, PyStackRef_AsPyObjectBorrow(retval));
+ frame, this_instr, PyStackRef_AsPyObjectBorrow(val));
if (err) ERROR_NO_POP();
- STACK_SHRINK(1);
- assert(EMPTY());
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_LeaveRecursiveCallPy(tstate);
- assert(frame != &entry_frame);
- // GH-99729: We need to unlink the frame *before* clearing it:
- _PyInterpreterFrame *dying = frame;
- frame = tstate->current_frame = dying->previous;
- _PyEval_FrameClearAndPop(tstate, dying);
- _PyFrame_StackPush(frame, retval);
- LOAD_IP(frame->return_offset);
- goto resume_frame;
}
+ macro(INSTRUMENTED_RETURN_VALUE) =
+ _RETURN_VALUE_EVENT +
+ RETURN_VALUE;
+
macro(RETURN_CONST) =
LOAD_CONST +
RETURN_VALUE;
- inst(INSTRUMENTED_RETURN_CONST, (--)) {
- PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg);
- int err = _Py_call_instrumentation_arg(
- tstate, PY_MONITORING_EVENT_PY_RETURN,
- frame, this_instr, retval);
- if (err) ERROR_NO_POP();
- Py_INCREF(retval);
- assert(EMPTY());
- _PyFrame_SetStackPointer(frame, stack_pointer);
- _Py_LeaveRecursiveCallPy(tstate);
- assert(frame != &entry_frame);
- // GH-99729: We need to unlink the frame *before* clearing it:
- _PyInterpreterFrame *dying = frame;
- frame = tstate->current_frame = dying->previous;
- _PyEval_FrameClearAndPop(tstate, dying);
- _PyFrame_StackPush(frame, PyStackRef_FromPyObjectSteal(retval));
- LOAD_IP(frame->return_offset);
- goto resume_frame;
- }
+ macro(INSTRUMENTED_RETURN_CONST) =
+ LOAD_CONST +
+ _RETURN_VALUE_EVENT +
+ RETURN_VALUE;
inst(GET_AITER, (obj -- iter)) {
unaryfunc getter = NULL;
@@ -1183,31 +1160,6 @@ dummy_func(
_SEND_GEN_FRAME +
_PUSH_FRAME;
- inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) {
- assert(frame != &entry_frame);
- frame->instr_ptr = next_instr;
- PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
- assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
- assert(oparg == 0 || oparg == 1);
- gen->gi_frame_state = FRAME_SUSPENDED + oparg;
- _PyFrame_SetStackPointer(frame, stack_pointer - 1);
- int err = _Py_call_instrumentation_arg(
- tstate, PY_MONITORING_EVENT_PY_YIELD,
- frame, this_instr, PyStackRef_AsPyObjectBorrow(retval));
- if (err) ERROR_NO_POP();
- tstate->exc_info = gen->gi_exc_state.previous_item;
- gen->gi_exc_state.previous_item = NULL;
- _Py_LeaveRecursiveCallPy(tstate);
- _PyInterpreterFrame *gen_frame = frame;
- 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;
- }
-
inst(YIELD_VALUE, (retval -- value)) {
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed close()
@@ -1244,6 +1196,23 @@ dummy_func(
LLTRACE_RESUME_FRAME();
}
+ tier1 op(_YIELD_VALUE_EVENT, (val -- val)) {
+ SAVE_SP();
+ int err = _Py_call_instrumentation_arg(
+ tstate, PY_MONITORING_EVENT_PY_YIELD,
+ frame, this_instr, PyStackRef_AsPyObjectBorrow(val));
+ LOAD_SP();
+ if (err) ERROR_NO_POP();
+ if (frame->instr_ptr != this_instr) {
+ next_instr = frame->instr_ptr;
+ DISPATCH();
+ }
+ }
+
+ macro(INSTRUMENTED_YIELD_VALUE) =
+ _YIELD_VALUE_EVENT +
+ YIELD_VALUE;
+
inst(POP_EXCEPT, (exc_value -- )) {
_PyErr_StackItem *exc_info = tstate->exc_info;
Py_XSETREF(exc_info->exc_value,
@@ -4450,6 +4419,36 @@ dummy_func(
assert(oparg >= 2);
}
+ inst(INSTRUMENTED_LINE, ( -- )) {
+ int original_opcode = 0;
+ if (tstate->tracing) {
+ PyCodeObject *code = _PyFrame_GetCode(frame);
+ original_opcode = code->_co_monitoring->lines[(int)(this_instr - _PyCode_CODE(code))].original_opcode;
+ next_instr = this_instr;
+ } else {
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ original_opcode = _Py_call_instrumentation_line(
+ tstate, frame, this_instr, prev_instr);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ if (original_opcode < 0) {
+ next_instr = this_instr+1;
+ goto error;
+ }
+ next_instr = frame->instr_ptr;
+ if (next_instr != this_instr) {
+ DISPATCH();
+ }
+ }
+ if (_PyOpcode_Caches[original_opcode]) {
+ _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1);
+ /* Prevent the underlying instruction from specializing
+ * and overwriting the instrumentation. */
+ PAUSE_ADAPTIVE_COUNTER(cache->counter);
+ }
+ opcode = original_opcode;
+ DISPATCH_GOTO();
+ }
+
inst(INSTRUMENTED_INSTRUCTION, ( -- )) {
int next_opcode = _Py_call_instrumentation_instruction(
tstate, frame, this_instr);