# HG changeset patch # User Richard M. Stallman # Date 1190561833 0 # Node ID 4d1c866492b0866b348788a65b242a498a67b268 # Parent 022950ce616ad8383c7293b0cd884e8741990632 (gc_sweep): Check cons cell mark bits word by word and optimize the case where they are all 1. diff -r 022950ce616a -r 4d1c866492b0 src/alloc.c --- 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