Skip to content

Commit

Permalink
add last_traced_index to frame and use it instead of prev_instr in IN…
Browse files Browse the repository at this point in the history
…STRUMENTED_LINE
  • Loading branch information
iritkatriel committed Sep 13, 2023
1 parent d69805b commit 2f8629b
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 7 deletions.
4 changes: 4 additions & 0 deletions Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ typedef struct _PyInterpreterFrame {
* If there is no callee, then it is meaningless. */
uint16_t return_offset;
char owner;
/* Used by INSTRUMENTED_LINE */
int last_traced_index;
/* Locals and stack */
PyObject *localsplus[1];
} _PyInterpreterFrame;
Expand Down Expand Up @@ -137,6 +139,7 @@ _PyFrame_Initialize(
frame->prev_instr = _PyCode_CODE(code) - 1;
frame->return_offset = 0;
frame->owner = FRAME_OWNED_BY_THREAD;
frame->last_traced_index = 0;

for (int i = null_locals_from; i < code->co_nlocalsplus; i++) {
frame->localsplus[i] = NULL;
Expand Down Expand Up @@ -300,6 +303,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
frame->prev_instr = _PyCode_CODE(code) + prev_instr;
frame->owner = FRAME_OWNED_BY_THREAD;
frame->return_offset = 0;
frame->last_traced_index = 0;
return frame;
}

Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_instruments.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ _Py_call_instrumentation(PyThreadState *tstate, int event,

extern int
_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
_Py_CODEUNIT *instr, _Py_CODEUNIT *prev);
_Py_CODEUNIT *instr);

extern int
_Py_call_instrumentation_instruction(
Expand Down
3 changes: 1 addition & 2 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,11 +776,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
case INSTRUMENTED_LINE:
#endif
{
_Py_CODEUNIT *prev = frame->prev_instr;
_Py_CODEUNIT *here = frame->prev_instr = next_instr;
_PyFrame_SetStackPointer(frame, stack_pointer);
int original_opcode = _Py_call_instrumentation_line(
tstate, frame, here, prev);
tstate, frame, here);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (original_opcode < 0) {
next_instr = here+1;
Expand Down
9 changes: 5 additions & 4 deletions Python/instrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ _Py_Instrumentation_GetLine(PyCodeObject *code, int index)
}

int
_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev)
_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr)
{
assert(frame->prev_instr == instr);
PyCodeObject *code = _PyFrame_GetCode(frame);
Expand All @@ -1130,17 +1130,18 @@ _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);
int prev_index = (int)(prev - _PyCode_CODE(code));
int prev_line = _Py_Instrumentation_GetLine(code, prev_index);
int prev_line = frame->last_traced_index == 0 ? -1 :
_Py_Instrumentation_GetLine(code, frame->last_traced_index);
if (prev_line == line) {
int prev_opcode = _PyCode_CODE(code)[prev_index].op.code;
int prev_opcode = _PyCode_CODE(code)[frame->last_traced_index].op.code;
/* RESUME and INSTRUMENTED_RESUME are needed for the operation of
* instrumentation, so must never be hidden by an INSTRUMENTED_LINE.
*/
if (prev_opcode != RESUME && prev_opcode != INSTRUMENTED_RESUME) {
goto done;
}
}
frame->last_traced_index = i;
uint8_t tools = code->_co_monitoring->line_tools != NULL ?
code->_co_monitoring->line_tools[i] :
(interp->monitors.tools[PY_MONITORING_EVENT_LINE] |
Expand Down

0 comments on commit 2f8629b

Please sign in to comment.