-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Description
faster-cpython/ideas#700 describes three ways to count references:
- Virtual,
- Embedded, and
- Immediate
Virtual
references are references that are know to exist to the relevant code generator, but are elided at runtime, so no API is needed for them.
Embedded
references are marked by bit(s) in the reference and not in the ob_refcount
field of the object.
Immediate
references are counted in the ob_refcount
(or free-threading equivalent) field of the object.
To this we should add uncounted
which are references to immortal objects (including NULL
).
Note that it is possible to have embedded or immediate references to immortal objects if the object was mortal when the reference, or reference this reference was created from, was created.
Why this matters
It is important that the use of references is understandable without referring to the implementation and we have multiple implementations of stackrefs, so the interface needs to be clear.
Multiple implementations
Even when we merge the free-threading and default implementations of stackrefs, we will still have the Py_STACKREF_DEBUG
implementation which is very different and vital to finding reference errors.
Examples:
When creating an embedded stackref from another stackref, we should use PyStackRef_DUP_Embedded
which has the same semantics as PyStackRef_DUP
but creates an embedded reference if the implementation supports it.
There are circumstance when a method of counting is not safe. E.g. using embedded references in the heap is not safe. For that we will want to physically transform a reference without a logic change in ownership.
E.g. PyStackRef_ToNonEmbedded
. In terms of ownership, this a no-op, PyStackRef_ToNonEmbedded(ref)
is equivalent ref
, but ensures that any embedded count is turned into an immediate count.
We probably should only use uncounted
when referring to references in docs and comments, as we already have PyStackRef_FromPyObjectImmortal
, there is no need for PyStackRef_FromPyObjectUncounted
as well.