// Asserts that the mutex for the given object is locked. The mutex must
// be held by the top-most critical section otherwise there's the
// possibility that the mutex would be swalled out in some code paths.
+//
+// NOTE: We use Py_REFCNT(op) != 1 instead of
+// !PyUnstable_Object_IsUniquelyReferenced(op) because the free threading
+// GC can change an object's ob_tid (it overwrites ob_tid and later
+// restores it from the mimalloc segment). This means
+// PyUnstable_Object_IsUniquelyReferenced() may spuriously return false
+// after a GC collection, even though the thread may still have exclusive
+// access to the object. The refcount check is a looser but still catches
+// most misuses.
#ifdef Py_DEBUG
# define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op) \
The garbage collector also temporarily repurposes the `ob_tid` (thread ID)
and `ob_ref_local` (local reference count) fields for other purposes during
-collections.
+collections. The `ob_tid` field is later restored from the containing
+mimalloc segment data structure. In some cases, such as when the original
+allocating thread exits, this can result in a different `ob_tid` value.
+Code should not rely on `ob_tid` being stable across operations that may
+trigger garbage collection.
C APIs