gh-122417: Implement per-thread heap type refcounts (#122418)

The free-threaded build partially stores heap type reference counts in
distributed manner in per-thread arrays. This avoids reference count
contention when creating or destroying instances.

Co-authored-by: Ken Jin <kenjin@python.org>
This commit is contained in:
Sam Gross 2024-08-06 14:36:57 -04:00 committed by GitHub
parent 1429651a06
commit dc09301067
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 427 additions and 69 deletions

View file

@ -2452,7 +2452,7 @@ subtype_dealloc(PyObject *self)
reference counting. Only decref if the base type is not already a heap
allocated type. Otherwise, basedealloc should have decref'd it already */
if (type_needs_decref) {
Py_DECREF(type);
_Py_DECREF_TYPE(type);
}
/* Done */
@ -2562,7 +2562,7 @@ subtype_dealloc(PyObject *self)
reference counting. Only decref if the base type is not already a heap
allocated type. Otherwise, basedealloc should have decref'd it already */
if (type_needs_decref) {
Py_DECREF(type);
_Py_DECREF_TYPE(type);
}
endlabel:
@ -3913,7 +3913,9 @@ type_new_alloc(type_new_ctx *ctx)
et->ht_module = NULL;
et->_ht_tpname = NULL;
_PyObject_SetDeferredRefcount((PyObject *)et);
#ifdef Py_GIL_DISABLED
_PyType_AssignId(et);
#endif
return type;
}
@ -4965,6 +4967,11 @@ _PyType_FromMetaclass_impl(
type->tp_weaklistoffset = weaklistoffset;
type->tp_dictoffset = dictoffset;
#ifdef Py_GIL_DISABLED
// Assign a type id to enable thread-local refcounting
_PyType_AssignId(res);
#endif
/* Ready the type (which includes inheritance).
*
* After this call we should generally only touch up what's
@ -5914,6 +5921,9 @@ type_dealloc(PyObject *self)
}
Py_XDECREF(et->ht_module);
PyMem_Free(et->_ht_tpname);
#ifdef Py_GIL_DISABLED
_PyType_ReleaseId(et);
#endif
Py_TYPE(type)->tp_free((PyObject *)type);
}