Core and builtins
-----------------
+- Limit free list of method and builtin function objects to 256 entries
+ each.
+
- Patch #1953: Added ``sys._compact_freelists()`` and the C API functions
``PyInt_CompactFreeList`` and ``PyFloat_CompactFreeList``
to compact the internal free lists of pre-allocted ints and floats.
#include "Python.h"
#include "structmember.h"
+/* Free list for method objects to safe malloc/free overhead
+ * The im_self element is used to chain the elements.
+ */
+static PyMethodObject *free_list;
+static int numfree = 0;
+#define MAXFREELIST 256
+
#define TP_DESCR_GET(t) \
(PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
-
/* Forward */
static PyObject *class_lookup(PyClassObject *, PyObject *,
PyClassObject **);
In case (b), im_self is NULL
*/
-static PyMethodObject *free_list;
-
PyObject *
PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
{
if (im != NULL) {
free_list = (PyMethodObject *)(im->im_self);
PyObject_INIT(im, &PyMethod_Type);
+ numfree--;
}
else {
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
Py_DECREF(im->im_func);
Py_XDECREF(im->im_self);
Py_XDECREF(im->im_class);
- im->im_self = (PyObject *)free_list;
- free_list = im;
+ if (numfree < MAXFREELIST) {
+ im->im_self = (PyObject *)free_list;
+ free_list = im;
+ numfree++;
+ }
+ else {
+ PyObject_GC_Del(im);
+ }
}
static int
PyMethodObject *im = free_list;
free_list = (PyMethodObject *)(im->im_self);
PyObject_GC_Del(im);
+ numfree--;
}
+ assert(numfree == 0);
}
#include "Python.h"
#include "structmember.h"
+/* Free list for method objects to safe malloc/free overhead
+ * The m_self element is used to chain the objects.
+ */
static PyCFunctionObject *free_list = NULL;
+static int numfree = 0;
+#define MAXFREELIST 256
PyObject *
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
if (op != NULL) {
free_list = (PyCFunctionObject *)(op->m_self);
PyObject_INIT(op, &PyCFunction_Type);
+ numfree--;
}
else {
op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
_PyObject_GC_UNTRACK(m);
Py_XDECREF(m->m_self);
Py_XDECREF(m->m_module);
- m->m_self = (PyObject *)free_list;
- free_list = m;
+ if (numfree < MAXFREELIST) {
+ m->m_self = (PyObject *)free_list;
+ free_list = m;
+ numfree++;
+ }
+ else {
+ PyObject_GC_Del(m);
+ }
}
static PyObject *
PyCFunctionObject *v = free_list;
free_list = (PyCFunctionObject *)(v->m_self);
PyObject_GC_Del(v);
+ numfree--;
}
+ assert(numfree == 0);
}
/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
but it's part of the API so we need to keep a function around that
existing C extensions can call.
*/
-
+
#undef PyCFunction_New
PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);