diff options
author | Sam Gross <colesbury@gmail.com> | 2024-02-01 20:29:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-01 20:29:19 (GMT) |
commit | 587d4802034749e2aace9c00b00bd73eccdae1e7 (patch) | |
tree | ba760dcffd508c28bb8ed42930bd7fba009dd38a /Tools | |
parent | 500ede01178a8063bb2a3c664172dffa1b40d7c9 (diff) | |
download | cpython-587d4802034749e2aace9c00b00bd73eccdae1e7.zip cpython-587d4802034749e2aace9c00b00bd73eccdae1e7.tar.gz cpython-587d4802034749e2aace9c00b00bd73eccdae1e7.tar.bz2 |
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`.
Diffstat (limited to 'Tools')
-rwxr-xr-x | Tools/gdb/libpython.py | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 5ef5552..483f28b 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -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 |