Skip to content

Commit 807fd11

Browse files
author
christian.heimes
committed
Implemented Martin's suggestion to clear the free lists during the garbage collection of the highest generation.
git-svn-id: http://svn.python.org/projects/python/trunk@60797 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent dbb0623 commit 807fd11

15 files changed

Lines changed: 131 additions & 25 deletions

Doc/c-api/method.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,10 @@ There are some useful functions that are useful for working with method objects.
6363
.. cfunction:: PyObject* PyMethod_GET_SELF(PyObject *meth)
6464

6565
Macro version of :cfunc:`PyMethod_Self` which avoids error checking.
66+
67+
68+
.. cfunction:: int PyMethod_ClearFreeList(void)
69+
70+
Clear the free list. Return the total number of freed items.
71+
72+
.. versionadded:: 2.6

Doc/c-api/tuple.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,10 @@ Tuple Objects
115115

116116
.. versionchanged:: 2.2
117117
Removed unused third parameter, *last_is_sticky*.
118+
119+
120+
.. cfunction:: int PyMethod_ClearFreeList(void)
121+
122+
Clear the free list. Return the total number of freed items.
123+
124+
.. versionadded:: 2.6

Doc/c-api/unicode.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ access internal read-only data of Unicode objects:
8989
Return a pointer to the internal buffer of the object. *o* has to be a
9090
:ctype:`PyUnicodeObject` (not checked).
9191

92+
93+
.. cfunction:: int PyUnicode_ClearFreeList(void)
94+
95+
Clear the free list. Return the total number of freed items.
96+
97+
.. versionadded:: 2.6
98+
9299
Unicode provides many different character properties. The most often needed ones
93100
are available through these macros which are mapped to C functions depending on
94101
the Python configuration.

Include/classobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name);
7474

7575
PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *);
7676

77+
PyAPI_FUNC(int) PyMethod_ClearFreeList(void);
7778

7879
#ifdef __cplusplus
7980
}

Include/frameobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int);
7575
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
7676
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
7777

78+
PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
79+
7880
#ifdef __cplusplus
7981
}
8082
#endif

Include/methodobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ typedef struct {
8585
PyObject *m_module; /* The __module__ attribute, can be anything */
8686
} PyCFunctionObject;
8787

88+
PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
89+
8890
#ifdef __cplusplus
8991
}
9092
#endif

Include/tupleobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...);
5252
/* Macro, *only* to be used to fill in brand new tuples */
5353
#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
5454

55+
PyAPI_FUNC(int) PyTuple_ClearFreeList(void);
56+
5557
#ifdef __cplusplus
5658
}
5759
#endif

Include/unicodeobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
209209
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString
210210
# define _PyUnicode_Fini _PyUnicodeUCS2_Fini
211211
# define _PyUnicode_Init _PyUnicodeUCS2_Init
212+
# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
212213
# define _PyUnicode_IsAlpha _PyUnicodeUCS2_IsAlpha
213214
# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS2_IsDecimalDigit
214215
# define _PyUnicode_IsDigit _PyUnicodeUCS2_IsDigit
@@ -295,6 +296,7 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
295296
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString
296297
# define _PyUnicode_Fini _PyUnicodeUCS4_Fini
297298
# define _PyUnicode_Init _PyUnicodeUCS4_Init
299+
# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
298300
# define _PyUnicode_IsAlpha _PyUnicodeUCS4_IsAlpha
299301
# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS4_IsDecimalDigit
300302
# define _PyUnicode_IsDigit _PyUnicodeUCS4_IsDigit
@@ -403,6 +405,8 @@ extern const unsigned char _Py_ascii_whitespace[];
403405
extern "C" {
404406
#endif
405407

408+
PyAPI_FUNC(int) PyUnicode_ClearFreeList(void);
409+
406410
/* --- Unicode Type ------------------------------------------------------- */
407411

408412
typedef struct {

Misc/NEWS

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

15+
- Clear all free list during a gc.collect() of the highest generation in order
16+
to allow pymalloc to free more arenas. Python may give back memory to the
17+
OS earlier.
18+
1519
- Issue #2045: Fix an infinite recursion triggered when printing a subclass of
1620
collections.defaultdict, if its default_factory is set to a bound method.
1721

Modules/gcmodule.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include "Python.h"
22+
#include "frameobject.h" /* for PyFrame_ClearFreeList */
2223

2324
/* Get an object's GC head */
2425
#define AS_GC(o) ((PyGC_Head *)(o)-1)
@@ -722,6 +723,21 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
722723
}
723724
}
724725

726+
/* Clear all free lists
727+
* All free lists are cleared during the collection of the highest generation.
728+
* Allocated items in the free list may keep a pymalloc arena occupied.
729+
* Clearing the free lists may give back memory to the OS earlier.
730+
*/
731+
static void
732+
clear_freelists(void)
733+
{
734+
(void)PyMethod_ClearFreeList();
735+
(void)PyFrame_ClearFreeList();
736+
(void)PyCFunction_ClearFreeList();
737+
(void)PyTuple_ClearFreeList();
738+
(void)PyUnicode_ClearFreeList();
739+
}
740+
725741
/* This is the main function. Read this to understand how the
726742
* collection process works. */
727743
static Py_ssize_t
@@ -874,6 +890,12 @@ collect(int generation)
874890
*/
875891
(void)handle_finalizers(&finalizers, old);
876892

893+
/* Clear free list only during the collection of the higest
894+
* generation */
895+
if (generation == NUM_GENERATIONS-1) {
896+
clear_freelists();
897+
}
898+
877899
if (PyErr_Occurred()) {
878900
if (gc_str == NULL)
879901
gc_str = PyString_FromString("garbage collection");

0 commit comments

Comments
 (0)