Skip to content

Commit

Permalink
gh-126868: Add freelist for compact ints to _PyLong_New (#128181)
Browse files Browse the repository at this point in the history
Co-authored-by: Kumar Aditya <[email protected]>
  • Loading branch information
eendebakpt and kumaraditya303 authored Dec 26, 2024
1 parent fb0b942 commit 3bd7730
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Increase usage of freelist for :class:`int` allocation.
30 changes: 18 additions & 12 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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;
Expand Down

0 comments on commit 3bd7730

Please sign in to comment.