summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-08-16 12:57:18 (GMT)
committerGitHub <noreply@github.com>2022-08-16 12:57:18 (GMT)
commit5a8c15819c27c516e5b75b7c9d89eacdb16b77c3 (patch)
treeb75d585f24f97aac724952a75175cc9f15af48af /Objects
parent829aab859266253320317caabdb0e17fa4e0f05e (diff)
downloadcpython-5a8c15819c27c516e5b75b7c9d89eacdb16b77c3.zip
cpython-5a8c15819c27c516e5b75b7c9d89eacdb16b77c3.tar.gz
cpython-5a8c15819c27c516e5b75b7c9d89eacdb16b77c3.tar.bz2
GH-95245: Move weakreflist into the pre-header. (GH-95996)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 67dfc6f..c881aeb 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -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) {