mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
GH-118093: Remove invalidated executors from side exits (GH-121885)
This commit is contained in:
parent
e9681211b9
commit
794546fd53
4 changed files with 27 additions and 28 deletions
2
Include/internal/pycore_uop_metadata.h
generated
2
Include/internal/pycore_uop_metadata.h
generated
|
@ -260,7 +260,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_CHECK_FUNCTION] = HAS_DEOPT_FLAG,
|
[_CHECK_FUNCTION] = HAS_DEOPT_FLAG,
|
||||||
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
|
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
|
||||||
[_DYNAMIC_EXIT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
|
[_DYNAMIC_EXIT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_START_EXECUTOR] = HAS_DEOPT_FLAG,
|
[_START_EXECUTOR] = 0,
|
||||||
[_FATAL_ERROR] = 0,
|
[_FATAL_ERROR] = 0,
|
||||||
[_CHECK_VALIDITY_AND_SET_IP] = HAS_DEOPT_FLAG,
|
[_CHECK_VALIDITY_AND_SET_IP] = HAS_DEOPT_FLAG,
|
||||||
[_DEOPT] = 0,
|
[_DEOPT] = 0,
|
||||||
|
|
|
@ -4624,6 +4624,10 @@ dummy_func(
|
||||||
_PyOpcode_OpName[target->op.code]);
|
_PyOpcode_OpName[target->op.code]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (exit->executor && !exit->executor->vm_data.valid) {
|
||||||
|
exit->temperature = initial_temperature_backoff_counter();
|
||||||
|
Py_CLEAR(exit->executor);
|
||||||
|
}
|
||||||
if (exit->executor == NULL) {
|
if (exit->executor == NULL) {
|
||||||
_Py_BackoffCounter temperature = exit->temperature;
|
_Py_BackoffCounter temperature = exit->temperature;
|
||||||
if (!backoff_counter_triggers(temperature)) {
|
if (!backoff_counter_triggers(temperature)) {
|
||||||
|
@ -4743,7 +4747,7 @@ dummy_func(
|
||||||
#ifndef _Py_JIT
|
#ifndef _Py_JIT
|
||||||
current_executor = (_PyExecutorObject*)executor;
|
current_executor = (_PyExecutorObject*)executor;
|
||||||
#endif
|
#endif
|
||||||
DEOPT_IF(!((_PyExecutorObject *)executor)->vm_data.valid);
|
assert(((_PyExecutorObject *)executor)->vm_data.valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
tier2 op(_FATAL_ERROR, (--)) {
|
tier2 op(_FATAL_ERROR, (--)) {
|
||||||
|
|
9
Python/executor_cases.c.h
generated
9
Python/executor_cases.c.h
generated
|
@ -4986,6 +4986,10 @@
|
||||||
_PyOpcode_OpName[target->op.code]);
|
_PyOpcode_OpName[target->op.code]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (exit->executor && !exit->executor->vm_data.valid) {
|
||||||
|
exit->temperature = initial_temperature_backoff_counter();
|
||||||
|
Py_CLEAR(exit->executor);
|
||||||
|
}
|
||||||
if (exit->executor == NULL) {
|
if (exit->executor == NULL) {
|
||||||
_Py_BackoffCounter temperature = exit->temperature;
|
_Py_BackoffCounter temperature = exit->temperature;
|
||||||
if (!backoff_counter_triggers(temperature)) {
|
if (!backoff_counter_triggers(temperature)) {
|
||||||
|
@ -5156,10 +5160,7 @@
|
||||||
#ifndef _Py_JIT
|
#ifndef _Py_JIT
|
||||||
current_executor = (_PyExecutorObject*)executor;
|
current_executor = (_PyExecutorObject*)executor;
|
||||||
#endif
|
#endif
|
||||||
if (!((_PyExecutorObject *)executor)->vm_data.valid) {
|
assert(((_PyExecutorObject *)executor)->vm_data.valid);
|
||||||
UOP_STAT_INC(uopcode, miss);
|
|
||||||
JUMP_TO_JUMP_TARGET();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1587,42 +1587,36 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
|
||||||
_Py_BloomFilter_Add(&obj_filter, obj);
|
_Py_BloomFilter_Add(&obj_filter, obj);
|
||||||
/* Walk the list of executors */
|
/* Walk the list of executors */
|
||||||
/* TO DO -- Use a tree to avoid traversing as many objects */
|
/* TO DO -- Use a tree to avoid traversing as many objects */
|
||||||
bool no_memory = false;
|
|
||||||
PyObject *invalidate = PyList_New(0);
|
PyObject *invalidate = PyList_New(0);
|
||||||
if (invalidate == NULL) {
|
if (invalidate == NULL) {
|
||||||
PyErr_Clear();
|
goto error;
|
||||||
no_memory = true;
|
|
||||||
}
|
}
|
||||||
/* Clearing an executor can deallocate others, so we need to make a list of
|
/* Clearing an executor can deallocate others, so we need to make a list of
|
||||||
* executors to invalidate first */
|
* executors to invalidate first */
|
||||||
for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) {
|
for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) {
|
||||||
assert(exec->vm_data.valid);
|
assert(exec->vm_data.valid);
|
||||||
_PyExecutorObject *next = exec->vm_data.links.next;
|
_PyExecutorObject *next = exec->vm_data.links.next;
|
||||||
if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter)) {
|
if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter) &&
|
||||||
unlink_executor(exec);
|
PyList_Append(invalidate, (PyObject *)exec))
|
||||||
if (no_memory) {
|
{
|
||||||
exec->vm_data.valid = 0;
|
goto error;
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
exec = next;
|
exec = next;
|
||||||
}
|
}
|
||||||
if (invalidate != NULL) {
|
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
|
||||||
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
|
_PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
|
||||||
_PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
|
executor_clear(exec);
|
||||||
executor_clear(exec);
|
if (is_invalidation) {
|
||||||
|
OPT_STAT_INC(executors_invalidated);
|
||||||
}
|
}
|
||||||
Py_DECREF(invalidate);
|
|
||||||
}
|
}
|
||||||
|
Py_DECREF(invalidate);
|
||||||
return;
|
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 */
|
/* Invalidate all executors */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue