From 9a812cbc899caeb25ab523e904dfac02e4da2999 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 15 Nov 2011 00:00:12 +0100 Subject: [PATCH] Issue #13389: Full garbage collection passes now clear the freelists for list and dict objects. They already cleared other freelists in the interpreter. --- Doc/c-api/dict.rst | 7 +++++++ Doc/c-api/list.rst | 7 +++++++ Include/dictobject.h | 2 ++ Include/listobject.h | 2 ++ Misc/NEWS | 4 ++++ Modules/gcmodule.c | 2 ++ Objects/dictobject.c | 13 ++++++++++--- Objects/listobject.c | 13 ++++++++++--- 8 files changed, 44 insertions(+), 6 deletions(-) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 6df84e075a5..ac714a69113 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -209,3 +209,10 @@ Dictionary Objects for key, value in seq2: if override or key not in a: a[key] = value + + +.. c:function:: int PyDict_ClearFreeList() + + Clear the free list. Return the total number of freed items. + + .. versionadded:: 3.3 diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index feb9015b6da..5b263a7b1cd 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -142,3 +142,10 @@ List Objects Return a new tuple object containing the contents of *list*; equivalent to ``tuple(list)``. + + +.. c:function:: int PyList_ClearFreeList() + + Clear the free list. Return the total number of freed items. + + .. versionadded:: 3.3 diff --git a/Include/dictobject.h b/Include/dictobject.h index b0267859197..ed44e20a23f 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -129,6 +129,8 @@ PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash); PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); + +PyAPI_FUNC(int) PyDict_ClearFreeList(void); #endif /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ diff --git a/Include/listobject.h b/Include/listobject.h index 949b1a3e319..6fd374bb86e 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -62,6 +62,8 @@ PyAPI_FUNC(int) PyList_Reverse(PyObject *); PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); + +PyAPI_FUNC(int) PyList_ClearFreeList(void); #endif /* Macro, trading safety for speed */ diff --git a/Misc/NEWS b/Misc/NEWS index 423e29da8fc..082da2a003c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ What's New in Python 3.3 Alpha 1? Core and Builtins ----------------- +- Issue #13389: Full garbage collection passes now clear the freelists for + list and dict objects. They already cleared other freelists in the + interpreter. + - Issue #13327: Remove the need for an explicit None as the second argument to os.utime, os.lutimes, os.futimes, os.futimens, os.futimesat, in order to update to the current time. Also added keyword argument diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 6c8ca38d628..154f13623e0 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -762,6 +762,8 @@ clear_freelists(void) (void)PyTuple_ClearFreeList(); (void)PyUnicode_ClearFreeList(); (void)PyFloat_ClearFreeList(); + (void)PyList_ClearFreeList(); + (void)PyDict_ClearFreeList(); } static double diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 82735e6753b..f8f072d4009 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -217,16 +217,23 @@ show_track(void) static PyDictObject *free_list[PyDict_MAXFREELIST]; static int numfree = 0; -void -PyDict_Fini(void) +int +PyDict_ClearFreeList(void) { PyDictObject *op; - + int ret = numfree; while (numfree) { op = free_list[--numfree]; assert(PyDict_CheckExact(op)); PyObject_GC_Del(op); } + return ret; +} + +void +PyDict_Fini(void) +{ + PyDict_ClearFreeList(); } PyObject * diff --git a/Objects/listobject.c b/Objects/listobject.c index 69a632d5289..6f1edc55d87 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -97,16 +97,23 @@ show_alloc(void) static PyListObject *free_list[PyList_MAXFREELIST]; static int numfree = 0; -void -PyList_Fini(void) +int +PyList_ClearFreeList(void) { PyListObject *op; - + int ret = numfree; while (numfree) { op = free_list[--numfree]; assert(PyList_CheckExact(op)); PyObject_GC_Del(op); } + return ret; +} + +void +PyList_Fini(void) +{ + PyList_ClearFreeList(); } PyObject *