Skip to content

Conversation

@colesbury
Copy link
Contributor

@colesbury colesbury commented Dec 5, 2025

Copy link
Member

@Fidget-Spinner Fidget-Spinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. Could you also please take a look at #141675 ? If that goes in, then some of the docs will go out of date as we won't be using different tagging schemes anymore.

Copy link
Contributor

@mpage mpage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just some suggestions inline

Going back to `PyObject*` mirrors this:

- `PyStackRef_AsPyObjectBorrow(ref)` - borrow the underlying pointer
- `PyStackRef_AsPyObjectSteal(ref)` - transfer ownership from the stackref
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ref is borrowed/deferred this will create a new owning reference. Not sure it's worth documenting, but I figured I'd call it out since this is not exactly the dual of PyStackRef_FromPyObjectSteal.

Objects that support deferred reference counting can be pushed to the evaluation
stack and stored in local variables without directly incrementing the reference
count because they are only freed during cyclic garbage collection. This avoids
reference count contention on short-lived values such as methods and types. The GC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is confusing to me because methods and types tend to be long-lived.

Suggested change
reference count contention on short-lived values such as methods and types. The GC
reference count contention on commonly shared objects such as methods and types. The GC


In GIL builds, most objects carry their refcount; tagged borrowed refs skip decref on close. In free
threading builds, the tag is also used to mark deferred refcounted objects so the GC can see them and
to avoid refcount contention for short-lived stack values.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm probably misreading this as it's written (it's Friday afternoon) but the following is clearer to me

Suggested change
to avoid refcount contention for short-lived stack values.
to avoid refcount contention on commonly shared objects.

Comment on lines +10 to +12
- `Py_TAG_REFCNT` clear - reference count lives on the pointed-to object.
- `Py_TAG_REFCNT` set - ownership is "borrowed" (no refcount to drop on close) or the object is immortal.
- `Py_INT_TAG` - tagged small integer stored directly in the stackref (no heap allocation).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `Py_TAG_REFCNT` clear - reference count lives on the pointed-to object.
- `Py_TAG_REFCNT` set - ownership is "borrowed" (no refcount to drop on close) or the object is immortal.
- `Py_INT_TAG` - tagged small integer stored directly in the stackref (no heap allocation).
- `Py_TAG_REFCNT` unset - reference count lives on the pointed-to object.
- `Py_TAG_REFCNT` set - ownership is "borrowed" (no refcount to drop on close) or the object is immortal.
- `Py_INT_TAG` set - tagged small integer stored directly in the stackref (no heap allocation).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants