aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/gc_free_threading.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/gc_free_threading.c')
-rw-r--r--Python/gc_free_threading.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 69ce22a1e83..4524382e4f6 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