changeset 84816:4d1c866492b0

(gc_sweep): Check cons cell mark bits word by word and optimize the case where they are all 1.
author Richard M. Stallman <rms@gnu.org>
date Sun, 23 Sep 2007 15:37:13 +0000
parents 022950ce616a
children 003b4ae4b791
files src/alloc.c
diffstat 1 files changed, 42 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/alloc.c	Sun Sep 23 15:32:17 2007 +0000
+++ b/src/alloc.c	Sun Sep 23 15:37:13 2007 +0000
@@ -6028,23 +6028,51 @@
 
     for (cblk = cons_block; cblk; cblk = *cprev)
       {
-	register int i;
+	register int i = 0;
 	int this_free = 0;
-	for (i = 0; i < lim; i++)
-	  if (!CONS_MARKED_P (&cblk->conses[i]))
-	    {
-	      this_free++;
-	      cblk->conses[i].u.chain = cons_free_list;
-	      cons_free_list = &cblk->conses[i];
+	int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT;
+
+	/* Scan the mark bits an int at a time.  */
+	for (i = 0; i <= ilim; i++)
+	  {
+	    if (cblk->gcmarkbits[i] == -1)
+	      {
+		/* Fast path - all cons cells for this int are marked.  */
+		cblk->gcmarkbits[i] = 0;
+		num_used += BITS_PER_INT;
+	      }
+	    else
+	      {
+		/* Some cons cells for this int are not marked.
+		   Find which ones, and free them.  */
+		int start, pos, stop;
+
+		start = i * BITS_PER_INT;
+		stop = lim - start;
+		if (stop > BITS_PER_INT)
+		  stop = BITS_PER_INT;
+		stop += start;
+
+		for (pos = start; pos < stop; pos++)
+		  {
+		    if (!CONS_MARKED_P (&cblk->conses[pos]))
+		      {
+			this_free++;
+			cblk->conses[pos].u.chain = cons_free_list;
+			cons_free_list = &cblk->conses[pos];
 #if GC_MARK_STACK
-	      cons_free_list->car = Vdead;
+			cons_free_list->car = Vdead;
 #endif
-	    }
-	  else
-	    {
-	      num_used++;
-	      CONS_UNMARK (&cblk->conses[i]);
-	    }
+		      }
+		    else
+		      {
+			num_used++;
+			CONS_UNMARK (&cblk->conses[pos]);
+		      }
+		  }
+	      }
+	  }
+
 	lim = CONS_BLOCK_SIZE;
 	/* If this block contains only free conses and we have already
 	   seen more than two blocks worth of free conses then deallocate