]> git.eshelyaron.com Git - emacs.git/commitdiff
(gc_sweep): Check cons cell mark bits word by word
authorRichard M. Stallman <rms@gnu.org>
Sun, 23 Sep 2007 15:39:16 +0000 (15:39 +0000)
committerRichard M. Stallman <rms@gnu.org>
Sun, 23 Sep 2007 15:39:16 +0000 (15:39 +0000)
and optimize the case where they are all 1.

src/ChangeLog
src/alloc.c

index 1ee960f80c44e3ca0fcb3d452a80ffee92ef1cbe..8356d0ea04f49eab1443e11b03e2b01bac8d930e 100644 (file)
@@ -1,8 +1,13 @@
+2007-09-23  Dmitry Antipov  <dmantipov@yandex.ru>
+
+       * alloc.c (gc_sweep): Check cons cell mark bits word by word
+       and optimize the case where they are all 1.
+
 2007-09-23  Johannes Weiner  <hannes@saeurebad.de>
 
-       * lisp.h (abs): Define if unknown.
-       * keyboard.c, sound.c, w32term.c, xfaces.c, xterm.c: Don't
-       define abs now it's in lisp.h.
+       * lisp.h (abs): Define if not defined.
+       * keyboard.c, sound.c, w32term.c, xfaces.c, xterm.c:
+       Don't define `abs', since it's defined in lisp.h.
 
 2007-09-22  Eli Zaretskii  <eliz@gnu.org>
 
index 2599d5c8ad8ab4529f37393489fc79d59be82573..9ba21c2c47a63afeef30bae6c13bb170a76e9999 100644 (file)
@@ -6028,23 +6028,51 @@ gc_sweep ()
 
     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