summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2022-05-19 05:43:50 (GMT)
committerGitHub <noreply@github.com>2022-05-19 05:43:50 (GMT)
commit8a6af5a34642f5564220eb50d72caada8f17fc78 (patch)
tree79595d9287532adcd7bb6c7a63950a0ca9e10dca
parent96f65835f8f66d058b444e0b4e436af45e2902f7 (diff)
downloadcpython-8a6af5a34642f5564220eb50d72caada8f17fc78.zip
cpython-8a6af5a34642f5564220eb50d72caada8f17fc78.tar.gz
cpython-8a6af5a34642f5564220eb50d72caada8f17fc78.tar.bz2
gh-92914: Round the allocated size for lists up to the even number (GH-92915)
-rw-r--r--Lib/test/test_sys.py7
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst1
-rw-r--r--Objects/listobject.c6
3 files changed, 11 insertions, 3 deletions
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();