Skip to content

Commit 794546f

Browse files
authored
GH-118093: Remove invalidated executors from side exits (GH-121885)
1 parent e968121 commit 794546f

File tree

4 files changed

+27
-28
lines changed

4 files changed

+27
-28
lines changed

Include/internal/pycore_uop_metadata.h

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -4624,6 +4624,10 @@ dummy_func(
46244624
_PyOpcode_OpName[target->op.code]);
46254625
}
46264626
#endif
4627+
if (exit->executor && !exit->executor->vm_data.valid) {
4628+
exit->temperature = initial_temperature_backoff_counter();
4629+
Py_CLEAR(exit->executor);
4630+
}
46274631
if (exit->executor == NULL) {
46284632
_Py_BackoffCounter temperature = exit->temperature;
46294633
if (!backoff_counter_triggers(temperature)) {
@@ -4743,7 +4747,7 @@ dummy_func(
47434747
#ifndef _Py_JIT
47444748
current_executor = (_PyExecutorObject*)executor;
47454749
#endif
4746-
DEOPT_IF(!((_PyExecutorObject *)executor)->vm_data.valid);
4750+
assert(((_PyExecutorObject *)executor)->vm_data.valid);
47474751
}
47484752

47494753
tier2 op(_FATAL_ERROR, (--)) {

Python/executor_cases.c.h

+5-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer.c

+16-22
Original file line numberDiff line numberDiff line change
@@ -1587,42 +1587,36 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
15871587
_Py_BloomFilter_Add(&obj_filter, obj);
15881588
/* Walk the list of executors */
15891589
/* TO DO -- Use a tree to avoid traversing as many objects */
1590-
bool no_memory = false;
15911590
PyObject *invalidate = PyList_New(0);
15921591
if (invalidate == NULL) {
1593-
PyErr_Clear();
1594-
no_memory = true;
1592+
goto error;
15951593
}
15961594
/* Clearing an executor can deallocate others, so we need to make a list of
15971595
* executors to invalidate first */
15981596
for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) {
15991597
assert(exec->vm_data.valid);
16001598
_PyExecutorObject *next = exec->vm_data.links.next;
1601-
if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter)) {
1602-
unlink_executor(exec);
1603-
if (no_memory) {
1604-
exec->vm_data.valid = 0;
1605-
} else {
1606-
if (PyList_Append(invalidate, (PyObject *)exec) < 0) {
1607-
PyErr_Clear();
1608-
no_memory = true;
1609-
exec->vm_data.valid = 0;
1610-
}
1611-
}
1612-
if (is_invalidation) {
1613-
OPT_STAT_INC(executors_invalidated);
1614-
}
1599+
if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter) &&
1600+
PyList_Append(invalidate, (PyObject *)exec))
1601+
{
1602+
goto error;
16151603
}
16161604
exec = next;
16171605
}
1618-
if (invalidate != NULL) {
1619-
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
1620-
_PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
1621-
executor_clear(exec);
1606+
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
1607+
_PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
1608+
executor_clear(exec);
1609+
if (is_invalidation) {
1610+
OPT_STAT_INC(executors_invalidated);
16221611
}
1623-
Py_DECREF(invalidate);
16241612
}
1613+
Py_DECREF(invalidate);
16251614
return;
1615+
error:
1616+
PyErr_Clear();
1617+
Py_XDECREF(invalidate);
1618+
// If we're truly out of memory, wiping out everything is a fine fallback:
1619+
_Py_Executors_InvalidateAll(interp, is_invalidation);
16261620
}
16271621

16281622
/* Invalidate all executors */

0 commit comments

Comments
 (0)