From 8a6af5a34642f5564220eb50d72caada8f17fc78 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 19 May 2022 08:43:50 +0300 Subject: gh-92914: Round the allocated size for lists up to the even number (GH-92915) --- Lib/test/test_sys.py | 7 ++++--- .../2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst | 1 + Objects/listobject.c | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 9c0f4a6..94a09ff 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1432,9 +1432,10 @@ class SizeofTest(unittest.TestCase): import re check(re.finditer('',''), size('2P')) # list - samples = [[], [1,2,3], ['1', '2', '3']] - for sample in samples: - check(list(sample), vsize('Pn') + len(sample)*self.P) + check(list([]), vsize('Pn')) + check(list([1]), vsize('Pn') + 2*self.P) + check(list([1, 2]), vsize('Pn') + 2*self.P) + check(list([1, 2, 3]), vsize('Pn') + 4*self.P) # sortwrapper (list) # XXX # cmpwrapper (list) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst new file mode 100644 index 0000000..1242a15 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst @@ -0,0 +1 @@ +Always round the allocated size for lists up to the nearest even number. diff --git a/Objects/listobject.c b/Objects/listobject.c index b50623e..0a99ec9 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -94,6 +94,12 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) assert(self->ob_item == NULL); assert(size > 0); + /* Since the Python memory allocator has granularity of 16 bytes on 64-bit + * platforms (8 on 32-bit), there is no benefit of allocating space for + * the odd number of items, and there is no drawback of rounding the + * allocated size up to the nearest even number. + */ + size = (size + 1) & ~(size_t)1; PyObject **items = PyMem_New(PyObject*, size); if (items == NULL) { PyErr_NoMemory(); -- cgit v0.12