gh-117139: Garbage collector support for deferred refcounting (#122956)

The free-threaded GC now visits interpreter stacks to keep objects
that use deferred reference counting alive.

Interpreter frames are zero initialized in the free-threaded GC so
that the GC doesn't see garbage data. This is a temporary measure
until stack spilling around escaping calls is implemented.

Co-authored-by: Ken Jin <kenjin@python.org>
This commit is contained in:
Sam Gross 2024-08-15 12:09:11 -04:00 committed by GitHub
parent 1dad23edbc
commit e001027188
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 121 additions and 20 deletions

View file

@ -150,8 +150,7 @@ PyStackRef_FromPyObjectNew(PyObject *obj)
// Make sure we don't take an already tagged value.
assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
assert(obj != NULL);
// TODO (gh-117139): Add deferred objects later.
if (_Py_IsImmortal(obj)) {
if (_Py_IsImmortal(obj) || _PyObject_HasDeferredRefcount(obj)) {
return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_DEFERRED };
}
else {
@ -220,7 +219,8 @@ PyStackRef_DUP(_PyStackRef stackref)
{
if (PyStackRef_IsDeferred(stackref)) {
assert(PyStackRef_IsNull(stackref) ||
_Py_IsImmortal(PyStackRef_AsPyObjectBorrow(stackref)));
_Py_IsImmortal(PyStackRef_AsPyObjectBorrow(stackref)) ||
_PyObject_HasDeferredRefcount(PyStackRef_AsPyObjectBorrow(stackref)));
return stackref;
}
Py_INCREF(PyStackRef_AsPyObjectBorrow(stackref));