mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
gh-118692: Avoid creating unnecessary StopIteration instances for monitoring (#119216)
This commit is contained in:
parent
b64182550f
commit
6e9863d7a3
10 changed files with 60 additions and 35 deletions
|
@ -292,11 +292,9 @@ dummy_func(
|
|||
/* Need to create a fake StopIteration error here,
|
||||
* to conform to PEP 380 */
|
||||
if (PyGen_Check(receiver)) {
|
||||
PyErr_SetObject(PyExc_StopIteration, value);
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr)) {
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr, value)) {
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
PyErr_SetRaisedException(NULL);
|
||||
}
|
||||
DECREF_INPUTS();
|
||||
}
|
||||
|
@ -307,11 +305,9 @@ dummy_func(
|
|||
|
||||
tier1 inst(INSTRUMENTED_END_SEND, (receiver, value -- value)) {
|
||||
if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) {
|
||||
PyErr_SetObject(PyExc_StopIteration, value);
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr)) {
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr, value)) {
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
PyErr_SetRaisedException(NULL);
|
||||
}
|
||||
Py_DECREF(receiver);
|
||||
}
|
||||
|
|
|
@ -231,7 +231,8 @@ static void monitor_reraise(PyThreadState *tstate,
|
|||
_Py_CODEUNIT *instr);
|
||||
static int monitor_stop_iteration(PyThreadState *tstate,
|
||||
_PyInterpreterFrame *frame,
|
||||
_Py_CODEUNIT *instr);
|
||||
_Py_CODEUNIT *instr,
|
||||
PyObject *value);
|
||||
static void monitor_unwind(PyThreadState *tstate,
|
||||
_PyInterpreterFrame *frame,
|
||||
_Py_CODEUNIT *instr);
|
||||
|
@ -2215,12 +2216,19 @@ monitor_reraise(PyThreadState *tstate, _PyInterpreterFrame *frame,
|
|||
|
||||
static int
|
||||
monitor_stop_iteration(PyThreadState *tstate, _PyInterpreterFrame *frame,
|
||||
_Py_CODEUNIT *instr)
|
||||
_Py_CODEUNIT *instr, PyObject *value)
|
||||
{
|
||||
if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_STOP_ITERATION)) {
|
||||
return 0;
|
||||
}
|
||||
return do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_STOP_ITERATION);
|
||||
assert(!PyErr_Occurred());
|
||||
PyErr_SetObject(PyExc_StopIteration, value);
|
||||
int res = do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_STOP_ITERATION);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
PyErr_SetRaisedException(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
8
Python/generated_cases.c.h
generated
8
Python/generated_cases.c.h
generated
|
@ -3260,11 +3260,9 @@
|
|||
/* Need to create a fake StopIteration error here,
|
||||
* to conform to PEP 380 */
|
||||
if (PyGen_Check(receiver)) {
|
||||
PyErr_SetObject(PyExc_StopIteration, value);
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr)) {
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr, value)) {
|
||||
goto error;
|
||||
}
|
||||
PyErr_SetRaisedException(NULL);
|
||||
}
|
||||
Py_DECREF(value);
|
||||
stack_pointer += -1;
|
||||
|
@ -3281,11 +3279,9 @@
|
|||
value = stack_pointer[-1];
|
||||
receiver = stack_pointer[-2];
|
||||
if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) {
|
||||
PyErr_SetObject(PyExc_StopIteration, value);
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr)) {
|
||||
if (monitor_stop_iteration(tstate, frame, this_instr, value)) {
|
||||
goto error;
|
||||
}
|
||||
PyErr_SetRaisedException(NULL);
|
||||
}
|
||||
Py_DECREF(receiver);
|
||||
stack_pointer[-2] = value;
|
||||
|
|
|
@ -2622,7 +2622,7 @@ exception_event_teardown(int err, PyObject *exc) {
|
|||
}
|
||||
else {
|
||||
assert(PyErr_Occurred());
|
||||
Py_DECREF(exc);
|
||||
Py_XDECREF(exc);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -2712,15 +2712,17 @@ _PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, in
|
|||
}
|
||||
|
||||
int
|
||||
_PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
||||
_PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)
|
||||
{
|
||||
int event = PY_MONITORING_EVENT_STOP_ITERATION;
|
||||
assert(state->active);
|
||||
assert(!PyErr_Occurred());
|
||||
PyErr_SetObject(PyExc_StopIteration, value);
|
||||
PyObject *exc;
|
||||
if (exception_event_setup(&exc, event) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *args[4] = { NULL, NULL, NULL, exc };
|
||||
int err = capi_call_instrumentation(state, codelike, offset, args, 3, event);
|
||||
return exception_event_teardown(err, exc);
|
||||
return exception_event_teardown(err, NULL);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue