@@ -945,48 +945,25 @@ dummy_func(
945945 LLTRACE_RESUME_FRAME ();
946946 }
947947
948- inst ( INSTRUMENTED_RETURN_VALUE , (retval -- )) {
948+ tier1 op ( _RETURN_VALUE_EVENT , (val -- val )) {
949949 int err = _Py_call_instrumentation_arg (
950950 tstate , PY_MONITORING_EVENT_PY_RETURN ,
951- frame , this_instr , PyStackRef_AsPyObjectBorrow (retval ));
951+ frame , this_instr , PyStackRef_AsPyObjectBorrow (val ));
952952 if (err ) ERROR_NO_POP ();
953- STACK_SHRINK (1 );
954- assert (EMPTY ());
955- _PyFrame_SetStackPointer (frame , stack_pointer );
956- _Py_LeaveRecursiveCallPy (tstate );
957- assert (frame != & entry_frame );
958- // GH-99729: We need to unlink the frame *before* clearing it:
959- _PyInterpreterFrame * dying = frame ;
960- frame = tstate -> current_frame = dying -> previous ;
961- _PyEval_FrameClearAndPop (tstate , dying );
962- _PyFrame_StackPush (frame , retval );
963- LOAD_IP (frame -> return_offset );
964- goto resume_frame ;
965953 }
966954
955+ macro (INSTRUMENTED_RETURN_VALUE ) =
956+ _RETURN_VALUE_EVENT +
957+ RETURN_VALUE ;
958+
967959 macro (RETURN_CONST ) =
968960 LOAD_CONST +
969961 RETURN_VALUE ;
970962
971- inst (INSTRUMENTED_RETURN_CONST , (-- )) {
972- PyObject * retval = GETITEM (FRAME_CO_CONSTS , oparg );
973- int err = _Py_call_instrumentation_arg (
974- tstate , PY_MONITORING_EVENT_PY_RETURN ,
975- frame , this_instr , retval );
976- if (err ) ERROR_NO_POP ();
977- Py_INCREF (retval );
978- assert (EMPTY ());
979- _PyFrame_SetStackPointer (frame , stack_pointer );
980- _Py_LeaveRecursiveCallPy (tstate );
981- assert (frame != & entry_frame );
982- // GH-99729: We need to unlink the frame *before* clearing it:
983- _PyInterpreterFrame * dying = frame ;
984- frame = tstate -> current_frame = dying -> previous ;
985- _PyEval_FrameClearAndPop (tstate , dying );
986- _PyFrame_StackPush (frame , PyStackRef_FromPyObjectSteal (retval ));
987- LOAD_IP (frame -> return_offset );
988- goto resume_frame ;
989- }
963+ macro (INSTRUMENTED_RETURN_CONST ) =
964+ LOAD_CONST +
965+ _RETURN_VALUE_EVENT +
966+ RETURN_VALUE ;
990967
991968 inst (GET_AITER , (obj -- iter )) {
992969 unaryfunc getter = NULL ;
@@ -1183,31 +1160,6 @@ dummy_func(
11831160 _SEND_GEN_FRAME +
11841161 _PUSH_FRAME ;
11851162
1186- inst (INSTRUMENTED_YIELD_VALUE , (retval -- unused )) {
1187- assert (frame != & entry_frame );
1188- frame -> instr_ptr = next_instr ;
1189- PyGenObject * gen = _PyGen_GetGeneratorFromFrame (frame );
1190- assert (FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1 );
1191- assert (oparg == 0 || oparg == 1 );
1192- gen -> gi_frame_state = FRAME_SUSPENDED + oparg ;
1193- _PyFrame_SetStackPointer (frame , stack_pointer - 1 );
1194- int err = _Py_call_instrumentation_arg (
1195- tstate , PY_MONITORING_EVENT_PY_YIELD ,
1196- frame , this_instr , PyStackRef_AsPyObjectBorrow (retval ));
1197- if (err ) ERROR_NO_POP ();
1198- tstate -> exc_info = gen -> gi_exc_state .previous_item ;
1199- gen -> gi_exc_state .previous_item = NULL ;
1200- _Py_LeaveRecursiveCallPy (tstate );
1201- _PyInterpreterFrame * gen_frame = frame ;
1202- frame = tstate -> current_frame = frame -> previous ;
1203- gen_frame -> previous = NULL ;
1204- _PyFrame_StackPush (frame , retval );
1205- /* We don't know which of these is relevant here, so keep them equal */
1206- assert (INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER );
1207- LOAD_IP (1 + INLINE_CACHE_ENTRIES_SEND );
1208- goto resume_frame ;
1209- }
1210-
12111163 inst (YIELD_VALUE , (retval -- value )) {
12121164 // NOTE: It's important that YIELD_VALUE never raises an exception!
12131165 // The compiler treats any exception raised here as a failed close()
@@ -1244,6 +1196,23 @@ dummy_func(
12441196 LLTRACE_RESUME_FRAME ();
12451197 }
12461198
1199+ tier1 op (_YIELD_VALUE_EVENT , (val -- val )) {
1200+ SAVE_SP ();
1201+ int err = _Py_call_instrumentation_arg (
1202+ tstate , PY_MONITORING_EVENT_PY_YIELD ,
1203+ frame , this_instr , PyStackRef_AsPyObjectBorrow (val ));
1204+ LOAD_SP ();
1205+ if (err ) ERROR_NO_POP ();
1206+ if (frame -> instr_ptr != this_instr ) {
1207+ next_instr = frame -> instr_ptr ;
1208+ DISPATCH ();
1209+ }
1210+ }
1211+
1212+ macro (INSTRUMENTED_YIELD_VALUE ) =
1213+ _YIELD_VALUE_EVENT +
1214+ YIELD_VALUE ;
1215+
12471216 inst (POP_EXCEPT , (exc_value -- )) {
12481217 _PyErr_StackItem * exc_info = tstate -> exc_info ;
12491218 Py_XSETREF (exc_info -> exc_value ,
@@ -4450,6 +4419,36 @@ dummy_func(
44504419 assert (oparg >= 2 );
44514420 }
44524421
4422+ inst (INSTRUMENTED_LINE , ( -- )) {
4423+ int original_opcode = 0 ;
4424+ if (tstate -> tracing ) {
4425+ PyCodeObject * code = _PyFrame_GetCode (frame );
4426+ original_opcode = code -> _co_monitoring -> lines [(int )(this_instr - _PyCode_CODE (code ))].original_opcode ;
4427+ next_instr = this_instr ;
4428+ } else {
4429+ _PyFrame_SetStackPointer (frame , stack_pointer );
4430+ original_opcode = _Py_call_instrumentation_line (
4431+ tstate , frame , this_instr , prev_instr );
4432+ stack_pointer = _PyFrame_GetStackPointer (frame );
4433+ if (original_opcode < 0 ) {
4434+ next_instr = this_instr + 1 ;
4435+ goto error ;
4436+ }
4437+ next_instr = frame -> instr_ptr ;
4438+ if (next_instr != this_instr ) {
4439+ DISPATCH ();
4440+ }
4441+ }
4442+ if (_PyOpcode_Caches [original_opcode ]) {
4443+ _PyBinaryOpCache * cache = (_PyBinaryOpCache * )(next_instr + 1 );
4444+ /* Prevent the underlying instruction from specializing
4445+ * and overwriting the instrumentation. */
4446+ PAUSE_ADAPTIVE_COUNTER (cache -> counter );
4447+ }
4448+ opcode = original_opcode ;
4449+ DISPATCH_GOTO ();
4450+ }
4451+
44534452 inst (INSTRUMENTED_INSTRUCTION , ( -- )) {
44544453 int next_opcode = _Py_call_instrumentation_instruction (
44554454 tstate , frame , this_instr );
0 commit comments