[Python-checkins] r42746 - python/branches/tim-obmalloc/Objects/obmalloc.c

tim.peters python-checkins at python.org
Wed Mar 1 23:01:39 CET 2006


Author: tim.peters
Date: Wed Mar  1 23:01:38 2006
New Revision: 42746

Modified:
   python/branches/tim-obmalloc/Objects/obmalloc.c
Log:
Heroic attempts to get lines under 80 columns.

Resolved all new XXX except for the critical one:
Py_ADDRESS_IN_RANGE is still broken in an endcase
by the new logic, and I still haven't thought of
a way to fix that "for free".


Modified: python/branches/tim-obmalloc/Objects/obmalloc.c
==============================================================================
--- python/branches/tim-obmalloc/Objects/obmalloc.c	(original)
+++ python/branches/tim-obmalloc/Objects/obmalloc.c	Wed Mar  1 23:01:38 2006
@@ -494,10 +494,8 @@
 
 /* Allocate a new arena.  If we run out of memory, return NULL.  Else
  * allocate a new arena, and return the address of an arena_object
- * descriptor describing the new arena.  The `prevarena` and `freepools`
- * members of the arena_object are left as uninitialized trash.  XXX
- * That last sentence isn't true right now (it's all zero filled, but don't
- * know yet why we bother to do that).
+ * descriptor describing the new arena.  It's expected that the caller will
+ * set `usable_arenas` to the return value.
  */
 static struct arena_object*
 new_arena(void)
@@ -509,7 +507,6 @@
 	if (Py_GETENV("PYTHONMALLOCSTATS"))
 		_PyObject_DebugMallocStats();
 #endif
-
 	if (available_arenas == NULL) {
 		uint i;
 		uint numarenas;
@@ -538,16 +535,12 @@
 		assert(usable_arenas == NULL);
 		assert(available_arenas == NULL);
 
-		/* Zero fill the new section of the array. */
-		/* XXX Why? */
-		memset(&(arenas[maxarenas]), 0,
-		       sizeof(*arenas) * (numarenas - maxarenas));
-
 		/* Put the new arenas on the available_arenas list. */
-		for (i = maxarenas; i < numarenas-1; ++i)
-			arenas[i].nextarena = &arenas[i+1];
-		/* The last new arenaobj still points to NULL. */
-		assert(arenas[numarenas-1].nextarena == NULL);
+		for (i = maxarenas; i < numarenas; ++i) {
+			arenas[i].address = 0;	/* mark as unassociated */
+			arenas[i].nextarena = i < numarenas - 1 ?
+					       &arenas[i+1] : NULL;
+		}
 
 		/* Update globals. */
 		available_arenas = &arenas[maxarenas];
@@ -557,16 +550,10 @@
 	/* Take the next available arena object off the head of the list. */
 	assert(available_arenas != NULL);
 	arenaobj = available_arenas;
-	available_arenas = available_arenas->nextarena;
-
-	assert(arenaobj->address == (uptr)NULL);
-
-	/* Fill the newly allocated or reused arena object with zeros. */
-	/* XXX Why? */
-	memset(arenaobj, 0, sizeof(*arenaobj));
-
+	available_arenas = arenaobj->nextarena;
+	assert(arenaobj->address == 0);
 	arenaobj->address = (uptr)malloc(ARENA_SIZE);
-	if (arenaobj->address == (uptr)NULL) {
+	if (arenaobj->address == 0) {
 		/* The allocation failed: return NULL after putting the
 		 * arenaobj back.
 		 */
@@ -581,12 +568,13 @@
 	if (narenas_currently_allocated > narenas_highwater)
 		narenas_highwater = narenas_currently_allocated;
 #endif
+	arenaobj->freepools = NULL;
 	/* pool_address <- first pool-aligned address in the arena
 	   nfreepools <- number of whole pools that fit after alignment */
 	arenaobj->pool_address = (block*)arenaobj->address;
 	arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE;
 	assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE);
-	excess = (uint)((Py_uintptr_t)arenaobj->address & POOL_SIZE_MASK);
+	excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
 	if (excess != 0) {
 		--arenaobj->nfreepools;
 		arenaobj->pool_address += POOL_SIZE - excess;
@@ -746,6 +734,8 @@
 				UNLOCK();
 				goto redirect;
 			}
+			usable_arenas->nextarena =
+				usable_arenas->prevarena = NULL;
 		}
 		assert(usable_arenas->address != 0);
 
@@ -888,7 +878,8 @@
 		*(block **)p = lastfree = pool->freeblock;
 		pool->freeblock = (block *)p;
 		if (lastfree) {
-			struct arena_object* arenaobj;
+			struct arena_object* ao;
+			uint nf;  /* ao->nfreepools */
 
 			/* freeblock wasn't NULL, so the pool wasn't full,
 			 * and the pool is in a usedpools[] list.
@@ -911,72 +902,65 @@
 			/* Link the pool to freepools.  This is a singly-linked
 			 * list, and pool->prevpool isn't used there.
 			 */
-			arenaobj = &arenas[pool->arenaindex];
-			pool->nextpool = arenaobj->freepools;
-			arenaobj->freepools = pool;
-			++arenaobj->nfreepools;
+			ao = &arenas[pool->arenaindex];
+			pool->nextpool = ao->freepools;
+			ao->freepools = pool;
+			nf = ++ao->nfreepools;
 
-			if (arenaobj->nfreepools == arenaobj->ntotalpools) {
-				void* address;
+			if (nf == ao->ntotalpools) {
 				/* This arena is completely deallocated.
 				 * Unlink it from the partially allocated
 				 * arenas.
 				 */
-				assert(arenaobj->prevarena == NULL ||
-				       arenaobj->prevarena->address !=
-				       (uptr)NULL);
-				assert(arenaobj->nextarena == NULL ||
-				       arenaobj->nextarena->address !=
-				       (uptr)NULL);
+				assert(ao->prevarena == NULL ||
+				       ao->prevarena->address != 0);
+				assert(ao ->nextarena == NULL ||
+				       ao->nextarena->address != 0);
 
 				/* Fix the pointer in the prevarena, or the
-				 * usable_arenas pointer
+				 * usable_arenas pointer.
 				 */
-				if (arenaobj->prevarena == NULL) {
-					usable_arenas = arenaobj->nextarena;
+				if (ao->prevarena == NULL) {
+					usable_arenas = ao->nextarena;
 					assert(usable_arenas == NULL ||
 					       usable_arenas->address != 0);
 				}
 				else {
-					assert(arenaobj->prevarena->nextarena ==
-					       arenaobj);
-					arenaobj->prevarena->nextarena =
-						arenaobj->nextarena;
+					assert(ao->prevarena->nextarena == ao);
+					ao->prevarena->nextarena =
+						ao->nextarena;
 				}
 
 				/* Fix the pointer in the nextarena. */
-				if (arenaobj->nextarena != NULL) {
-					assert(arenaobj->nextarena->prevarena ==
-						arenaobj);
-					arenaobj->nextarena->prevarena =
-						arenaobj->prevarena;
+				if (ao->nextarena != NULL) {
+					assert(ao->nextarena->prevarena == ao);
+					ao->nextarena->prevarena =
+						ao->prevarena;
 				}
 
-				/* Record that this arena slot is available to
-				 * be reused.
+				/* Record that this arena_object slot is
+				 * available to be reused.
 				 */
-				arenaobj->nextarena = available_arenas;
-				available_arenas = arenaobj;
+				ao->nextarena = available_arenas;
+				available_arenas = ao;
 
 				/* Free the entire arena. */
-				address = (void *)arenaobj->address;
-				arenaobj->address = (uptr)NULL;
-				free(address);
+				free((void *)ao->address);
+				ao->address = 0;
 				--narenas_currently_allocated;
-
 			}
-			else if (arenaobj->nfreepools == 1) {
+			else if (nf == 1) {
 				/* If this arena was completely allocated,
 				 * go link it to the head of the partially
 				 * allocated list.
 				 */
-				arenaobj->nextarena = usable_arenas;
-				arenaobj->prevarena = NULL;
-				usable_arenas = arenaobj;
+				ao->nextarena = usable_arenas;
+				ao->prevarena = NULL;
+				usable_arenas = ao;
 
 				/* Fix the pointer in the nextarena. */
-				if (arenaobj->nextarena != NULL)
-					arenaobj->nextarena->prevarena = arenaobj;
+				if (ao->nextarena != NULL)
+					ao->nextarena->prevarena = ao;
 
 				assert(usable_arenas->address != 0);
 			}
@@ -987,60 +971,56 @@
 			 * a few un-scientific tests, it seems like this
 			 * approach allowed a lot more memory to be freed.
 			 */
-			else if (arenaobj->nextarena != NULL &&
-				 arenaobj->nfreepools >
-				 arenaobj->nextarena->nfreepools) {
+			else if (ao->nextarena != NULL &&
+				     nf > ao->nextarena->nfreepools) {
 				/* We have to move the arena towards the end
 				 * of the list.
 				 */
 				struct arena_object** lastPointer;
-				if (arenaobj->prevarena != NULL)
-					lastPointer = &arenaobj->prevarena->nextarena;
+				if (ao->prevarena != NULL)
+					lastPointer =
+						&ao->prevarena->nextarena;
 				else
 					lastPointer = &usable_arenas;
-				assert(*lastPointer == arenaobj);
+				assert(*lastPointer == ao);
 
 				/* Step one: unlink the arena from the list. */
-				*lastPointer = arenaobj->nextarena;
-				arenaobj->nextarena->prevarena = arenaobj->prevarena;
+				*lastPointer = ao->nextarena;
+				ao->nextarena->prevarena = ao->prevarena;
 
 				/* Step two: Locate the new insertion point by
 				 * iterating over the list, using our nextarena
 				 * pointer.
 				 */
-				while (arenaobj->nextarena != NULL &&
-					  arenaobj->nfreepools >
-					  arenaobj->nextarena->nfreepools) {
-					arenaobj->prevarena = arenaobj->nextarena;
-					arenaobj->nextarena = arenaobj->nextarena->nextarena;
+				while (ao->nextarena != NULL &&
+					 nf > ao->nextarena->nfreepools) {
+					ao->prevarena = ao->nextarena;
+					ao->nextarena =
+						ao->nextarena->nextarena;
 				}
 
 				/* Step three: insert the arena at this point. */
-				assert(arenaobj->nextarena == NULL ||
-					arenaobj->prevarena ==
-					arenaobj->nextarena->prevarena);
-				assert(arenaobj->prevarena->nextarena ==
-					arenaobj->nextarena);
-
-				arenaobj->prevarena->nextarena = arenaobj;
-				if (arenaobj->nextarena != NULL) {
-					arenaobj->nextarena->prevarena = arenaobj;
+				assert(ao->nextarena == NULL ||
+					ao->prevarena ==
+					    ao->nextarena->prevarena);
+				assert(ao->prevarena->nextarena ==
+					ao->nextarena);
+
+				ao->prevarena->nextarena = ao;
+				if (ao->nextarena != NULL) {
+					ao->nextarena->prevarena = ao;
 				}
 
 				/* Verify that the swaps worked. */
-				assert(arenaobj->nextarena == NULL ||
-					arenaobj->nfreepools <=
-					arenaobj->nextarena->nfreepools);
-				assert(arenaobj->prevarena == NULL ||
-					arenaobj->nfreepools >
-					arenaobj->prevarena->nfreepools);
-				assert(arenaobj->nextarena == NULL ||
-					arenaobj->nextarena->prevarena ==
-					arenaobj);
-				assert((usable_arenas == arenaobj &&
-					arenaobj->prevarena == NULL) ||
-					arenaobj->prevarena->nextarena ==
-					arenaobj);
+				assert(ao->nextarena == NULL ||
+					  nf <= ao->nextarena->nfreepools);
+				assert(ao->prevarena == NULL ||
+					  nf > ao->prevarena->nfreepools);
+				assert(ao->nextarena == NULL ||
+					ao->nextarena->prevarena == ao);
+				assert((usable_arenas == ao &&
+					ao->prevarena == NULL) ||
+					ao->prevarena->nextarena == ao);
 			}
 
 			UNLOCK();


More information about the Python-checkins mailing list