[Python-checkins] r64753 - in python/trunk: Doc/c-api/float.rst Doc/c-api/int.rst Doc/library/gc.rst Doc/library/sys.rst Include/floatobject.h Include/intobject.h Misc/NEWS Modules/gcmodule.c Objects/floatobject.c Objects/intobject.c Python/sysmodule.c

gregory.p.smith python-checkins at python.org
Sun Jul 6 05:35:59 CEST 2008


Author: gregory.p.smith
Date: Sun Jul  6 05:35:58 2008
New Revision: 64753

Log:
- Issue #2862: Make int and float freelist management consistent with other
  freelists.  Changes their CompactFreeList apis into ClearFreeList apis and
  calls them via gc.collect().


Modified:
   python/trunk/Doc/c-api/float.rst
   python/trunk/Doc/c-api/int.rst
   python/trunk/Doc/library/gc.rst
   python/trunk/Doc/library/sys.rst
   python/trunk/Include/floatobject.h
   python/trunk/Include/intobject.h
   python/trunk/Misc/NEWS
   python/trunk/Modules/gcmodule.c
   python/trunk/Objects/floatobject.c
   python/trunk/Objects/intobject.c
   python/trunk/Python/sysmodule.c

Modified: python/trunk/Doc/c-api/float.rst
==============================================================================
--- python/trunk/Doc/c-api/float.rst	(original)
+++ python/trunk/Doc/c-api/float.rst	Sun Jul  6 05:35:58 2008
@@ -86,10 +86,9 @@
    .. versionadded:: 2.6
 
 
-.. cfunction:: void PyFloat_CompactFreeList(size_t *bc, size_t *bf, size_t *sum)
+.. cfunction:: int PyFloat_ClearFreeList(void)
 
-   Compact the float free list. *bc* is the number of allocated blocks before
-   blocks are freed, *bf* is the number of freed blocks and *sum* is the number
-   of remaining objects in the blocks.
+   Clear the float free list. Return the number of items that could not
+   be freed.
 
    .. versionadded:: 2.6

Modified: python/trunk/Doc/c-api/int.rst
==============================================================================
--- python/trunk/Doc/c-api/int.rst	(original)
+++ python/trunk/Doc/c-api/int.rst	Sun Jul  6 05:35:58 2008
@@ -122,10 +122,9 @@
    (:const:`LONG_MAX`, as defined in the system header files).
 
 
-.. cfunction:: void PyInt_CompactFreeList(size_t *bc, size_t *bf, size_t *sum)
+.. cfunction:: int PyInt_ClearFreeList(void)
 
-   Compact the integer free list. *bc* is the number of allocated blocks before
-   blocks are freed, *bf* is the number of freed blocks and *sum* is the number
-   of remaining objects in the blocks.
+   Clear the integer free list. Return the number of items that could not
+   be freed.
 
    .. versionadded:: 2.6

Modified: python/trunk/Doc/library/gc.rst
==============================================================================
--- python/trunk/Doc/library/gc.rst	(original)
+++ python/trunk/Doc/library/gc.rst	Sun Jul  6 05:35:58 2008
@@ -47,6 +47,12 @@
    .. versionchanged:: 2.5
       The optional *generation* argument was added.
 
+   .. versionchanged:: 2.6
+      The free lists maintained for a number of builtin types are cleared
+      whenever a full collection or collection of the highest generation (2)
+      is run.  Not all items in some free lists may be freed due to the
+      particular implementation, in particular :class:`int` and :class:`float`.
+
 
 .. function:: set_debug(flags)
 

Modified: python/trunk/Doc/library/sys.rst
==============================================================================
--- python/trunk/Doc/library/sys.rst	(original)
+++ python/trunk/Doc/library/sys.rst	Sun Jul  6 05:35:58 2008
@@ -58,22 +58,6 @@
    A string containing the copyright pertaining to the Python interpreter.
 
 
-.. function:: _compact_freelists()
-
-   Compact the free lists of integers and floats by deallocating unused blocks.
-   It can reduce the memory usage of the Python process several tenth of
-   thousands of integers or floats have been allocated at once.
-
-   The return value is a tuple of tuples each containing three elements,
-   amount of used objects, total block count before the blocks are deallocated
-   and amount of freed blocks. The first tuple refers to ints, the second to
-   floats.
-
-   This function should be used for specialized purposes only.
-
-   .. versionadded:: 2.6
-
-
 .. function:: _clear_type_cache()
 
    Clear the internal type cache. The type cache is used to speed up attribute

Modified: python/trunk/Include/floatobject.h
==============================================================================
--- python/trunk/Include/floatobject.h	(original)
+++ python/trunk/Include/floatobject.h	Sun Jul  6 05:35:58 2008
@@ -113,7 +113,7 @@
 PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
 
 /* free list api */
-PyAPI_FUNC(void) PyFloat_CompactFreeList(size_t *, size_t *, size_t *);
+PyAPI_FUNC(int) PyFloat_ClearFreeList(void);
 
 /* Format the object based on the format_spec, as defined in PEP 3101
    (Advanced String Formatting). */

Modified: python/trunk/Include/intobject.h
==============================================================================
--- python/trunk/Include/intobject.h	(original)
+++ python/trunk/Include/intobject.h	Sun Jul  6 05:35:58 2008
@@ -60,7 +60,7 @@
 PyAPI_FUNC(long) PyOS_strtol(char *, char **, int);
 
 /* free list api */
-PyAPI_FUNC(void) PyInt_CompactFreeList(size_t *, size_t *, size_t *);
+PyAPI_FUNC(int) PyInt_ClearFreeList(void);
 
 /* Convert an integer to the given base.  Returns a string.
    If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'.

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Sun Jul  6 05:35:58 2008
@@ -29,6 +29,10 @@
   would not cause a syntax error.  This was regression from 2.4 caused by the
   switch to the new compiler.
 
+- Issue #2862: Make int and float freelist management consistent with other
+  freelists.  Changes their CompactFreeList apis into ClearFreeList apis and
+  calls them via gc.collect().
+
 Library
 -------
 

Modified: python/trunk/Modules/gcmodule.c
==============================================================================
--- python/trunk/Modules/gcmodule.c	(original)
+++ python/trunk/Modules/gcmodule.c	Sun Jul  6 05:35:58 2008
@@ -736,6 +736,8 @@
 	(void)PyCFunction_ClearFreeList();
 	(void)PyTuple_ClearFreeList();
 	(void)PyUnicode_ClearFreeList();
+	(void)PyInt_ClearFreeList();
+	(void)PyFloat_ClearFreeList();
 }
 
 /* This is the main function.  Read this to understand how the

Modified: python/trunk/Objects/floatobject.c
==============================================================================
--- python/trunk/Objects/floatobject.c	(original)
+++ python/trunk/Objects/floatobject.c	Sun Jul  6 05:35:58 2008
@@ -1608,30 +1608,28 @@
 		PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
 }
 
-void
-PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
+int
+PyFloat_ClearFreeList(void)
 {
 	PyFloatObject *p;
 	PyFloatBlock *list, *next;
-	unsigned i;
-	size_t bc = 0, bf = 0;	/* block count, number of freed blocks */
-	size_t fsum = 0;	/* total unfreed ints */
-	int frem;		/* remaining unfreed ints per block */
+	int i;
+	int u;			/* remaining unfreed ints per block */
+	int freelist_size = 0;
 
 	list = block_list;
 	block_list = NULL;
 	free_list = NULL;
 	while (list != NULL) {
-		bc++;
-		frem = 0;
+		u = 0;
 		for (i = 0, p = &list->objects[0];
 		     i < N_FLOATOBJECTS;
 		     i++, p++) {
 			if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
-				frem++;
+				u++;
 		}
 		next = list->next;
-		if (frem) {
+		if (u) {
 			list->next = block_list;
 			block_list = list;
 			for (i = 0, p = &list->objects[0];
@@ -1646,15 +1644,12 @@
 			}
 		}
 		else {
-			PyMem_FREE(list); /* XXX PyObject_FREE ??? */
-			bf++;
+			PyMem_FREE(list);
 		}
-		fsum += frem;
+		freelist_size += u;
 		list = next;
 	}
-	*pbc = bc;
-	*pbf = bf;
-	*bsum = fsum;
+	return freelist_size;
 }
 
 void
@@ -1662,25 +1657,21 @@
 {
 	PyFloatObject *p;
 	PyFloatBlock *list;
-	unsigned i;
-	size_t bc, bf;	/* block count, number of freed blocks */
-	size_t fsum;	/* total unfreed floats per block */
+	int i;
+	int u;			/* total unfreed floats per block */
 
-	PyFloat_CompactFreeList(&bc, &bf, &fsum);
+	u = PyFloat_ClearFreeList();
 
 	if (!Py_VerboseFlag)
 		return;
 	fprintf(stderr, "# cleanup floats");
-	if (!fsum) {
+	if (!u) {
 		fprintf(stderr, "\n");
 	}
 	else {
 		fprintf(stderr,
-			": %" PY_FORMAT_SIZE_T "d unfreed float%s in %"
-			PY_FORMAT_SIZE_T "d out of %"
-			PY_FORMAT_SIZE_T "d block%s\n",
-			fsum, fsum == 1 ? "" : "s",
-			bc - bf, bc, bc == 1 ? "" : "s");
+			": %d unfreed float%s\n",
+			u, u == 1 ? "" : "s");
 	}
 	if (Py_VerboseFlag > 1) {
 		list = block_list;

Modified: python/trunk/Objects/intobject.c
==============================================================================
--- python/trunk/Objects/intobject.c	(original)
+++ python/trunk/Objects/intobject.c	Sun Jul  6 05:35:58 2008
@@ -1296,35 +1296,33 @@
 	return 1;
 }
 
-void
-PyInt_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
+int
+PyInt_ClearFreeList(void)
 {
 	PyIntObject *p;
 	PyIntBlock *list, *next;
-	unsigned int ctr;
-	size_t bc = 0, bf = 0;	/* block count, number of freed blocks */
-	size_t isum = 0;	/* total unfreed ints */
-	int irem;		/* remaining unfreed ints per block */
+	int i;
+	int u;			/* remaining unfreed ints per block */
+	int freelist_size = 0;
 
 	list = block_list;
 	block_list = NULL;
 	free_list = NULL;
 	while (list != NULL) {
-		bc++;
-		irem = 0;
-		for (ctr = 0, p = &list->objects[0];
-		     ctr < N_INTOBJECTS;
-		     ctr++, p++) {
+		u = 0;
+		for (i = 0, p = &list->objects[0];
+		     i < N_INTOBJECTS;
+		     i++, p++) {
 			if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
-				irem++;
+				u++;
 		}
 		next = list->next;
-		if (irem) {
+		if (u) {
 			list->next = block_list;
 			block_list = list;
-			for (ctr = 0, p = &list->objects[0];
-			     ctr < N_INTOBJECTS;
-			     ctr++, p++) {
+			for (i = 0, p = &list->objects[0];
+			     i < N_INTOBJECTS;
+			     i++, p++) {
 				if (!PyInt_CheckExact(p) ||
 				    p->ob_refcnt == 0) {
 					Py_TYPE(p) = (struct _typeobject *)
@@ -1345,15 +1343,12 @@
 		}
 		else {
 			PyMem_FREE(list);
-			bf++;
 		}
-		isum += irem;
+		freelist_size += u;
 		list = next;
 	}
 
-	*pbc = bc;
-	*pbf = bf;
-	*bsum = isum;
+	return freelist_size;
 }
 
 void
@@ -1361,12 +1356,10 @@
 {
 	PyIntObject *p;
 	PyIntBlock *list;
-	unsigned int ctr;
-	size_t bc, bf;	/* block count, number of freed blocks */
-	size_t isum;	/* total unfreed ints per block */
+	int i;
+	int u;			/* total unfreed ints per block */
 
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
-	int i;
 	PyIntObject **q;
 
 	i = NSMALLNEGINTS + NSMALLPOSINTS;
@@ -1376,27 +1369,24 @@
 		*q++ = NULL;
 	}
 #endif
-	PyInt_CompactFreeList(&bc, &bf, &isum);
+	u = PyInt_ClearFreeList();
 	if (!Py_VerboseFlag)
 		return;
 	fprintf(stderr, "# cleanup ints");
-	if (!isum) {
+	if (!u) {
 		fprintf(stderr, "\n");
 	}
 	else {
 		fprintf(stderr,
-			": %" PY_FORMAT_SIZE_T "d unfreed int%s in %"
-			PY_FORMAT_SIZE_T "d out of %"
-			PY_FORMAT_SIZE_T "d block%s\n",
-			isum, isum == 1 ? "" : "s",
-			bc - bf, bc, bc == 1 ? "" : "s");
+			": %d unfreed int%s\n",
+			u, u == 1 ? "" : "s");
 	}
 	if (Py_VerboseFlag > 1) {
 		list = block_list;
 		while (list != NULL) {
-			for (ctr = 0, p = &list->objects[0];
-			     ctr < N_INTOBJECTS;
-			     ctr++, p++) {
+			for (i = 0, p = &list->objects[0];
+			     i < N_INTOBJECTS;
+			     i++, p++) {
 				if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
 					/* XXX(twouters) cast refcount to
 					   long until %zd is universally

Modified: python/trunk/Python/sysmodule.c
==============================================================================
--- python/trunk/Python/sysmodule.c	(original)
+++ python/trunk/Python/sysmodule.c	Sun Jul  6 05:35:58 2008
@@ -829,32 +829,12 @@
 Clear the internal type lookup cache.");
 
 
-static PyObject *
-sys_compact_freelists(PyObject* self, PyObject* args)
-{
-	size_t isum, ibc, ibf;
-	size_t fsum, fbc, fbf;
-
-	PyInt_CompactFreeList(&ibc, &ibf, &isum);
-	PyFloat_CompactFreeList(&fbc, &fbf, &fsum);
-
-	return Py_BuildValue("(kkk)(kkk)", isum, ibc, ibf,
-					   fsum, fbc, fbf);
-
-}
-
-PyDoc_STRVAR(sys_compact_freelists__doc__,
-"_compact_freelists() -> ((remaing_objects, total_blocks, freed_blocks), ...)\n\
-Compact the free lists of ints and floats.");
-
 static PyMethodDef sys_methods[] = {
 	/* Might as well keep this in alphabetic order */
 	{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
 	 callstats_doc},
 	{"_clear_type_cache",	sys_clear_type_cache,	  METH_NOARGS,
 	 sys_clear_type_cache__doc__},
-	{"_compact_freelists",	sys_compact_freelists,	  METH_NOARGS,
-	 sys_compact_freelists__doc__},
 	{"_current_frames", sys_current_frames, METH_NOARGS,
 	 current_frames_doc},
 	{"displayhook",	sys_displayhook, METH_O, displayhook_doc},


More information about the Python-checkins mailing list