mirror of
https://github.com/python/cpython.git
synced 2025-08-25 03:04:55 +00:00
gh-112529: Remove PyGC_Head from object pre-header in free-threaded build (#114564)
* gh-112529: Remove PyGC_Head from object pre-header in free-threaded build This avoids allocating space for PyGC_Head in the free-threaded build. The GC implementation for free-threaded CPython does not use the PyGC_Head structure. * The trashcan mechanism uses the `ob_tid` field instead of `_gc_prev` in the free-threaded build. * The GDB libpython.py file now determines the offset of the managed dict field based on whether the running process is a free-threaded build. Those are identified by the `ob_ref_local` field in PyObject. * Fixes `_PySys_GetSizeOf()` which incorrectly incorrectly included the size of `PyGC_Head` in the size of static `PyTypeObject`.
This commit is contained in:
parent
500ede0117
commit
587d480203
9 changed files with 86 additions and 26 deletions
|
@ -70,6 +70,14 @@ def _type_unsigned_int_ptr():
|
|||
def _sizeof_void_p():
|
||||
return gdb.lookup_type('void').pointer().sizeof
|
||||
|
||||
def _managed_dict_offset():
|
||||
# See pycore_object.h
|
||||
pyobj = gdb.lookup_type("PyObject")
|
||||
if any(field.name == "ob_ref_local" for field in pyobj.fields()):
|
||||
return -1 * _sizeof_void_p()
|
||||
else:
|
||||
return -3 * _sizeof_void_p()
|
||||
|
||||
|
||||
Py_TPFLAGS_MANAGED_DICT = (1 << 4)
|
||||
Py_TPFLAGS_HEAPTYPE = (1 << 9)
|
||||
|
@ -457,7 +465,7 @@ class HeapTypeObjectPtr(PyObjectPtr):
|
|||
if dictoffset < 0:
|
||||
if int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT:
|
||||
assert dictoffset == -1
|
||||
dictoffset = -3 * _sizeof_void_p()
|
||||
dictoffset = _managed_dict_offset()
|
||||
else:
|
||||
type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer()
|
||||
tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
|
||||
|
@ -485,9 +493,8 @@ class HeapTypeObjectPtr(PyObjectPtr):
|
|||
has_values = int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT
|
||||
if not has_values:
|
||||
return None
|
||||
charptrptr_t = _type_char_ptr().pointer()
|
||||
ptr = self._gdbval.cast(charptrptr_t) - 3
|
||||
char_ptr = ptr.dereference()
|
||||
ptr = self._gdbval.cast(_type_char_ptr()) + _managed_dict_offset()
|
||||
char_ptr = ptr.cast(_type_char_ptr().pointer()).dereference()
|
||||
if (int(char_ptr) & 1) == 0:
|
||||
return None
|
||||
char_ptr += 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue