Skip to content

Commit ef0485b

Browse files
author
christian.heimes
committed
Limit free list of method and builtin function objects to 256 entries each.
git-svn-id: http://svn.python.org/projects/python/trunk@60614 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent ba933f4 commit ef0485b

3 files changed

Lines changed: 38 additions & 8 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
1212
Core and builtins
1313
-----------------
1414

15+
- Limit free list of method and builtin function objects to 256 entries
16+
each.
17+
1518
- Patch #1953: Added ``sys._compact_freelists()`` and the C API functions
1619
``PyInt_CompactFreeList`` and ``PyFloat_CompactFreeList``
1720
to compact the internal free lists of pre-allocted ints and floats.

Objects/classobject.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@
44
#include "Python.h"
55
#include "structmember.h"
66

7+
/* Free list for method objects to safe malloc/free overhead
8+
* The im_self element is used to chain the elements.
9+
*/
10+
static PyMethodObject *free_list;
11+
static int numfree = 0;
12+
#define MAXFREELIST 256
13+
714
#define TP_DESCR_GET(t) \
815
(PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
916

10-
1117
/* Forward */
1218
static PyObject *class_lookup(PyClassObject *, PyObject *,
1319
PyClassObject **);
@@ -2193,8 +2199,6 @@ PyTypeObject PyInstance_Type = {
21932199
In case (b), im_self is NULL
21942200
*/
21952201

2196-
static PyMethodObject *free_list;
2197-
21982202
PyObject *
21992203
PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
22002204
{
@@ -2207,6 +2211,7 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
22072211
if (im != NULL) {
22082212
free_list = (PyMethodObject *)(im->im_self);
22092213
PyObject_INIT(im, &PyMethod_Type);
2214+
numfree--;
22102215
}
22112216
else {
22122217
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
@@ -2332,8 +2337,14 @@ instancemethod_dealloc(register PyMethodObject *im)
23322337
Py_DECREF(im->im_func);
23332338
Py_XDECREF(im->im_self);
23342339
Py_XDECREF(im->im_class);
2335-
im->im_self = (PyObject *)free_list;
2336-
free_list = im;
2340+
if (numfree < MAXFREELIST) {
2341+
im->im_self = (PyObject *)free_list;
2342+
free_list = im;
2343+
numfree++;
2344+
}
2345+
else {
2346+
PyObject_GC_Del(im);
2347+
}
23372348
}
23382349

23392350
static int
@@ -2620,5 +2631,7 @@ PyMethod_Fini(void)
26202631
PyMethodObject *im = free_list;
26212632
free_list = (PyMethodObject *)(im->im_self);
26222633
PyObject_GC_Del(im);
2634+
numfree--;
26232635
}
2636+
assert(numfree == 0);
26242637
}

Objects/methodobject.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
#include "Python.h"
55
#include "structmember.h"
66

7+
/* Free list for method objects to safe malloc/free overhead
8+
* The m_self element is used to chain the objects.
9+
*/
710
static PyCFunctionObject *free_list = NULL;
11+
static int numfree = 0;
12+
#define MAXFREELIST 256
813

914
PyObject *
1015
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
@@ -14,6 +19,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
1419
if (op != NULL) {
1520
free_list = (PyCFunctionObject *)(op->m_self);
1621
PyObject_INIT(op, &PyCFunction_Type);
22+
numfree--;
1723
}
1824
else {
1925
op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
@@ -125,8 +131,14 @@ meth_dealloc(PyCFunctionObject *m)
125131
_PyObject_GC_UNTRACK(m);
126132
Py_XDECREF(m->m_self);
127133
Py_XDECREF(m->m_module);
128-
m->m_self = (PyObject *)free_list;
129-
free_list = m;
134+
if (numfree < MAXFREELIST) {
135+
m->m_self = (PyObject *)free_list;
136+
free_list = m;
137+
numfree++;
138+
}
139+
else {
140+
PyObject_GC_Del(m);
141+
}
130142
}
131143

132144
static PyObject *
@@ -346,14 +358,16 @@ PyCFunction_Fini(void)
346358
PyCFunctionObject *v = free_list;
347359
free_list = (PyCFunctionObject *)(v->m_self);
348360
PyObject_GC_Del(v);
361+
numfree--;
349362
}
363+
assert(numfree == 0);
350364
}
351365

352366
/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
353367
but it's part of the API so we need to keep a function around that
354368
existing C extensions can call.
355369
*/
356-
370+
357371
#undef PyCFunction_New
358372
PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
359373

0 commit comments

Comments
 (0)