diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 69ce22a1e83b62..4524382e4f689f 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -374,25 +374,28 @@ update_refs(const mi_heap_t *heap, const mi_heap_area_t *area, return true; } - // Untrack tuples and dicts as necessary in this pass. - if (PyTuple_CheckExact(op)) { - _PyTuple_MaybeUntrack(op); - if (!_PyObject_GC_IS_TRACKED(op)) { - gc_restore_refs(op); - return true; + Py_ssize_t refcount = Py_REFCNT(op); + _PyObject_ASSERT(op, refcount >= 0); + + if (refcount > 0) { + // Untrack tuples and dicts as necessary in this pass, but not objects + // with zero refcount, which we will want to collect. + if (PyTuple_CheckExact(op)) { + _PyTuple_MaybeUntrack(op); + if (!_PyObject_GC_IS_TRACKED(op)) { + gc_restore_refs(op); + return true; + } } - } - else if (PyDict_CheckExact(op)) { - _PyDict_MaybeUntrack(op); - if (!_PyObject_GC_IS_TRACKED(op)) { - gc_restore_refs(op); - return true; + else if (PyDict_CheckExact(op)) { + _PyDict_MaybeUntrack(op); + if (!_PyObject_GC_IS_TRACKED(op)) { + gc_restore_refs(op); + return true; + } } } - Py_ssize_t refcount = Py_REFCNT(op); - _PyObject_ASSERT(op, refcount >= 0); - // We repurpose ob_tid to compute "gc_refs", the number of external // references to the object (i.e., from outside the GC heaps). This means // that ob_tid is no longer a valid thread id until it is restored by