Index: alloc.c =================================================================== RCS file: /sources/emacs/emacs/src/alloc.c,v retrieving revision 1.414 diff -u -r1.414 alloc.c --- alloc.c 19 Aug 2007 00:15:26 -0000 1.414 +++ alloc.c 21 Aug 2007 14:31:37 -0000 @@ -5974,23 +5974,53 @@ 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]; + + while (1) + { + if (cblk->gcmarkbits[i] == -1) + { + /* Fast path - everything is marked. */ + cblk->gcmarkbits[i++] = 0; + num_used += BITS_PER_INT; + } + else + { + /* Slow path - scan over each bit, from the beginning + of current word to 'min (word boundary, LIM)'. */ + int start, stop; + + start = i * BITS_PER_INT; + stop = lim - start; + if (stop > BITS_PER_INT) + stop = BITS_PER_INT; + stop += start; + + while (start < stop) + { + if (!CONS_MARKED_P (&cblk->conses[start])) + { + this_free++; + cblk->conses[start].u.chain = cons_free_list; + cons_free_list = &cblk->conses[start]; #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[start]); + } + start++; + } + if (stop < (++i) * BITS_PER_INT) + /* Whole bitmap is scanned or LIM is reached. */ + break; + } + } + 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