gh-94673: Add Per-Interpreter tp_weaklist for Static Builtin Types (#95302)

* Store tp_weaklist on the interpreter state for static builtin types.

* Factor out _PyStaticType_GET_WEAKREFS_LISTPTR().

* Add _PyStaticType_ClearWeakRefs().

* Add a comment about how _PyStaticType_ClearWeakRefs() loops.

* Document the change.

* Update Doc/whatsnew/3.12.rst

* Fix a typo.
This commit is contained in:
Eric Snow 2022-07-28 19:23:47 -06:00 committed by GitHub
parent 6e44bf9558
commit 3e7cad3bca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 1 deletions

View file

@ -220,6 +220,12 @@ extern void _Py_PrintReferenceAddresses(FILE *);
static inline PyObject **
_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
{
if (PyType_Check(op) &&
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
static_builtin_state *state = _PyStaticType_GetState(
(PyTypeObject *)op);
return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
}
Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
return (PyObject **)((char *)op + offset);
}

View file

@ -45,8 +45,20 @@ struct type_cache {
typedef struct {
PyTypeObject *type;
/* We never clean up weakrefs for static builtin types since
they will effectively never get triggered. However, there
are also some diagnostic uses for the list of weakrefs,
so we still keep it. */
PyObject *tp_weaklist;
} static_builtin_state;
static inline PyObject **
_PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state)
{
assert(state != NULL);
return &state->tp_weaklist;
}
struct types_state {
struct type_cache type_cache;
size_t num_builtins_initialized;
@ -58,6 +70,7 @@ extern PyStatus _PyTypes_InitSlotDefs(void);
extern int _PyStaticType_InitBuiltin(PyTypeObject *type);
extern static_builtin_state * _PyStaticType_GetState(PyTypeObject *);
extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type);
extern void _PyStaticType_Dealloc(PyTypeObject *type);