Skip to content

Commit e012b8b

Browse files
Store tp_weaklist on the interpreter state for static builtin types.
1 parent 47e75a0 commit e012b8b

File tree

4 files changed

+17
-1
lines changed

4 files changed

+17
-1
lines changed

Include/cpython/object.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ struct _typeobject {
219219
PyObject *tp_mro; /* method resolution order */
220220
PyObject *tp_cache;
221221
PyObject *tp_subclasses;
222-
PyObject *tp_weaklist;
222+
PyObject *tp_weaklist; /* not used for static builtin types */
223223
destructor tp_del;
224224

225225
/* Type attribute cache version tag. Added in version 2.6 */

Include/internal/pycore_object.h

+6
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,12 @@ extern void _Py_PrintReferenceAddresses(FILE *);
220220
static inline PyObject **
221221
_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
222222
{
223+
if (PyType_Check(op) &&
224+
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
225+
static_builtin_state *state = _PyStaticType_GetState(
226+
(PyTypeObject *)op);
227+
return &state->tp_weaklist;
228+
}
223229
Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
224230
return (PyObject **)((char *)op + offset);
225231
}

Include/internal/pycore_typeobject.h

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ struct type_cache {
4545

4646
typedef struct {
4747
PyTypeObject *type;
48+
/* We never clean up weakrefs for static builtin types since
49+
they will effectively never get triggered. However, there
50+
are also some diagnostic uses for the list of weakrefs,
51+
so we still keep it. */
52+
PyObject *tp_weaklist;
4853
} static_builtin_state;
4954

5055
struct types_state {

Objects/typeobject.c

+5
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ static_builtin_state_init(PyTypeObject *self)
127127

128128
static_builtin_state *state = static_builtin_state_get(interp, self);
129129
state->type = self;
130+
/* state->tp_weaklist is left NULL until insert_head() or insert_after()
131+
(in weakrefobject.c) sets it. */
130132
}
131133

132134
static void
@@ -138,6 +140,7 @@ static_builtin_state_clear(PyTypeObject *self)
138140

139141
static_builtin_state *state = static_builtin_state_get(interp, self);
140142
state->type = NULL;
143+
/* state->tp_weaklist should already have been cleared out. */
141144
static_builtin_index_clear(self);
142145

143146
assert(interp->types.num_builtins_initialized > 0);
@@ -502,6 +505,8 @@ static PyMemberDef type_members[] = {
502505
{"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY},
503506
{"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY},
504507
{"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY},
508+
/* Note that this value is misleading for static builtin types,
509+
since the memory at this offset will always be NULL. */
505510
{"__weakrefoffset__", T_PYSSIZET,
506511
offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
507512
{"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY},

0 commit comments

Comments
 (0)