diff options
author | Pieter Eendebak <pieter.eendebak@gmail.com> | 2024-12-26 15:17:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-26 15:17:22 (GMT) |
commit | 3bd7730bbda3e38db5920a7b8c95958ca90342bf (patch) | |
tree | 979f14790cdce58474c45e39d2575e7b1c5cdd03 /Objects | |
parent | fb0b94223d481ca58b7c77332348d1ab2c9ab272 (diff) | |
download | cpython-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.c | 30 |
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; |