mirror of
https://github.com/python/cpython.git
synced 2025-08-01 15:43:13 +00:00
Limit free list of method and builtin function objects to 256 entries each.
This commit is contained in:
parent
45eda64691
commit
6075a82243
3 changed files with 38 additions and 8 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue