mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
GH-95245: Store object values and dict pointers in single tagged pointer. (GH-95278)
This commit is contained in:
parent
fb75d015f4
commit
de388c0a7b
10 changed files with 271 additions and 203 deletions
|
|
@ -1310,15 +1310,13 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg)
|
|||
}
|
||||
|
||||
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
|
||||
assert(type->tp_dictoffset);
|
||||
int err = _PyObject_VisitInstanceAttributes(self, visit, arg);
|
||||
int err = _PyObject_VisitManagedDict(self, visit, arg);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->tp_dictoffset != base->tp_dictoffset) {
|
||||
PyObject **dictptr = _PyObject_DictPointer(self);
|
||||
else if (type->tp_dictoffset != base->tp_dictoffset) {
|
||||
PyObject **dictptr = _PyObject_ComputedDictPointer(self);
|
||||
if (dictptr && *dictptr)
|
||||
Py_VISIT(*dictptr);
|
||||
}
|
||||
|
|
@ -1379,10 +1377,10 @@ subtype_clear(PyObject *self)
|
|||
/* Clear the instance dict (if any), to break cycles involving only
|
||||
__dict__ slots (as in the case 'self.__dict__ is self'). */
|
||||
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
|
||||
_PyObject_ClearInstanceAttributes(self);
|
||||
_PyObject_ClearManagedDict(self);
|
||||
}
|
||||
if (type->tp_dictoffset != base->tp_dictoffset) {
|
||||
PyObject **dictptr = _PyObject_DictPointer(self);
|
||||
else if (type->tp_dictoffset != base->tp_dictoffset) {
|
||||
PyObject **dictptr = _PyObject_ComputedDictPointer(self);
|
||||
if (dictptr && *dictptr)
|
||||
Py_CLEAR(*dictptr);
|
||||
}
|
||||
|
|
@ -1526,18 +1524,17 @@ subtype_dealloc(PyObject *self)
|
|||
|
||||
/* If we added a dict, DECREF it, or free inline values. */
|
||||
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
|
||||
PyObject **dictptr = _PyObject_ManagedDictPointer(self);
|
||||
if (*dictptr != NULL) {
|
||||
assert(*_PyObject_ValuesPointer(self) == NULL);
|
||||
Py_DECREF(*dictptr);
|
||||
*dictptr = NULL;
|
||||
}
|
||||
else {
|
||||
PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(self);
|
||||
if (_PyDictOrValues_IsValues(*dorv_ptr)) {
|
||||
_PyObject_FreeInstanceAttributes(self);
|
||||
}
|
||||
else {
|
||||
Py_XDECREF(_PyDictOrValues_GetDict(*dorv_ptr));
|
||||
}
|
||||
dorv_ptr->values = NULL;
|
||||
}
|
||||
else if (type->tp_dictoffset && !base->tp_dictoffset) {
|
||||
PyObject **dictptr = _PyObject_DictPointer(self);
|
||||
PyObject **dictptr = _PyObject_ComputedDictPointer(self);
|
||||
if (dictptr != NULL) {
|
||||
PyObject *dict = *dictptr;
|
||||
if (dict != NULL) {
|
||||
|
|
@ -5137,7 +5134,9 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
|
|||
* so we must materialize the dictionary first. */
|
||||
assert((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == (newto->tp_flags & Py_TPFLAGS_MANAGED_DICT));
|
||||
_PyObject_GetDictPtr(self);
|
||||
if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && *_PyObject_ValuesPointer(self)) {
|
||||
if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT &&
|
||||
_PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self)))
|
||||
{
|
||||
/* Was unable to convert to dict */
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue