mirror of
https://github.com/python/cpython.git
synced 2025-07-30 14:44:10 +00:00
GH-95245: Move weakreflist into the pre-header. (GH-95996)
This commit is contained in:
parent
829aab8592
commit
5a8c15819c
6 changed files with 105 additions and 20 deletions
|
@ -2497,10 +2497,11 @@ subtype_getweakref(PyObject *obj, void *context)
|
|||
return NULL;
|
||||
}
|
||||
_PyObject_ASSERT((PyObject *)type,
|
||||
type->tp_weaklistoffset > 0);
|
||||
type->tp_weaklistoffset > 0 ||
|
||||
type->tp_weaklistoffset == MANAGED_WEAKREF_OFFSET);
|
||||
_PyObject_ASSERT((PyObject *)type,
|
||||
((type->tp_weaklistoffset + sizeof(PyObject *))
|
||||
<= (size_t)(type->tp_basicsize)));
|
||||
((type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject *))
|
||||
<= type->tp_basicsize));
|
||||
weaklistptr = (PyObject **)((char *)obj + type->tp_weaklistoffset);
|
||||
if (*weaklistptr == NULL)
|
||||
result = Py_None;
|
||||
|
@ -3093,9 +3094,9 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type)
|
|||
}
|
||||
|
||||
if (ctx->add_weak) {
|
||||
assert(!ctx->base->tp_itemsize);
|
||||
type->tp_weaklistoffset = slotoffset;
|
||||
slotoffset += sizeof(PyObject *);
|
||||
assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0);
|
||||
type->tp_flags |= Py_TPFLAGS_MANAGED_WEAKREF;
|
||||
type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET;
|
||||
}
|
||||
if (ctx->add_dict) {
|
||||
assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
|
||||
|
@ -5116,9 +5117,9 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char*
|
|||
!same_slots_added(newbase, oldbase))) {
|
||||
goto differs;
|
||||
}
|
||||
/* The above does not check for managed __dicts__ */
|
||||
if ((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) ==
|
||||
((newto->tp_flags & Py_TPFLAGS_MANAGED_DICT)))
|
||||
/* The above does not check for the preheader */
|
||||
if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) ==
|
||||
((newto->tp_flags & Py_TPFLAGS_PREHEADER)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -5217,7 +5218,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
|
|||
if (compatible_for_assignment(oldto, newto, "__class__")) {
|
||||
/* Changing the class will change the implicit dict keys,
|
||||
* so we must materialize the dictionary first. */
|
||||
assert((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == (newto->tp_flags & Py_TPFLAGS_MANAGED_DICT));
|
||||
assert((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == (newto->tp_flags & Py_TPFLAGS_PREHEADER));
|
||||
_PyObject_GetDictPtr(self);
|
||||
if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT &&
|
||||
_PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self)))
|
||||
|
@ -5360,7 +5361,7 @@ object_getstate_default(PyObject *obj, int required)
|
|||
{
|
||||
basicsize += sizeof(PyObject *);
|
||||
}
|
||||
if (Py_TYPE(obj)->tp_weaklistoffset) {
|
||||
if (Py_TYPE(obj)->tp_weaklistoffset > 0) {
|
||||
basicsize += sizeof(PyObject *);
|
||||
}
|
||||
if (slotnames != Py_None) {
|
||||
|
@ -6150,7 +6151,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
|
|||
if (type->tp_clear == NULL)
|
||||
type->tp_clear = base->tp_clear;
|
||||
}
|
||||
type->tp_flags |= (base->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
type->tp_flags |= (base->tp_flags & Py_TPFLAGS_PREHEADER);
|
||||
|
||||
if (type->tp_basicsize == 0)
|
||||
type->tp_basicsize = base->tp_basicsize;
|
||||
|
@ -6571,7 +6572,7 @@ type_ready_fill_dict(PyTypeObject *type)
|
|||
}
|
||||
|
||||
static int
|
||||
type_ready_dict_offset(PyTypeObject *type)
|
||||
type_ready_preheader(PyTypeObject *type)
|
||||
{
|
||||
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
|
||||
if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) {
|
||||
|
@ -6583,6 +6584,18 @@ type_ready_dict_offset(PyTypeObject *type)
|
|||
}
|
||||
type->tp_dictoffset = -1;
|
||||
}
|
||||
if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) {
|
||||
if (type->tp_weaklistoffset != 0 &&
|
||||
type->tp_weaklistoffset != MANAGED_WEAKREF_OFFSET)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"type %s has the Py_TPFLAGS_MANAGED_WEAKREF flag "
|
||||
"but tp_weaklistoffset is set",
|
||||
type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6802,7 +6815,7 @@ type_ready_post_checks(PyTypeObject *type)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
else if (type->tp_dictoffset < sizeof(PyObject)) {
|
||||
else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) {
|
||||
if (type->tp_dictoffset + type->tp_basicsize <= 0) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"type %s has a tp_dictoffset that is too small");
|
||||
|
@ -6847,7 +6860,7 @@ type_ready(PyTypeObject *type)
|
|||
if (type_ready_inherit(type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (type_ready_dict_offset(type) < 0) {
|
||||
if (type_ready_preheader(type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (type_ready_set_hash(type) < 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue