Index: Python/sysmodule.c =================================================================== --- Python/sysmodule.c (Revision 60378) +++ Python/sysmodule.c (Arbeitskopie) @@ -754,17 +754,6 @@ 10. Number of stack pops performed by call_function()" ); -static PyObject * -sys_cleartypecache(PyObject* self, PyObject* args) -{ - PyType_ClearCache(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(cleartypecache_doc, -"_cleartypecache() -> None\n\ -Clear the internal type lookup cache."); - #ifdef __cplusplus extern "C" { #endif @@ -787,8 +776,6 @@ /* Might as well keep this in alphabetic order */ {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS, callstats_doc}, - {"_cleartypecache", sys_cleartypecache, METH_NOARGS, - cleartypecache_doc}, {"_current_frames", sys_current_frames, METH_NOARGS, current_frames_doc}, {"displayhook", sys_displayhook, METH_O, displayhook_doc}, Index: Include/intobject.h =================================================================== --- Include/intobject.h (Revision 60375) +++ Include/intobject.h (Arbeitskopie) @@ -59,6 +59,8 @@ PyAPI_FUNC(unsigned long) PyOS_strtoul(char *, char **, int); PyAPI_FUNC(long) PyOS_strtol(char *, char **, int); +PyAPI_FUNC(int) PyInt_CompactFreeList(int *, int *, int *); + #ifdef __cplusplus } #endif Index: Include/floatobject.h =================================================================== --- Include/floatobject.h (Revision 60375) +++ Include/floatobject.h (Arbeitskopie) @@ -101,6 +101,7 @@ PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); +PyAPI_FUNC(int) PyFloat_CompactFreeList(int *, int *, int *); #ifdef __cplusplus } Index: Objects/intobject.c =================================================================== --- Objects/intobject.c (Revision 60375) +++ Objects/intobject.c (Arbeitskopie) @@ -1201,26 +1201,15 @@ return 1; } -void -PyInt_Fini(void) +int +PyInt_CompactFreeList(int *pbc, int *pbf, int *bsum) { PyIntObject *p; PyIntBlock *list, *next; - int i; unsigned int ctr; int bc, bf; /* block count, number of freed blocks */ int irem, isum; /* remaining unfreed ints per block, total */ -#if NSMALLNEGINTS + NSMALLPOSINTS > 0 - PyIntObject **q; - - i = NSMALLNEGINTS + NSMALLPOSINTS; - q = small_ints; - while (--i >= 0) { - Py_XDECREF(*q); - *q++ = NULL; - } -#endif bc = 0; bf = 0; isum = 0; @@ -1268,6 +1257,34 @@ isum += irem; list = next; } + + *pbc = bc; + *pbf = bf; + *bsum = isum; + return 0; +} + +void +PyInt_Fini(void) +{ + PyIntObject *p; + PyIntBlock *list; + unsigned int ctr; + int bc, bf; /* block count, number of freed blocks */ + int isum; /* total unfreed ints per block */ + +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 + int i; + PyIntObject **q; + + i = NSMALLNEGINTS + NSMALLPOSINTS; + q = small_ints; + while (--i >= 0) { + Py_XDECREF(*q); + *q++ = NULL; + } +#endif + PyInt_CompactFreeList(&bc, &bf, &isum); if (!Py_VerboseFlag) return; fprintf(stderr, "# cleanup ints"); Index: Objects/floatobject.c =================================================================== --- Objects/floatobject.c (Revision 60375) +++ Objects/floatobject.c (Arbeitskopie) @@ -1513,8 +1513,8 @@ #endif } -void -PyFloat_Fini(void) +int +PyFloat_CompactFreeList(int *pbc, int *pbf, int *bsum) { PyFloatObject *p; PyFloatBlock *list, *next; @@ -1559,6 +1559,23 @@ fsum += frem; list = next; } + *pbc = bc; + *pbf = bf; + *bsum = fsum; + return 0; +} + +void +PyFloat_Fini(void) +{ + PyFloatObject *p; + PyFloatBlock *list; + unsigned i; + int bc, bf; /* block count, number of freed blocks */ + int fsum; /* total unfreed floats per block */ + + PyFloat_CompactFreeList(&bc, &bf, &fsum); + if (!Py_VerboseFlag) return; fprintf(stderr, "# cleanup floats"); Index: Lib/test/regrtest.py =================================================================== --- Lib/test/regrtest.py (Revision 60378) +++ Lib/test/regrtest.py (Arbeitskopie) @@ -710,7 +710,7 @@ sys.path_importer_cache.update(pic) # clear type cache - sys._cleartypecache() + gc.clear_type_cache() # Clear ABC registries, restoring previously saved ABC registries. for abc in [getattr(_abcoll, a) for a in _abcoll.__all__]: Index: Modules/gcmodule.c =================================================================== --- Modules/gcmodule.c (Revision 60375) +++ Modules/gcmodule.c (Arbeitskopie) @@ -1171,7 +1171,37 @@ return result; } +static PyObject * +gc_clear_type_cache(PyObject* self, PyObject* args) +{ + PyType_ClearCache(); + Py_RETURN_NONE; +} +PyDoc_STRVAR(gc_clear_type_cache__doc__, +"clear_type_cache() -> None\n\ +Clear the internal type lookup cache."); + + +static PyObject * +gc_compact_freelists(PyObject* self, PyObject* args) +{ + int isum, ibc, ibf; + int fsum, fbc, fbf; + + PyInt_CompactFreeList(&ibc, &ibf, &isum); + PyFloat_CompactFreeList(&fbc, &fbf, &fsum); + + return Py_BuildValue("(iii)(iii)", isum, ibc, ibf, + fsum, fbc, fbf); + +} + +PyDoc_STRVAR(gc_compact_freelists__doc__, +"compact_freelists() -> ((remaing_objects, total_blocks, freed_blocks), ...)\n\ +Compact the free lists of ints and floats."); + + PyDoc_STRVAR(gc__doc__, "This module provides access to the garbage collector for reference cycles.\n" "\n" @@ -1189,6 +1219,10 @@ "get_referents() -- Return the list of objects that an object refers to.\n"); static PyMethodDef GcMethods[] = { + {"compact_freelists", gc_compact_freelists, METH_NOARGS, + gc_compact_freelists__doc__}, + {"clear_type_cache", gc_clear_type_cache, METH_NOARGS, + gc_clear_type_cache__doc__}, {"enable", gc_enable, METH_NOARGS, gc_enable__doc__}, {"disable", gc_disable, METH_NOARGS, gc_disable__doc__}, {"isenabled", gc_isenabled, METH_NOARGS, gc_isenabled__doc__},