diff --git a/Include/object.h b/Include/object.h index 772bbb3..91b3970 100644 --- a/Include/object.h +++ b/Include/object.h @@ -284,6 +284,7 @@ typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); typedef int (*initproc)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); +typedef int (*freelistfunc)(void); typedef struct _typeobject { PyObject_VAR_HEAD @@ -352,6 +353,7 @@ typedef struct _typeobject { allocfunc tp_alloc; newfunc tp_new; freefunc tp_free; /* Low-level free-memory routine */ + freelistfunc tp_free_list; /* Low-level routine to clear free list */ inquiry tp_is_gc; /* For PyObject_IS_GC */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ @@ -418,6 +420,8 @@ PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, char *, PyObject **); PyAPI_FUNC(unsigned int) PyType_ClearCache(void); PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); +PyAPI_FUNC(int) PyType_ClearFreeList(PyTypeObject *); + /* Generic operations on objects */ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index a031998..ab056e4 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -389,6 +389,7 @@ static PyTypeObject localtype = { /* tp_alloc */ 0, /* tp_new */ local_new, /* tp_free */ 0, /* Low-level free-mem routine */ + /* tp_free_list */ 0, /* tp_is_gc */ 0, /* For PyObject_IS_GC */ }; diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index d4a0900..7033283 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -762,6 +762,7 @@ clear_freelists(void) (void)PyTuple_ClearFreeList(); (void)PyUnicode_ClearFreeList(); (void)PyFloat_ClearFreeList(); + (void)PyType_ClearFreeList(&PyDict_Type); } static double diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 03f2010..6b8ac12 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -226,9 +226,10 @@ show_track(void) static PyDictObject *free_list[PyDict_MAXFREELIST]; static int numfree = 0; -void -PyDict_Fini(void) +static int +dict_free_list(void) { + int freelist_size = numfree; PyDictObject *op; while (numfree) { @@ -236,6 +237,13 @@ PyDict_Fini(void) assert(PyDict_CheckExact(op)); PyObject_GC_Del(op); } + return freelist_size; +} + +void +PyDict_Fini(void) +{ + (void)dict_free_list(); } PyObject * @@ -2151,6 +2159,7 @@ PyTypeObject PyDict_Type = { PyType_GenericAlloc, /* tp_alloc */ dict_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + dict_free_list, /* tp_free_list */ }; /* For backward compatibility with old dictionary interface */ diff --git a/Objects/genobject.c b/Objects/genobject.c index fb8415f..1cac54d 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -365,6 +365,7 @@ PyTypeObject PyGen_Type = { 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ + 0, /* tp_free_list */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 24866ff..8dcba22 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -93,6 +93,14 @@ PyType_Modified(PyTypeObject *type) type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; } +int +PyType_ClearFreeList(PyTypeObject *type) { + if (type->tp_free_list != NULL) { + return type->tp_free_list(); + } + return 0; +} + static void type_mro_modified(PyTypeObject *type, PyObject *bases) { /* @@ -2613,6 +2621,7 @@ PyTypeObject PyType_Type = { 0, /* tp_alloc */ type_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + 0, /* tp_free_list */ (inquiry)type_is_gc, /* tp_is_gc */ };