diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2024-07-24 16:16:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-24 16:16:30 (GMT) |
commit | 794546fd53dffa1903a2d0fbe8d745889978f5dc (patch) | |
tree | 417805f6a81561365e2b6b625510a75115a7a5ec /Python/optimizer.c | |
parent | e9681211b9ad11d1c1f471c43bc57cac46814779 (diff) | |
download | cpython-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.c | 38 |
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 */ |