bpo-40428: Remove PyTuple_ClearFreeList() function (GH-19769)

Remove the following function from the C API:

* PyAsyncGen_ClearFreeLists()
* PyContext_ClearFreeList()
* PyDict_ClearFreeList()
* PyFloat_ClearFreeList()
* PyFrame_ClearFreeList()
* PyList_ClearFreeList()
* PySet_ClearFreeList()
* PyTuple_ClearFreeList()

Make these functions private, move them to the internal C API and
change their return type to void.

Call explicitly PyGC_Collect() to free all free lists.

Note: PySet_ClearFreeList() did nothing.
This commit is contained in:
Victor Stinner 2020-04-29 02:29:20 +02:00 committed by GitHub
parent cc0dc7e484
commit ae00a5a885
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 71 additions and 86 deletions

View file

@ -257,20 +257,17 @@ static int numfreekeys = 0;
#include "clinic/dictobject.c.h"
int
PyDict_ClearFreeList(void)
void
_PyDict_ClearFreeList(void)
{
PyDictObject *op;
int ret = numfree + numfreekeys;
while (numfree) {
op = free_list[--numfree];
PyDictObject *op = free_list[--numfree];
assert(PyDict_CheckExact(op));
PyObject_GC_Del(op);
}
while (numfreekeys) {
PyObject_FREE(keys_free_list[--numfreekeys]);
}
return ret;
}
/* Print summary info about the state of the optimized allocator */
@ -285,7 +282,7 @@ _PyDict_DebugMallocStats(FILE *out)
void
_PyDict_Fini(void)
{
PyDict_ClearFreeList();
_PyDict_ClearFreeList();
}
#define DK_SIZE(dk) ((dk)->dk_size)

View file

@ -1998,25 +1998,22 @@ _PyFloat_Init(void)
return 1;
}
int
PyFloat_ClearFreeList(void)
void
_PyFloat_ClearFreeList(void)
{
PyFloatObject *f = free_list, *next;
int i = numfree;
while (f) {
for (; f; f = next) {
next = (PyFloatObject*) Py_TYPE(f);
PyObject_FREE(f);
f = next;
}
free_list = NULL;
numfree = 0;
return i;
}
void
_PyFloat_Fini(void)
{
(void)PyFloat_ClearFreeList();
_PyFloat_ClearFreeList();
}
/* Print summary info about the state of the optimized allocator */

View file

@ -1200,11 +1200,9 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
}
/* Clear out the free list */
int
PyFrame_ClearFreeList(void)
void
_PyFrame_ClearFreeList(void)
{
int freelist_size = numfree;
while (free_list != NULL) {
PyFrameObject *f = free_list;
free_list = free_list->f_back;
@ -1212,13 +1210,12 @@ PyFrame_ClearFreeList(void)
--numfree;
}
assert(numfree == 0);
return freelist_size;
}
void
_PyFrame_Fini(void)
{
(void)PyFrame_ClearFreeList();
_PyFrame_ClearFreeList();
}
/* Print summary info about the state of the optimized allocator */

View file

@ -1429,11 +1429,9 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
}
int
PyAsyncGen_ClearFreeLists(void)
void
_PyAsyncGen_ClearFreeLists(void)
{
int ret = ag_value_freelist_free + ag_asend_freelist_free;
while (ag_value_freelist_free) {
_PyAsyncGenWrappedValue *o;
o = ag_value_freelist[--ag_value_freelist_free];
@ -1447,14 +1445,12 @@ PyAsyncGen_ClearFreeLists(void)
assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type));
PyObject_GC_Del(o);
}
return ret;
}
void
_PyAsyncGen_Fini(void)
{
PyAsyncGen_ClearFreeLists();
_PyAsyncGen_ClearFreeLists();
}

View file

@ -103,23 +103,20 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
static PyListObject *free_list[PyList_MAXFREELIST];
static int numfree = 0;
int
PyList_ClearFreeList(void)
void
_PyList_ClearFreeList(void)
{
PyListObject *op;
int ret = numfree;
while (numfree) {
op = free_list[--numfree];
PyListObject *op = free_list[--numfree];
assert(PyList_CheckExact(op));
PyObject_GC_Del(op);
}
return ret;
}
void
_PyList_Fini(void)
{
PyList_ClearFreeList();
_PyList_ClearFreeList();
}
/* Print summary info about the state of the optimized allocator */

View file

@ -2384,12 +2384,6 @@ PySet_Add(PyObject *anyset, PyObject *key)
return set_add_key((PySetObject *)anyset, key);
}
int
PySet_ClearFreeList(void)
{
return 0;
}
void
_PySet_Fini(void)
{

View file

@ -955,26 +955,22 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
return 0;
}
int
PyTuple_ClearFreeList(void)
void
_PyTuple_ClearFreeList(void)
{
int freelist_size = 0;
#if PyTuple_MAXSAVESIZE > 0
int i;
for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
PyTupleObject *p, *q;
p = free_list[i];
freelist_size += numfree[i];
for (Py_ssize_t i = 1; i < PyTuple_MAXSAVESIZE; i++) {
PyTupleObject *p = free_list[i];
free_list[i] = NULL;
numfree[i] = 0;
while (p) {
q = p;
PyTupleObject *q = p;
p = (PyTupleObject *)(p->ob_item[0]);
PyObject_GC_Del(q);
}
}
// the empty tuple singleton is only cleared by _PyTuple_Fini()
#endif
return freelist_size;
}
void
@ -985,7 +981,7 @@ _PyTuple_Fini(void)
* rely on the fact that an empty tuple is a singleton. */
Py_CLEAR(free_list[0]);
(void)PyTuple_ClearFreeList();
_PyTuple_ClearFreeList();
#endif
}