bpo-45947: Place dict and values pointer at fixed (negative) offset just before GC header. (GH-29879)

* Place __dict__ immediately before GC header for plain Python objects.

* Fix up lazy dict creation logic to use managed dict pointers.

* Manage values pointer, placing them directly before managed dict pointers.

* Convert hint-based load/store attr specialization target managed dict classes.

* Specialize LOAD_METHOD for managed dict objects.

* Remove unsafe _PyObject_GC_Calloc function.

* Remove unsafe _PyObject_GC_Malloc() function.

* Add comment explaning use of Py_TPFLAGS_MANAGED_DICT.
This commit is contained in:
Mark Shannon 2021-12-07 16:02:53 +00:00 committed by GitHub
parent c7e7a4b969
commit 8319114fee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 260 additions and 285 deletions

View file

@ -83,7 +83,8 @@ def _sizeof_void_p():
# value computed later, see PyUnicodeObjectPtr.proxy()
_is_pep393 = None
Py_TPFLAGS_HEAPTYPE = (1 << 9)
Py_TPFLAGS_MANAGED_DICT = (1 << 4)
Py_TPFLAGS_HEAPTYPE = (1 << 9)
Py_TPFLAGS_LONG_SUBCLASS = (1 << 24)
Py_TPFLAGS_LIST_SUBCLASS = (1 << 25)
Py_TPFLAGS_TUPLE_SUBCLASS = (1 << 26)
@ -507,7 +508,6 @@ class HeapTypeObjectPtr(PyObjectPtr):
tsize = -tsize
size = _PyObject_VAR_SIZE(typeobj, tsize)
dictoffset += size
assert dictoffset > 0
assert dictoffset % _sizeof_void_p() == 0
dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
@ -523,12 +523,11 @@ class HeapTypeObjectPtr(PyObjectPtr):
def get_keys_values(self):
typeobj = self.type()
values_offset = int_from_int(typeobj.field('tp_inline_values_offset'))
if values_offset == 0:
has_values = int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT
if not has_values:
return None
charptr = self._gdbval.cast(_type_char_ptr()) + values_offset
PyDictValuesPtrPtr = gdb.lookup_type("PyDictValues").pointer().pointer()
valuesptr = charptr.cast(PyDictValuesPtrPtr)
valuesptr = self._gdbval.cast(PyDictValuesPtrPtr) - 4
values = valuesptr.dereference()
if long(values) == 0:
return None