summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-05-24 10:18:13 (GMT)
committerGitHub <noreply@github.com>2024-05-24 10:18:13 (GMT)
commitc864efba25465eb6a4fff7e0a6df80a9ba449370 (patch)
treed4c9968b1ac36ac938a4b595d55534ea7f2ac5ea /Python
parente27e36922ee9fa970d3d8e602ac7eeb442ca530a (diff)
downloadcpython-c864efba25465eb6a4fff7e0a6df80a9ba449370.zip
cpython-c864efba25465eb6a4fff7e0a6df80a9ba449370.tar.gz
cpython-c864efba25465eb6a4fff7e0a6df80a9ba449370.tar.bz2
[3.13] gh-118692: Avoid creating unnecessary StopIteration instances for monitoring (GH-119216) (#119497)
* gh-118692: Avoid creating unnecessary StopIteration instances for monitoring (GH-119216) (cherry picked from commit 6e9863d7a3516cc76d6ce13923b15620499f3855) --------- Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
Diffstat (limited to 'Python')
-rw-r--r--Python/bytecodes.c8
-rw-r--r--Python/ceval.c14
-rw-r--r--Python/generated_cases.c.h8
-rw-r--r--Python/instrumentation.c9
4 files changed, 21 insertions, 18 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 55eda97..434eb80 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -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);
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 128e041..324d062 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 8b81122..96161c5 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -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;
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 77d3489..9095fb9 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -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,18 @@ _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);
+ Py_DECREF(exc);
+ return exception_event_teardown(err, NULL);
}