Skip to content

Commit

Permalink
pythonGH-107674: Avoid allocating boxed ints for sys.settrace line …
Browse files Browse the repository at this point in the history
…events (pythonGH-107780)
  • Loading branch information
markshannon authored Aug 10, 2023
1 parent 1d976b2 commit 37d8b90
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed performance regression in ``sys.settrace``.
44 changes: 38 additions & 6 deletions Python/instrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ call_instrumentation_vector(
/* Offset visible to user should be the offset in bytes, as that is the
* convention for APIs involving code offsets. */
int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT);
PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset);
PyObject *offset_obj = PyLong_FromLong(bytes_offset);
if (offset_obj == NULL) {
return -1;
}
Expand Down Expand Up @@ -1141,14 +1141,46 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
(interp->monitors.tools[PY_MONITORING_EVENT_LINE] |
code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_LINE]
);
PyObject *line_obj = PyLong_FromSsize_t(line);
/* Special case sys.settrace to avoid boxing the line number,
* only to immediately unbox it. */
if (tools & (1 << PY_MONITORING_SYS_TRACE_ID)) {
if (tstate->c_tracefunc != NULL && line >= 0) {
PyFrameObject *frame_obj = _PyFrame_GetFrameObject(frame);
if (frame_obj == NULL) {
return -1;
}
if (frame_obj->f_trace_lines) {
/* Need to set tracing and what_event as if using
* the instrumentation call. */
int old_what = tstate->what_event;
tstate->what_event = PY_MONITORING_EVENT_LINE;
tstate->tracing++;
/* Call c_tracefunc directly, having set the line number. */
Py_INCREF(frame_obj);
frame_obj->f_lineno = line;
int err = tstate->c_tracefunc(tstate->c_traceobj, frame_obj, PyTrace_LINE, Py_None);
frame_obj->f_lineno = 0;
tstate->tracing--;
tstate->what_event = old_what;
Py_DECREF(frame_obj);
if (err) {
return -1;
}
}
}
tools &= (255 - (1 << PY_MONITORING_SYS_TRACE_ID));
}
if (tools == 0) {
goto done;
}
PyObject *line_obj = PyLong_FromLong(line);
if (line_obj == NULL) {
return -1;
}
PyObject *args[3] = { NULL, (PyObject *)code, line_obj };
while (tools) {
do {
int tool = most_significant_bit(tools);
assert(tool >= 0 && tool < 8);
assert(tool >= 0 && tool < PY_MONITORING_SYS_PROFILE_ID);
assert(tools & (1 << tool));
tools &= ~(1 << tool);
int res = call_one_instrument(interp, tstate, &args[1],
Expand All @@ -1166,7 +1198,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
/* DISABLE */
remove_line_tools(code, i, 1 << tool);
}
}
} while (tools);
Py_DECREF(line_obj);
done:
assert(original_opcode != 0);
Expand Down Expand Up @@ -1195,7 +1227,7 @@ _Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame*
code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION]
);
int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT);
PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset);
PyObject *offset_obj = PyLong_FromLong(bytes_offset);
if (offset_obj == NULL) {
return -1;
}
Expand Down

0 comments on commit 37d8b90

Please sign in to comment.