Commit 6075a822 authored by Christian Heimes's avatar Christian Heimes

Limit free list of method and builtin function objects to 256 entries each.

parent 45eda646
...@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1? ...@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
Core and builtins 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 - Patch #1953: Added ``sys._compact_freelists()`` and the C API functions
``PyInt_CompactFreeList`` and ``PyFloat_CompactFreeList`` ``PyInt_CompactFreeList`` and ``PyFloat_CompactFreeList``
to compact the internal free lists of pre-allocted ints and floats. to compact the internal free lists of pre-allocted ints and floats.
......
...@@ -4,10 +4,16 @@ ...@@ -4,10 +4,16 @@
#include "Python.h" #include "Python.h"
#include "structmember.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) \ #define TP_DESCR_GET(t) \
(PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL) (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
/* Forward */ /* Forward */
static PyObject *class_lookup(PyClassObject *, PyObject *, static PyObject *class_lookup(PyClassObject *, PyObject *,
PyClassObject **); PyClassObject **);
...@@ -2193,8 +2199,6 @@ PyTypeObject PyInstance_Type = { ...@@ -2193,8 +2199,6 @@ PyTypeObject PyInstance_Type = {
In case (b), im_self is NULL In case (b), im_self is NULL
*/ */
static PyMethodObject *free_list;
PyObject * PyObject *
PyMethod_New(PyObject *func, PyObject *self, PyObject *klass) PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
{ {
...@@ -2207,6 +2211,7 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *klass) ...@@ -2207,6 +2211,7 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
if (im != NULL) { if (im != NULL) {
free_list = (PyMethodObject *)(im->im_self); free_list = (PyMethodObject *)(im->im_self);
PyObject_INIT(im, &PyMethod_Type); PyObject_INIT(im, &PyMethod_Type);
numfree--;
} }
else { else {
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
...@@ -2332,8 +2337,14 @@ instancemethod_dealloc(register PyMethodObject *im) ...@@ -2332,8 +2337,14 @@ instancemethod_dealloc(register PyMethodObject *im)
Py_DECREF(im->im_func); Py_DECREF(im->im_func);
Py_XDECREF(im->im_self); Py_XDECREF(im->im_self);
Py_XDECREF(im->im_class); Py_XDECREF(im->im_class);
if (numfree < MAXFREELIST) {
im->im_self = (PyObject *)free_list; im->im_self = (PyObject *)free_list;
free_list = im; free_list = im;
numfree++;
}
else {
PyObject_GC_Del(im);
}
} }
static int static int
...@@ -2620,5 +2631,7 @@ PyMethod_Fini(void) ...@@ -2620,5 +2631,7 @@ PyMethod_Fini(void)
PyMethodObject *im = free_list; PyMethodObject *im = free_list;
free_list = (PyMethodObject *)(im->im_self); free_list = (PyMethodObject *)(im->im_self);
PyObject_GC_Del(im); PyObject_GC_Del(im);
numfree--;
} }
assert(numfree == 0);
} }
...@@ -4,7 +4,12 @@ ...@@ -4,7 +4,12 @@
#include "Python.h" #include "Python.h"
#include "structmember.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 PyCFunctionObject *free_list = NULL;
static int numfree = 0;
#define MAXFREELIST 256
PyObject * PyObject *
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
...@@ -14,6 +19,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) ...@@ -14,6 +19,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
if (op != NULL) { if (op != NULL) {
free_list = (PyCFunctionObject *)(op->m_self); free_list = (PyCFunctionObject *)(op->m_self);
PyObject_INIT(op, &PyCFunction_Type); PyObject_INIT(op, &PyCFunction_Type);
numfree--;
} }
else { else {
op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type); op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
...@@ -125,8 +131,14 @@ meth_dealloc(PyCFunctionObject *m) ...@@ -125,8 +131,14 @@ meth_dealloc(PyCFunctionObject *m)
_PyObject_GC_UNTRACK(m); _PyObject_GC_UNTRACK(m);
Py_XDECREF(m->m_self); Py_XDECREF(m->m_self);
Py_XDECREF(m->m_module); Py_XDECREF(m->m_module);
if (numfree < MAXFREELIST) {
m->m_self = (PyObject *)free_list; m->m_self = (PyObject *)free_list;
free_list = m; free_list = m;
numfree++;
}
else {
PyObject_GC_Del(m);
}
} }
static PyObject * static PyObject *
...@@ -346,7 +358,9 @@ PyCFunction_Fini(void) ...@@ -346,7 +358,9 @@ PyCFunction_Fini(void)
PyCFunctionObject *v = free_list; PyCFunctionObject *v = free_list;
free_list = (PyCFunctionObject *)(v->m_self); free_list = (PyCFunctionObject *)(v->m_self);
PyObject_GC_Del(v); PyObject_GC_Del(v);
numfree--;
} }
assert(numfree == 0);
} }
/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(), /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment