From 5b0d27e4698e555fccbcd1b0f62ddc80e5dd4a14 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Thu, 14 Mar 2024 15:37:43 -0700 Subject: [PATCH 1/2] Simplify weakref creation logic Since 3.12 allocating a GC object cannot immediately trigger GC. This allows us to simplify the logic for creating the canonical callback-less weakref. --- Objects/weakrefobject.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index df74be6aba7244..5ef3689e33fded 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -801,24 +801,14 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) if (result != NULL) Py_INCREF(result); else { - /* Note: new_weakref() can trigger cyclic GC, so the weakref - list on ob can be mutated. This means that the ref and - proxy pointers we got back earlier may have been collected, - so we need to compute these values again before we use - them. */ + /* We do not need to recompute ref/proxy; new_weakref() cannot + trigger GC. + */ result = new_weakref(ob, callback); if (result != NULL) { - get_basic_refs(*list, &ref, &proxy); if (callback == NULL) { if (ref == NULL) insert_head(result, list); - else { - /* Someone else added a ref without a callback - during GC. Return that one instead of this one - to avoid violating the invariants of the list - of weakrefs for ob. */ - Py_SETREF(result, (PyWeakReference*)Py_NewRef(ref)); - } } else { PyWeakReference *prev; From 56956ecf51479c47b358b2d51b00b32a5582642c Mon Sep 17 00:00:00 2001 From: Matt Page Date: Thu, 14 Mar 2024 16:16:36 -0700 Subject: [PATCH 2/2] Ref is always NULL if callback is NULL --- Objects/weakrefobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 5ef3689e33fded..6264b1825eda73 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -807,8 +807,8 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) result = new_weakref(ob, callback); if (result != NULL) { if (callback == NULL) { - if (ref == NULL) - insert_head(result, list); + assert(ref == NULL); + insert_head(result, list); } else { PyWeakReference *prev;