]> granicus.if.org Git - python/commitdiff
Limit free list of method and builtin function objects to 256 entries each.
authorChristian Heimes <christian@cheimes.de>
Wed, 6 Feb 2008 12:44:34 +0000 (12:44 +0000)
committerChristian Heimes <christian@cheimes.de>
Wed, 6 Feb 2008 12:44:34 +0000 (12:44 +0000)
Misc/NEWS
Objects/classobject.c
Objects/methodobject.c

index 7bb43e1f5685207acfc4f620c29b600d8d998d3e..51eca005af53003d6da4aa9fd7a16a09b2fa2861 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
 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.
index 9f364e2e88a6ec983590a51fd84e209b9d5e5f2e..a9e8c6a9ea5dcfad35591311df8f6f4063aea286 100644 (file)
@@ -4,10 +4,16 @@
 #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 **);
@@ -2193,8 +2199,6 @@ PyTypeObject PyInstance_Type = {
    In case (b), im_self is NULL
 */
 
-static PyMethodObject *free_list;
-
 PyObject *
 PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
 {
@@ -2207,6 +2211,7 @@ 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);
@@ -2332,8 +2337,14 @@ instancemethod_dealloc(register PyMethodObject *im)
        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
@@ -2620,5 +2631,7 @@ PyMethod_Fini(void)
                PyMethodObject *im = free_list;
                free_list = (PyMethodObject *)(im->im_self);
                PyObject_GC_Del(im);
+               numfree--;
        }
+       assert(numfree == 0);
 }
index 3daa9dd70df604986dac085a7b8f479b5f9a714a..17e905be4b9900e964760958558cc96780672868 100644 (file)
@@ -4,7 +4,12 @@
 #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)
@@ -14,6 +19,7 @@ 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);
@@ -125,8 +131,14 @@ meth_dealloc(PyCFunctionObject *m)
        _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 *
@@ -346,14 +358,16 @@ PyCFunction_Fini(void)
                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 *);