]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-113750: Fix object resurrection in free-threaded builds (gh-113751)
authorSam Gross <colesbury@gmail.com>
Sat, 6 Jan 2024 03:12:26 +0000 (22:12 -0500)
committerGitHub <noreply@github.com>
Sat, 6 Jan 2024 03:12:26 +0000 (12:12 +0900)
gh-113750: Fix object resurrection on free-threaded builds

This avoids the undesired re-initializing of fields like `ob_gc_bits`,
`ob_mutex`, and `ob_tid` when an object is resurrected due to its
finalizer being called.

This change has no effect on the default (with GIL) build.

Include/cpython/object.h
Modules/_testcapi/gc.c
Objects/object.c

index d6482f4bc689a1ba62257aa00bbe3d51bda41de8..c93931634fee051aeac8d99c923b7f568e49f311 100644 (file)
@@ -4,6 +4,7 @@
 
 PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
 PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op);
+PyAPI_FUNC(void) _Py_ResurrectReference(PyObject *op);
 
 #ifdef Py_REF_DEBUG
 /* These are useful as debugging aids when chasing down refleaks. */
index 829200ad12cd3ce869b9a54392a80a0b9726457d..f4feaaafbdc6cc95b8c63adc521d8ac83345ef18 100644 (file)
@@ -126,9 +126,7 @@ slot_tp_del(PyObject *self)
      * never happened.
      */
     {
-        Py_ssize_t refcnt = Py_REFCNT(self);
-        _Py_NewReferenceNoTotal(self);
-        Py_SET_REFCNT(self, refcnt);
+        _Py_ResurrectReference(self);
     }
     assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self));
 }
index d970a26756173bdf48cd26421446a857527c4198..587c5528c01345b9d7134eb1a29926a01af23357 100644 (file)
@@ -509,9 +509,7 @@ PyObject_CallFinalizerFromDealloc(PyObject *self)
 
     /* tp_finalize resurrected it!  Make it look like the original Py_DECREF
      * never happened. */
-    Py_ssize_t refcnt = Py_REFCNT(self);
-    _Py_NewReferenceNoTotal(self);
-    Py_SET_REFCNT(self, refcnt);
+    _Py_ResurrectReference(self);
 
     _PyObject_ASSERT(self,
                      (!_PyType_IS_GC(Py_TYPE(self))
@@ -2389,6 +2387,17 @@ _Py_NewReferenceNoTotal(PyObject *op)
     new_reference(op);
 }
 
+void
+_Py_ResurrectReference(PyObject *op)
+{
+    if (_PyRuntime.tracemalloc.config.tracing) {
+        _PyTraceMalloc_NewReference(op);
+    }
+#ifdef Py_TRACE_REFS
+    _Py_AddToAllObjects(op);
+#endif
+}
+
 
 #ifdef Py_TRACE_REFS
 void