diff -r 37bacf3fa1f5 Doc/c-api/long.rst --- a/Doc/c-api/long.rst Thu Feb 11 10:26:27 2016 -0500 +++ b/Doc/c-api/long.rst Thu Feb 11 14:12:46 2016 -0500 @@ -260,3 +260,9 @@ If *pylong* cannot be converted, an :exc:`OverflowError` will be raised. This is only assured to produce a usable :c:type:`void` pointer for values created with :c:func:`PyLong_FromVoidPtr`. + + +.. c:function:: int PyLong_ClearFreeList() + + Clear the long free list. Return the number of items that could not + be freed. diff -r 37bacf3fa1f5 Include/longobject.h --- a/Include/longobject.h Thu Feb 11 10:26:27 2016 -0500 +++ b/Include/longobject.h Thu Feb 11 14:12:46 2016 -0500 @@ -28,6 +28,7 @@ PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); +PyAPI_FUNC(int) PyLong_ClearFreeList(void); #endif PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); diff -r 37bacf3fa1f5 Modules/gcmodule.c --- a/Modules/gcmodule.c Thu Feb 11 10:26:27 2016 -0500 +++ b/Modules/gcmodule.c Thu Feb 11 14:12:46 2016 -0500 @@ -889,6 +889,7 @@ (void)PyTuple_ClearFreeList(); (void)PyUnicode_ClearFreeList(); (void)PyFloat_ClearFreeList(); + (void)PyLong_ClearFreeList(); (void)PyList_ClearFreeList(); (void)PyDict_ClearFreeList(); (void)PySet_ClearFreeList(); diff -r 37bacf3fa1f5 Objects/longobject.c --- a/Objects/longobject.c Thu Feb 11 10:26:27 2016 -0500 +++ b/Objects/longobject.c Thu Feb 11 14:12:46 2016 -0500 @@ -9,6 +9,13 @@ #include #include + +/* Free-list for single-digit longs. */ +#define PyLong_MAXFREELIST 200 +static PyLongObject *free_list[PyLong_MAXFREELIST]; +static int numfree = 0; + + #ifndef NSMALLPOSINTS #define NSMALLPOSINTS 257 #endif @@ -183,6 +190,17 @@ _PyLong_New(Py_ssize_t size) { PyLongObject *result; + + if (size == 1 && numfree) { + result = free_list[--numfree]; + assert(result != NULL); + assert(PyLong_CheckExact(result)); + assert(Py_ABS(Py_SIZE(result)) == 1); + Py_SIZE(result) = 1; + _Py_NewReference((PyObject *)result); + return result; + } + /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + sizeof(digit)*size. Previous incarnations of this code used sizeof(PyVarObject) instead of the offsetof, but this risks being @@ -2790,7 +2808,17 @@ static void long_dealloc(PyObject *v) { - Py_TYPE(v)->tp_free(v); + if (PyLong_CheckExact(v) && Py_ABS(Py_SIZE(v)) == 1) { + if (numfree < PyLong_MAXFREELIST) { + free_list[numfree++] = (PyLongObject*)v; + } + else { + PyObject_FREE(v); + } + } + else { + Py_TYPE(v)->tp_free(v); + } } static int @@ -5467,6 +5495,19 @@ return 1; } +int +PyLong_ClearFreeList(void) +{ + PyObject *o; + int ret = numfree; + while (numfree) { + o = (PyObject*) free_list[--numfree]; + assert(PyLong_CheckExact(o)); + PyObject_FREE(o); + } + return ret; +} + void PyLong_Fini(void) { @@ -5481,4 +5522,6 @@ _Py_ForgetReference((PyObject*)v); } #endif + + (void)PyLong_ClearFreeList(); }