summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorPieter Eendebak <pieter.eendebak@gmail.com>2024-12-26 15:17:22 (GMT)
committerGitHub <noreply@github.com>2024-12-26 15:17:22 (GMT)
commit3bd7730bbda3e38db5920a7b8c95958ca90342bf (patch)
tree979f14790cdce58474c45e39d2575e7b1c5cdd03 /Objects
parentfb0b94223d481ca58b7c77332348d1ab2c9ab272 (diff)
downloadcpython-3bd7730bbda3e38db5920a7b8c95958ca90342bf.zip
cpython-3bd7730bbda3e38db5920a7b8c95958ca90342bf.tar.gz
cpython-3bd7730bbda3e38db5920a7b8c95958ca90342bf.tar.bz2
gh-126868: Add freelist for compact ints to `_PyLong_New` (#128181)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/longobject.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c
index bd7ff68..d449a01 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -156,7 +156,7 @@ PyLongObject *
_PyLong_New(Py_ssize_t size)
{
assert(size >= 0);
- PyLongObject *result;
+ PyLongObject *result = NULL;
if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
PyErr_SetString(PyExc_OverflowError,
"too many digits in integer");
@@ -165,19 +165,25 @@ _PyLong_New(Py_ssize_t size)
/* Fast operations for single digit integers (including zero)
* assume that there is always at least one digit present. */
Py_ssize_t ndigits = size ? size : 1;
- /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
- sizeof(digit)*size. Previous incarnations of this code used
- sizeof() instead of the offsetof, but this risks being
- incorrect in the presence of padding between the header
- and the digits. */
- result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
- ndigits*sizeof(digit));
- if (!result) {
- PyErr_NoMemory();
- return NULL;
+
+ if (ndigits == 1) {
+ result = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints);
+ }
+ if (result == NULL) {
+ /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
+ sizeof(digit)*size. Previous incarnations of this code used
+ sizeof() instead of the offsetof, but this risks being
+ incorrect in the presence of padding between the header
+ and the digits. */
+ result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
+ ndigits*sizeof(digit));
+ if (!result) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ _PyObject_Init((PyObject*)result, &PyLong_Type);
}
_PyLong_SetSignAndDigitCount(result, size != 0, size);
- _PyObject_Init((PyObject*)result, &PyLong_Type);
/* The digit has to be initialized explicitly to avoid
* use-of-uninitialized-value. */
result->long_value.ob_digit[0] = 0;