.. cfunction:: PyObject* PyMethod_GET_SELF(PyObject *meth)
Macro version of :cfunc:`PyMethod_Self` which avoids error checking.
+
+
+.. cfunction:: int PyMethod_ClearFreeList(void)
+
+ Clear the free list. Return the total number of freed items.
+
+ .. versionadded:: 2.6
.. versionchanged:: 2.2
Removed unused third parameter, *last_is_sticky*.
+
+
+.. cfunction:: int PyMethod_ClearFreeList(void)
+
+ Clear the free list. Return the total number of freed items.
+
+ .. versionadded:: 2.6
Return a pointer to the internal buffer of the object. *o* has to be a
:ctype:`PyUnicodeObject` (not checked).
+
+.. cfunction:: int PyUnicode_ClearFreeList(void)
+
+ Clear the free list. Return the total number of freed items.
+
+ .. versionadded:: 2.6
+
Unicode provides many different character properties. The most often needed ones
are available through these macros which are mapped to C functions depending on
the Python configuration.
PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *);
+PyAPI_FUNC(int) PyMethod_ClearFreeList(void);
#ifdef __cplusplus
}
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
+PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
+
#ifdef __cplusplus
}
#endif
PyObject *m_module; /* The __module__ attribute, can be anything */
} PyCFunctionObject;
+PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
+
#ifdef __cplusplus
}
#endif
/* Macro, *only* to be used to fill in brand new tuples */
#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
+PyAPI_FUNC(int) PyTuple_ClearFreeList(void);
+
#ifdef __cplusplus
}
#endif
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString
# define _PyUnicode_Fini _PyUnicodeUCS2_Fini
# define _PyUnicode_Init _PyUnicodeUCS2_Init
+# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
# define _PyUnicode_IsAlpha _PyUnicodeUCS2_IsAlpha
# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS2_IsDecimalDigit
# define _PyUnicode_IsDigit _PyUnicodeUCS2_IsDigit
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString
# define _PyUnicode_Fini _PyUnicodeUCS4_Fini
# define _PyUnicode_Init _PyUnicodeUCS4_Init
+# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
# define _PyUnicode_IsAlpha _PyUnicodeUCS4_IsAlpha
# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS4_IsDecimalDigit
# define _PyUnicode_IsDigit _PyUnicodeUCS4_IsDigit
extern "C" {
#endif
+PyAPI_FUNC(int) PyUnicode_ClearFreeList(void);
+
/* --- Unicode Type ------------------------------------------------------- */
typedef struct {
Core and builtins
-----------------
+- Clear all free list during a gc.collect() of the highest generation in order
+ to allow pymalloc to free more arenas. Python may give back memory to the
+ OS earlier.
+
- Issue #2045: Fix an infinite recursion triggered when printing a subclass of
collections.defaultdict, if its default_factory is set to a bound method.
*/
#include "Python.h"
+#include "frameobject.h" /* for PyFrame_ClearFreeList */
/* Get an object's GC head */
#define AS_GC(o) ((PyGC_Head *)(o)-1)
}
}
+/* Clear all free lists
+ * All free lists are cleared during the collection of the highest generation.
+ * Allocated items in the free list may keep a pymalloc arena occupied.
+ * Clearing the free lists may give back memory to the OS earlier.
+ */
+static void
+clear_freelists(void)
+{
+ (void)PyMethod_ClearFreeList();
+ (void)PyFrame_ClearFreeList();
+ (void)PyCFunction_ClearFreeList();
+ (void)PyTuple_ClearFreeList();
+ (void)PyUnicode_ClearFreeList();
+}
+
/* This is the main function. Read this to understand how the
* collection process works. */
static Py_ssize_t
*/
(void)handle_finalizers(&finalizers, old);
+ /* Clear free list only during the collection of the higest
+ * generation */
+ if (generation == NUM_GENERATIONS-1) {
+ clear_freelists();
+ }
+
if (PyErr_Occurred()) {
if (gc_str == NULL)
gc_str = PyString_FromString("garbage collection");
/* Clear out the free list */
-void
-PyMethod_Fini(void)
+int
+PyMethod_ClearFreeList(void)
{
+ int freelist_size = numfree;
+
while (free_list) {
PyMethodObject *im = free_list;
free_list = (PyMethodObject *)(im->im_self);
numfree--;
}
assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+PyMethod_Fini(void)
+{
+ (void)PyMethod_ClearFreeList();
}
}
/* Clear out the free list */
-
-void
-PyFrame_Fini(void)
+int
+PyFrame_ClearFreeList(void)
{
+ int freelist_size = numfree;
+
while (free_list != NULL) {
PyFrameObject *f = free_list;
free_list = free_list->f_back;
--numfree;
}
assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+PyFrame_Fini(void)
+{
+ (void)PyFrame_ClearFreeList();
Py_XDECREF(builtin_object);
builtin_object = NULL;
}
/* Clear out the free list */
-void
-PyCFunction_Fini(void)
+int
+PyCFunction_ClearFreeList(void)
{
+ int freelist_size = numfree;
+
while (free_list) {
PyCFunctionObject *v = free_list;
free_list = (PyCFunctionObject *)(v->m_self);
numfree--;
}
assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+PyCFunction_Fini(void)
+{
+ (void)PyCFunction_ClearFreeList();
}
/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
return 0;
}
-void
-PyTuple_Fini(void)
+int
+PyTuple_ClearFreeList(void)
{
+ int freelist_size = 0;
#if PyTuple_MAXSAVESIZE > 0
int i;
-
- Py_XDECREF(free_list[0]);
- free_list[0] = NULL;
-
for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
PyTupleObject *p, *q;
p = free_list[i];
+ freelist_size += numfree[i];
free_list[i] = NULL;
+ numfree[i] = 0;
while (p) {
q = p;
p = (PyTupleObject *)(p->ob_item[0]);
PyObject_GC_Del(q);
}
}
+#endif
+ return freelist_size;
+}
+
+void
+PyTuple_Fini(void)
+{
+#if PyTuple_MAXSAVESIZE > 0
+ /* empty tuples are used all over the place and applications may
+ * rely on the fact that an empty tuple is a singleton. */
+ Py_XDECREF(free_list[0]);
+ free_list[0] = NULL;
+
+ (void)PyTuple_ClearFreeList();
#endif
}
/* Finalize the Unicode implementation */
+int
+PyUnicode_ClearFreeList(void)
+{
+ int freelist_size = numfree;
+ PyUnicodeObject *u;
+
+ for (u = free_list; u != NULL;) {
+ PyUnicodeObject *v = u;
+ u = *(PyUnicodeObject **)u;
+ if (v->str)
+ PyMem_DEL(v->str);
+ Py_XDECREF(v->defenc);
+ PyObject_Del(v);
+ numfree--;
+ }
+ free_list = NULL;
+ assert(numfree == 0);
+ return freelist_size;
+}
+
void
_PyUnicode_Fini(void)
{
- PyUnicodeObject *u;
int i;
Py_XDECREF(unicode_empty);
unicode_latin1[i] = NULL;
}
}
-
- for (u = free_list; u != NULL;) {
- PyUnicodeObject *v = u;
- u = *(PyUnicodeObject **)u;
- if (v->str)
- PyMem_DEL(v->str);
- Py_XDECREF(v->defenc);
- PyObject_Del(v);
- }
- free_list = NULL;
- numfree = 0;
+ (void)PyUnicode_ClearFreeList();
}
#ifdef __cplusplus