summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-02-01 20:29:19 (GMT)
committerGitHub <noreply@github.com>2024-02-01 20:29:19 (GMT)
commit587d4802034749e2aace9c00b00bd73eccdae1e7 (patch)
treeba760dcffd508c28bb8ed42930bd7fba009dd38a /Tools
parent500ede01178a8063bb2a3c664172dffa1b40d7c9 (diff)
downloadcpython-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-xTools/gdb/libpython.py15
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