From 1fc2b38d63170dd065efc2bc60e861f32c033b17 Mon Sep 17 00:00:00 2001 From: Mazin Sharaf Date: Sun, 3 May 2026 13:03:13 +1000 Subject: [PATCH] GH-148189: Fix miscalculation of type-specific free list memory use (#148190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix calculation of PyListObject size in allocator * Fix size calculation in _PyDict_DebugMallocStats * Fix memory size calculation in tupleobject.c Adjusted memory calculation for PyTupleObject freelist entries. * Revert in tupleobject.c Removed unnecessary comment regarding memory calculation and the memory calculation itself. * 📜🤖 Added by blurb_it. * Update tupleobject.c --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- .../2026-04-08-02-49-07.gh-issue-148189.0KpXID.rst | 1 + Objects/dictobject.c | 2 +- Objects/listobject.c | 2 +- Objects/tupleobject.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-08-02-49-07.gh-issue-148189.0KpXID.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-08-02-49-07.gh-issue-148189.0KpXID.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-08-02-49-07.gh-issue-148189.0KpXID.rst new file mode 100644 index 00000000000..d90e30b3d3f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-08-02-49-07.gh-issue-148189.0KpXID.rst @@ -0,0 +1 @@ +Repaired undercount of bytes in type-specific free lists reported by sys._debugmallocstats(). For types that participate in cyclic garbage collection, it was missing two pointers used by GC. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 09db93b2d31..5be5baf8fc4 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -443,7 +443,7 @@ _PyDict_DebugMallocStats(FILE *out) { _PyDebugAllocatorStats(out, "free PyDictObject", _Py_FREELIST_SIZE(dicts), - sizeof(PyDictObject)); + _PyType_PreHeaderSize(&PyDict_Type) + sizeof(PyDictObject)); _PyDebugAllocatorStats(out, "free PyDictKeysObject", _Py_FREELIST_SIZE(dictkeys), sizeof(PyDictKeysObject)); diff --git a/Objects/listobject.c b/Objects/listobject.c index 685b30bb9ee..10e25bbdcdc 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -234,7 +234,7 @@ _PyList_DebugMallocStats(FILE *out) _PyDebugAllocatorStats(out, "free PyListObject", _Py_FREELIST_SIZE(lists), - sizeof(PyListObject)); + _PyType_PreHeaderSize(&PyList_Type) + sizeof(PyListObject)); } PyObject * diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 7757a102677..753c270f525 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -1286,6 +1286,6 @@ _PyTuple_DebugMallocStats(FILE *out) PyOS_snprintf(buf, sizeof(buf), "free %d-sized PyTupleObject", len); _PyDebugAllocatorStats(out, buf, _Py_FREELIST_SIZE(tuples[i]), - _PyObject_VAR_SIZE(&PyTuple_Type, len)); + _PyType_PreHeaderSize(&PyTuple_Type) + _PyObject_VAR_SIZE(&PyTuple_Type, len)); } }