Skip to content

Commit 3bd7730

Browse files
gh-126868: Add freelist for compact ints to _PyLong_New (#128181)
Co-authored-by: Kumar Aditya <[email protected]>
1 parent fb0b942 commit 3bd7730

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Increase usage of freelist for :class:`int` allocation.

Objects/longobject.c

+18-12
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ PyLongObject *
156156
_PyLong_New(Py_ssize_t size)
157157
{
158158
assert(size >= 0);
159-
PyLongObject *result;
159+
PyLongObject *result = NULL;
160160
if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
161161
PyErr_SetString(PyExc_OverflowError,
162162
"too many digits in integer");
@@ -165,19 +165,25 @@ _PyLong_New(Py_ssize_t size)
165165
/* Fast operations for single digit integers (including zero)
166166
* assume that there is always at least one digit present. */
167167
Py_ssize_t ndigits = size ? size : 1;
168-
/* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
169-
sizeof(digit)*size. Previous incarnations of this code used
170-
sizeof() instead of the offsetof, but this risks being
171-
incorrect in the presence of padding between the header
172-
and the digits. */
173-
result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
174-
ndigits*sizeof(digit));
175-
if (!result) {
176-
PyErr_NoMemory();
177-
return NULL;
168+
169+
if (ndigits == 1) {
170+
result = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints);
171+
}
172+
if (result == NULL) {
173+
/* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
174+
sizeof(digit)*size. Previous incarnations of this code used
175+
sizeof() instead of the offsetof, but this risks being
176+
incorrect in the presence of padding between the header
177+
and the digits. */
178+
result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
179+
ndigits*sizeof(digit));
180+
if (!result) {
181+
PyErr_NoMemory();
182+
return NULL;
183+
}
184+
_PyObject_Init((PyObject*)result, &PyLong_Type);
178185
}
179186
_PyLong_SetSignAndDigitCount(result, size != 0, size);
180-
_PyObject_Init((PyObject*)result, &PyLong_Type);
181187
/* The digit has to be initialized explicitly to avoid
182188
* use-of-uninitialized-value. */
183189
result->long_value.ob_digit[0] = 0;

0 commit comments

Comments
 (0)