summaryrefslogtreecommitdiffstats
path: root/Python/optimizer.c
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@microsoft.com>2024-07-24 16:16:30 (GMT)
committerGitHub <noreply@github.com>2024-07-24 16:16:30 (GMT)
commit794546fd53dffa1903a2d0fbe8d745889978f5dc (patch)
tree417805f6a81561365e2b6b625510a75115a7a5ec /Python/optimizer.c
parente9681211b9ad11d1c1f471c43bc57cac46814779 (diff)
downloadcpython-794546fd53dffa1903a2d0fbe8d745889978f5dc.zip
cpython-794546fd53dffa1903a2d0fbe8d745889978f5dc.tar.gz
cpython-794546fd53dffa1903a2d0fbe8d745889978f5dc.tar.bz2
GH-118093: Remove invalidated executors from side exits (GH-121885)
Diffstat (limited to 'Python/optimizer.c')
-rw-r--r--Python/optimizer.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/Python/optimizer.c b/Python/optimizer.c
index a43eed4..73316b3 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -1587,42 +1587,36 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
_Py_BloomFilter_Add(&obj_filter, obj);
/* Walk the list of executors */
/* TO DO -- Use a tree to avoid traversing as many objects */
- bool no_memory = false;
PyObject *invalidate = PyList_New(0);
if (invalidate == NULL) {
- PyErr_Clear();
- no_memory = true;
+ goto error;
}
/* Clearing an executor can deallocate others, so we need to make a list of
* executors to invalidate first */
for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) {
assert(exec->vm_data.valid);
_PyExecutorObject *next = exec->vm_data.links.next;
- if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter)) {
- unlink_executor(exec);
- if (no_memory) {
- exec->vm_data.valid = 0;
- } else {
- if (PyList_Append(invalidate, (PyObject *)exec) < 0) {
- PyErr_Clear();
- no_memory = true;
- exec->vm_data.valid = 0;
- }
- }
- if (is_invalidation) {
- OPT_STAT_INC(executors_invalidated);
- }
+ if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter) &&
+ PyList_Append(invalidate, (PyObject *)exec))
+ {
+ goto error;
}
exec = next;
}
- if (invalidate != NULL) {
- for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
- _PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
- executor_clear(exec);
+ for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
+ _PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
+ executor_clear(exec);
+ if (is_invalidation) {
+ OPT_STAT_INC(executors_invalidated);
}
- Py_DECREF(invalidate);
}
+ Py_DECREF(invalidate);
return;
+error:
+ PyErr_Clear();
+ Py_XDECREF(invalidate);
+ // If we're truly out of memory, wiping out everything is a fine fallback:
+ _Py_Executors_InvalidateAll(interp, is_invalidation);
}
/* Invalidate all executors */