@@ -113,6 +113,15 @@ long_normalize(PyLongObject *v)
113113#define MAX_LONG_DIGITS \
114114 ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit))
115115
116+ union _small_object {
117+ PyFloatObject f ;
118+ PyLongObject l ;
119+ };
120+
121+ /* Free list is shared between ints and floats as they take the same amount of memory (on most platforms)
122+ */
123+ #define MAX_DIGITS_FOR_FREELIST ((sizeof(union _small_object) - offsetof(PyLongObject, ob_digit))/sizeof(digit))
124+
116125PyLongObject *
117126_PyLong_New (Py_ssize_t size )
118127{
@@ -122,16 +131,23 @@ _PyLong_New(Py_ssize_t size)
122131 "too many digits in integer" );
123132 return NULL ;
124133 }
125- /* Fast operations for single digit integers (including zero)
126- * assume that there is always at least one digit present. */
127- Py_ssize_t ndigits = size ? size : 1 ;
128- /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
129- sizeof(digit)*size. Previous incarnations of this code used
130- sizeof(PyVarObject) instead of the offsetof, but this risks being
131- incorrect in the presence of padding between the PyVarObject header
132- and the digits. */
133- result = PyObject_Malloc (offsetof(PyLongObject , ob_digit ) +
134- ndigits * sizeof (digit ));
134+ #if WITH_FREELISTS
135+ if (size <= MAX_DIGITS_FOR_FREELIST ) {
136+ result = (PyLongObject * )_PyFreeList_Alloc (& _Py_small_object_freelist );
137+ #else
138+ if (size == 0 ) {
139+ result = PyObject_Malloc (sizeof (PyLongObject ));
140+ #endif
141+ }
142+ else {
143+ /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
144+ sizeof(digit)*size. Previous incarnations of this code used
145+ sizeof(PyVarObject) instead of the offsetof, but this risks being
146+ incorrect in the presence of padding between the PyVarObject header
147+ and the digits. */
148+ result = PyObject_Malloc (offsetof(PyLongObject , ob_digit ) +
149+ size * sizeof (digit ));
150+ }
135151 if (!result ) {
136152 PyErr_NoMemory ();
137153 return NULL ;
0 commit comments