diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -437,9 +437,6 @@ move_unreachable(PyGC_Head *young, PyGC_ if (PyTuple_CheckExact(op)) { _PyTuple_MaybeUntrack(op); } - else if (PyDict_CheckExact(op)) { - _PyDict_MaybeUntrack(op); - } } else { /* This *may* be unreachable. To make progress, @@ -457,6 +454,19 @@ move_unreachable(PyGC_Head *young, PyGC_ } } +static void +untrack_dicts(PyGC_Head *head) +{ + PyGC_Head *next, *gc = head->gc.gc_next; + while (gc != head) { + PyObject *op = FROM_GC(gc); + next = gc->gc.gc_next; + if (PyDict_CheckExact(op)) + _PyDict_MaybeUntrack(op); + gc = next; + } +} + /* Return true if object has a finalization method. */ static int has_finalizer(PyObject *op) @@ -856,6 +866,7 @@ collect(int generation, Py_ssize_t *n_co gc_list_merge(young, old); } else { + untrack_dicts(young); long_lived_pending = 0; long_lived_total = gc_list_size(young); }