Mercurial > emacs
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