summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/classobject.c24
-rw-r--r--Objects/dictobject.c16
-rw-r--r--Objects/frameobject.c7
-rw-r--r--Objects/listobject.c24
-rw-r--r--Objects/methodobject.c22
-rw-r--r--Objects/setobject.c22
-rw-r--r--Objects/tupleobject.c58
-rw-r--r--Objects/unicodeobject.c36
8 files changed, 124 insertions, 85 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index d9f7219..be7ba2d 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -5,6 +5,15 @@
#define TP_DESCR_GET(t) ((t)->tp_descr_get)
+/* 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;
+#ifndef PyMethod_MAXFREELIST
+#define PyMethod_MAXFREELIST 256
+#endif
+
PyObject *
PyMethod_Function(PyObject *im)
{
@@ -30,8 +39,6 @@ PyMethod_Self(PyObject *im)
function.
*/
-static PyMethodObject *free_list;
-
PyObject *
PyMethod_New(PyObject *func, PyObject *self)
{
@@ -48,6 +55,7 @@ PyMethod_New(PyObject *func, PyObject *self)
if (im != NULL) {
free_list = (PyMethodObject *)(im->im_self);
PyObject_INIT(im, &PyMethod_Type);
+ numfree--;
}
else {
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
@@ -165,8 +173,14 @@ method_dealloc(register PyMethodObject *im)
PyObject_ClearWeakRefs((PyObject *)im);
Py_DECREF(im->im_func);
Py_XDECREF(im->im_self);
- im->im_self = (PyObject *)free_list;
- free_list = im;
+ if (numfree < PyMethod_MAXFREELIST) {
+ im->im_self = (PyObject *)free_list;
+ free_list = im;
+ numfree++;
+ }
+ else {
+ PyObject_GC_Del(im);
+ }
}
static PyObject *
@@ -375,7 +389,9 @@ PyMethod_Fini(void)
PyMethodObject *im = free_list;
free_list = (PyMethodObject *)(im->im_self);
PyObject_GC_Del(im);
+ numfree--;
}
+ assert(numfree == 0);
}
/* ------------------------------------------------------------------------
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 6a1938e..1bc7184 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -184,9 +184,11 @@ show_counts(void)
} while(0)
/* Dictionary reuse scheme to save calls to malloc, free, and memset */
-#define MAXFREEDICTS 80
-static PyDictObject *free_dicts[MAXFREEDICTS];
-static int num_free_dicts = 0;
+#ifndef PyDict_MAXFREELIST
+#define PyDict_MAXFREELIST 80
+#endif
+static PyDictObject *free_list[PyDict_MAXFREELIST];
+static int numfree = 0;
PyObject *
PyDict_New(void)
@@ -200,8 +202,8 @@ PyDict_New(void)
Py_AtExit(show_counts);
#endif
}
- if (num_free_dicts) {
- mp = free_dicts[--num_free_dicts];
+ if (numfree) {
+ mp = free_list[--numfree];
assert (mp != NULL);
assert (Py_TYPE(mp) == &PyDict_Type);
_Py_NewReference((PyObject *)mp);
@@ -897,8 +899,8 @@ dict_dealloc(register PyDictObject *mp)
}
if (mp->ma_table != mp->ma_smalltable)
PyMem_DEL(mp->ma_table);
- if (num_free_dicts < MAXFREEDICTS && Py_TYPE(mp) == &PyDict_Type)
- free_dicts[num_free_dicts++] = mp;
+ if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
+ free_list[numfree++] = mp;
else
Py_TYPE(mp)->tp_free((PyObject *)mp);
Py_TRASHCAN_SAFE_END(mp)
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index deda244..658ce1d 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -401,14 +401,15 @@ static PyGetSetDef frame_getsetlist[] = {
call depth of more than 20 or 30 is probably already exceptional
unless the program contains run-away recursion. I hope.
- Later, MAXFREELIST was added to bound the # of frames saved on
+ Later, PyFrame_MAXFREELIST was added to bound the # of frames saved on
free_list. Else programs creating lots of cyclic trash involving
frames could provoke free_list into growing without bound.
*/
static PyFrameObject *free_list = NULL;
static int numfree = 0; /* number of frames currently in free_list */
-#define MAXFREELIST 200 /* max value for numfree */
+/* max value for numfree */
+#define PyFrame_MAXFREELIST 200
static void
frame_dealloc(PyFrameObject *f)
@@ -441,7 +442,7 @@ frame_dealloc(PyFrameObject *f)
co = f->f_code;
if (co->co_zombieframe == NULL)
co->co_zombieframe = f;
- else if (numfree < MAXFREELIST) {
+ else if (numfree < PyFrame_MAXFREELIST) {
++numfree;
f->f_back = free_list;
free_list = f;
diff --git a/Objects/listobject.c b/Objects/listobject.c
index a36a29e..cb0609a 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -64,18 +64,20 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
}
/* Empty list reuse scheme to save calls to malloc and free */
-#define MAXFREELISTS 80
-static PyListObject *free_lists[MAXFREELISTS];
-static int num_free_lists = 0;
+#ifndef PyList_MAXFREELIST
+#define PyList_MAXFREELIST 80
+#endif
+static PyListObject *free_list[PyList_MAXFREELIST];
+static int numfree = 0;
void
PyList_Fini(void)
{
PyListObject *op;
- while (num_free_lists) {
- num_free_lists--;
- op = free_lists[num_free_lists];
+ while (numfree) {
+ numfree--;
+ op = free_list[numfree];
assert(PyList_CheckExact(op));
PyObject_GC_Del(op);
}
@@ -95,9 +97,9 @@ PyList_New(Py_ssize_t size)
/* Check for overflow */
if (nbytes / sizeof(PyObject *) != (size_t)size)
return PyErr_NoMemory();
- if (num_free_lists) {
- num_free_lists--;
- op = free_lists[num_free_lists];
+ if (numfree) {
+ numfree--;
+ op = free_list[numfree];
_Py_NewReference((PyObject *)op);
} else {
op = PyObject_GC_New(PyListObject, &PyList_Type);
@@ -265,8 +267,8 @@ list_dealloc(PyListObject *op)
}
PyMem_FREE(op->ob_item);
}
- if (num_free_lists < MAXFREELISTS && PyList_CheckExact(op))
- free_lists[num_free_lists++] = op;
+ if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))
+ free_list[numfree++] = op;
else
Py_TYPE(op)->tp_free((PyObject *)op);
Py_TRASHCAN_SAFE_END(op)
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 73e0790..7a82d89 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -4,7 +4,14 @@
#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;
+#ifndef PyCFunction_MAXFREELIST
+#define PyCFunction_MAXFREELIST 256
+#endif
PyObject *
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
@@ -14,6 +21,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);
@@ -116,8 +124,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 < PyCFunction_MAXFREELIST) {
+ m->m_self = (PyObject *)free_list;
+ free_list = m;
+ numfree++;
+ }
+ else {
+ PyObject_GC_Del(m);
+ }
}
static PyObject *
@@ -312,14 +326,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 *);
diff --git a/Objects/setobject.c b/Objects/setobject.c
index c827434..fcc152a 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -52,9 +52,11 @@ _PySet_Dummy(void)
} while(0)
/* Reuse scheme to save calls to malloc, free, and memset */
-#define MAXFREESETS 80
-static PySetObject *free_sets[MAXFREESETS];
-static int num_free_sets = 0;
+#ifndef PySet_MAXFREELIST
+#define PySet_MAXFREELIST 80
+#endif
+static PySetObject *free_list[PySet_MAXFREELIST];
+static int numfree = 0;
/*
@@ -561,8 +563,8 @@ set_dealloc(PySetObject *so)
}
if (so->table != so->smalltable)
PyMem_DEL(so->table);
- if (num_free_sets < MAXFREESETS && PyAnySet_CheckExact(so))
- free_sets[num_free_sets++] = so;
+ if (numfree < PySet_MAXFREELIST && PyAnySet_CheckExact(so))
+ free_list[numfree++] = so;
else
Py_TYPE(so)->tp_free(so);
Py_TRASHCAN_SAFE_END(so)
@@ -975,9 +977,9 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
}
/* create PySetObject structure */
- if (num_free_sets &&
+ if (numfree &&
(type == &PySet_Type || type == &PyFrozenSet_Type)) {
- so = free_sets[--num_free_sets];
+ so = free_list[--numfree];
assert (so != NULL && PyAnySet_CheckExact(so));
Py_TYPE(so) = type;
_Py_NewReference((PyObject *)so);
@@ -1045,9 +1047,9 @@ PySet_Fini(void)
{
PySetObject *so;
- while (num_free_sets) {
- num_free_sets--;
- so = free_sets[num_free_sets];
+ while (numfree) {
+ numfree--;
+ so = free_list[numfree];
PyObject_GC_Del(so);
}
Py_CLEAR(dummy);
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index c9d91e5..c212345 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -4,19 +4,19 @@
#include "Python.h"
/* Speed optimization to avoid frequent malloc/free of small tuples */
-#ifndef MAXSAVESIZE
-#define MAXSAVESIZE 20 /* Largest tuple to save on free list */
+#ifndef PyTuple_MAXSAVESIZE
+#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
#endif
-#ifndef MAXSAVEDTUPLES
-#define MAXSAVEDTUPLES 2000 /* Maximum number of tuples of each size to save */
+#ifndef PyTuple_MAXFREELIST
+#define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */
#endif
-#if MAXSAVESIZE > 0
-/* Entries 1 up to MAXSAVESIZE are free lists, entry 0 is the empty
+#if PyTuple_MAXSAVESIZE > 0
+/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
tuple () of which at most one instance will be allocated.
*/
-static PyTupleObject *free_tuples[MAXSAVESIZE];
-static int num_free_tuples[MAXSAVESIZE];
+static PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
+static int numfree[PyTuple_MAXSAVESIZE];
#endif
#ifdef COUNT_ALLOCS
int fast_tuple_allocs;
@@ -32,18 +32,18 @@ PyTuple_New(register Py_ssize_t size)
PyErr_BadInternalCall();
return NULL;
}
-#if MAXSAVESIZE > 0
- if (size == 0 && free_tuples[0]) {
- op = free_tuples[0];
+#if PyTuple_MAXSAVESIZE > 0
+ if (size == 0 && free_list[0]) {
+ op = free_list[0];
Py_INCREF(op);
#ifdef COUNT_ALLOCS
tuple_zero_allocs++;
#endif
return (PyObject *) op;
}
- if (size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
- free_tuples[size] = (PyTupleObject *) op->ob_item[0];
- num_free_tuples[size]--;
+ if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) {
+ free_list[size] = (PyTupleObject *) op->ob_item[0];
+ numfree[size]--;
#ifdef COUNT_ALLOCS
fast_tuple_allocs++;
#endif
@@ -71,10 +71,10 @@ PyTuple_New(register Py_ssize_t size)
}
for (i=0; i < size; i++)
op->ob_item[i] = NULL;
-#if MAXSAVESIZE > 0
+#if PyTuple_MAXSAVESIZE > 0
if (size == 0) {
- free_tuples[0] = op;
- ++num_free_tuples[0];
+ free_list[0] = op;
+ ++numfree[0];
Py_INCREF(op); /* extra INCREF so that this is never freed */
}
#endif
@@ -167,14 +167,14 @@ tupledealloc(register PyTupleObject *op)
i = len;
while (--i >= 0)
Py_XDECREF(op->ob_item[i]);
-#if MAXSAVESIZE > 0
- if (len < MAXSAVESIZE &&
- num_free_tuples[len] < MAXSAVEDTUPLES &&
+#if PyTuple_MAXSAVESIZE > 0
+ if (len < PyTuple_MAXSAVESIZE &&
+ numfree[len] < PyTuple_MAXFREELIST &&
Py_TYPE(op) == &PyTuple_Type)
{
- op->ob_item[0] = (PyObject *) free_tuples[len];
- num_free_tuples[len]++;
- free_tuples[len] = op;
+ op->ob_item[0] = (PyObject *) free_list[len];
+ numfree[len]++;
+ free_list[len] = op;
goto done; /* return */
}
#endif
@@ -756,16 +756,16 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
void
PyTuple_Fini(void)
{
-#if MAXSAVESIZE > 0
+#if PyTuple_MAXSAVESIZE > 0
int i;
- Py_XDECREF(free_tuples[0]);
- free_tuples[0] = NULL;
+ Py_XDECREF(free_list[0]);
+ free_list[0] = NULL;
- for (i = 1; i < MAXSAVESIZE; i++) {
+ for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
PyTupleObject *p, *q;
- p = free_tuples[i];
- free_tuples[i] = NULL;
+ p = free_list[i];
+ free_list[i] = NULL;
while (p) {
q = p;
p = (PyTupleObject *)(p->ob_item[0]);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 1b35d4e..4f0de1e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -54,7 +54,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Limit for the Unicode object free list */
-#define MAX_UNICODE_FREELIST_SIZE 1024
+#define PyUnicode_MAXFREELIST 1024
/* Limit for the Unicode object free list stay alive optimization.
@@ -62,7 +62,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
all objects on the free list having a size less than this
limit. This reduces malloc() overhead for small Unicode objects.
- At worst this will result in MAX_UNICODE_FREELIST_SIZE *
+ At worst this will result in PyUnicode_MAXFREELIST *
(sizeof(PyUnicodeObject) + KEEPALIVE_SIZE_LIMIT +
malloc()-overhead) bytes of unused garbage.
@@ -106,8 +106,8 @@ extern "C" {
static PyObject *interned;
/* Free list for Unicode objects */
-static PyUnicodeObject *unicode_freelist;
-static int unicode_freelist_size;
+static PyUnicodeObject *free_list;
+static int numfree;
/* The empty Unicode object is shared to improve performance. */
static PyUnicodeObject *unicode_empty;
@@ -313,10 +313,10 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
}
/* Unicode freelist & memory allocation */
- if (unicode_freelist) {
- unicode = unicode_freelist;
- unicode_freelist = *(PyUnicodeObject **)unicode;
- unicode_freelist_size--;
+ if (free_list) {
+ unicode = free_list;
+ free_list = *(PyUnicodeObject **)unicode;
+ numfree--;
if (unicode->str) {
/* Keep-Alive optimization: we only upsize the buffer,
never downsize it. */
@@ -386,7 +386,7 @@ void unicode_dealloc(register PyUnicodeObject *unicode)
}
if (PyUnicode_CheckExact(unicode) &&
- unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) {
+ numfree < PyUnicode_MAXFREELIST) {
/* Keep-Alive optimization */
if (unicode->length >= KEEPALIVE_SIZE_LIMIT) {
PyMem_DEL(unicode->str);
@@ -398,9 +398,9 @@ void unicode_dealloc(register PyUnicodeObject *unicode)
unicode->defenc = NULL;
}
/* Add to free list */
- *(PyUnicodeObject **)unicode = unicode_freelist;
- unicode_freelist = unicode;
- unicode_freelist_size++;
+ *(PyUnicodeObject **)unicode = free_list;
+ free_list = unicode;
+ numfree++;
}
else {
PyMem_DEL(unicode->str);
@@ -8033,7 +8033,7 @@ unicode_zfill(PyUnicodeObject *self, PyObject *args)
static PyObject*
unicode_freelistsize(PyUnicodeObject *self)
{
- return PyLong_FromLong(unicode_freelist_size);
+ return PyLong_FromLong(numfree);
}
#endif
@@ -9090,8 +9090,8 @@ void _PyUnicode_Init(void)
};
/* Init the implementation */
- unicode_freelist = NULL;
- unicode_freelist_size = 0;
+ free_list = NULL;
+ numfree = 0;
unicode_empty = _PyUnicode_New(0);
if (!unicode_empty)
return;
@@ -9127,7 +9127,7 @@ _PyUnicode_Fini(void)
}
}
- for (u = unicode_freelist; u != NULL;) {
+ for (u = free_list; u != NULL;) {
PyUnicodeObject *v = u;
u = *(PyUnicodeObject **)u;
if (v->str)
@@ -9135,8 +9135,8 @@ _PyUnicode_Fini(void)
Py_XDECREF(v->defenc);
PyObject_Del(v);
}
- unicode_freelist = NULL;
- unicode_freelist_size = 0;
+ free_list = NULL;
+ numfree = 0;
}
void