@@ -241,8 +241,9 @@ get_oparg(PyObject *self, PyObject *Py_UNUSED(ignored))
241241
242242///////////////////// Experimental UOp Optimizer /////////////////////
243243
244- static int executor_clear (PyObject * executor );
245- static void unlink_executor (_PyExecutorObject * executor );
244+ static int executor_clear (PyInterpreterState * interp , PyObject * executor );
245+ static int executor_clear_implicit_interp (PyObject * executor );
246+ static void unlink_executor (PyInterpreterState * interp , _PyExecutorObject * executor );
246247
247248
248249void
@@ -308,7 +309,7 @@ uop_dealloc(PyObject *op) {
308309 _PyExecutorObject * self = _PyExecutorObject_CAST (op );
309310 _PyObject_GC_UNTRACK (self );
310311 assert (self -> vm_data .code == NULL );
311- unlink_executor (self );
312+ unlink_executor (_PyInterpreterState_GET (), self );
312313 // Once unlinked it becomes impossible to invalidate an executor, so do it here.
313314 self -> vm_data .valid = 0 ;
314315 add_to_pending_deletion_list (self );
@@ -464,7 +465,7 @@ PyTypeObject _PyUOpExecutor_Type = {
464465 .tp_as_sequence = & uop_as_sequence ,
465466 .tp_methods = uop_executor_methods ,
466467 .tp_traverse = executor_traverse ,
467- .tp_clear = executor_clear ,
468+ .tp_clear = executor_clear_implicit_interp ,
468469 .tp_is_gc = executor_is_gc ,
469470};
470471
@@ -1525,7 +1526,7 @@ link_executor(_PyExecutorObject *executor)
15251526}
15261527
15271528static void
1528- unlink_executor (_PyExecutorObject * executor )
1529+ unlink_executor (PyInterpreterState * interp , _PyExecutorObject * executor )
15291530{
15301531 if (!executor -> vm_data .linked ) {
15311532 return ;
@@ -1542,7 +1543,6 @@ unlink_executor(_PyExecutorObject *executor)
15421543 }
15431544 else {
15441545 // prev == NULL implies that executor is the list head
1545- PyInterpreterState * interp = PyInterpreterState_Get ();
15461546 assert (interp -> executor_list_head == executor );
15471547 interp -> executor_list_head = next ;
15481548 }
@@ -1653,15 +1653,19 @@ _Py_ExecutorDetach(_PyExecutorObject *executor)
16531653 Py_DECREF (executor );
16541654}
16551655
1656+ // Note: we must use the interp state supplied and pass it to
1657+ // unlink_executor. This function might be called when a new
1658+ // interpreter is being created/removed. Thus the interpreter
1659+ // state is inconsistent with where the executor actually belongs.
16561660static int
1657- executor_clear (PyObject * op )
1661+ executor_clear (PyInterpreterState * interp , PyObject * op )
16581662{
16591663 _PyExecutorObject * executor = _PyExecutorObject_CAST (op );
16601664 if (!executor -> vm_data .valid ) {
16611665 return 0 ;
16621666 }
16631667 assert (executor -> vm_data .valid == 1 );
1664- unlink_executor (executor );
1668+ unlink_executor (interp , executor );
16651669 executor -> vm_data .valid = 0 ;
16661670
16671671 /* It is possible for an executor to form a reference
@@ -1675,15 +1679,21 @@ executor_clear(PyObject *op)
16751679 executor -> exits [i ].temperature = initial_unreachable_backoff_counter ();
16761680 _PyExecutorObject * e = executor -> exits [i ].executor ;
16771681 executor -> exits [i ].executor = NULL ;
1678- if (e != cold && e != cold_dynamic ) {
1679- executor_clear ((PyObject * )e );
1682+ if (e != cold && e != cold_dynamic && e -> vm_data . code == NULL ) {
1683+ executor_clear (interp , (PyObject * )e );
16801684 }
16811685 }
16821686 _Py_ExecutorDetach (executor );
16831687 Py_DECREF (executor );
16841688 return 0 ;
16851689}
16861690
1691+ static int
1692+ executor_clear_implicit_interp (PyObject * op )
1693+ {
1694+ return executor_clear (_PyInterpreterState_GET (), op );
1695+ }
1696+
16871697void
16881698_Py_Executor_DependsOn (_PyExecutorObject * executor , void * obj )
16891699{
@@ -1728,7 +1738,7 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
17281738 }
17291739 for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (invalidate ); i ++ ) {
17301740 PyObject * exec = PyList_GET_ITEM (invalidate , i );
1731- executor_clear (exec );
1741+ executor_clear (interp , exec );
17321742 if (is_invalidation ) {
17331743 OPT_STAT_INC (executors_invalidated );
17341744 }
@@ -1766,7 +1776,7 @@ _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation)
17661776 _PyCode_Clear_Executors (executor -> vm_data .code );
17671777 }
17681778 else {
1769- executor_clear ((PyObject * )executor );
1779+ executor_clear (interp , (PyObject * )executor );
17701780 }
17711781 if (is_invalidation ) {
17721782 OPT_STAT_INC (executors_invalidated );
@@ -1801,7 +1811,7 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp)
18011811 }
18021812 for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (invalidate ); i ++ ) {
18031813 PyObject * exec = PyList_GET_ITEM (invalidate , i );
1804- executor_clear (exec );
1814+ executor_clear (interp , exec );
18051815 }
18061816 Py_DECREF (invalidate );
18071817 return ;
0 commit comments