diff options
| author | Richard M. Stallman | 2007-09-23 15:39:16 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2007-09-23 15:39:16 +0000 |
| commit | 3ae2e3a37fae680f44f23170cc06d160d694b831 (patch) | |
| tree | 8866e4ca5115eb6f396cb8919c01492b250a166c /src/alloc.c | |
| parent | e32725a7f4b176c46cbe62a8ba697ecac30205c2 (diff) | |
| download | emacs-3ae2e3a37fae680f44f23170cc06d160d694b831.tar.gz emacs-3ae2e3a37fae680f44f23170cc06d160d694b831.zip | |
(gc_sweep): Check cons cell mark bits word by word
and optimize the case where they are all 1.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/src/alloc.c b/src/alloc.c index 2599d5c8ad8..9ba21c2c47a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -6028,23 +6028,51 @@ gc_sweep () | |||
| 6028 | 6028 | ||
| 6029 | for (cblk = cons_block; cblk; cblk = *cprev) | 6029 | for (cblk = cons_block; cblk; cblk = *cprev) |
| 6030 | { | 6030 | { |
| 6031 | register int i; | 6031 | register int i = 0; |
| 6032 | int this_free = 0; | 6032 | int this_free = 0; |
| 6033 | for (i = 0; i < lim; i++) | 6033 | int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; |
| 6034 | if (!CONS_MARKED_P (&cblk->conses[i])) | 6034 | |
| 6035 | { | 6035 | /* Scan the mark bits an int at a time. */ |
| 6036 | this_free++; | 6036 | for (i = 0; i <= ilim; i++) |
| 6037 | cblk->conses[i].u.chain = cons_free_list; | 6037 | { |
| 6038 | cons_free_list = &cblk->conses[i]; | 6038 | if (cblk->gcmarkbits[i] == -1) |
| 6039 | { | ||
| 6040 | /* Fast path - all cons cells for this int are marked. */ | ||
| 6041 | cblk->gcmarkbits[i] = 0; | ||
| 6042 | num_used += BITS_PER_INT; | ||
| 6043 | } | ||
| 6044 | else | ||
| 6045 | { | ||
| 6046 | /* Some cons cells for this int are not marked. | ||
| 6047 | Find which ones, and free them. */ | ||
| 6048 | int start, pos, stop; | ||
| 6049 | |||
| 6050 | start = i * BITS_PER_INT; | ||
| 6051 | stop = lim - start; | ||
| 6052 | if (stop > BITS_PER_INT) | ||
| 6053 | stop = BITS_PER_INT; | ||
| 6054 | stop += start; | ||
| 6055 | |||
| 6056 | for (pos = start; pos < stop; pos++) | ||
| 6057 | { | ||
| 6058 | if (!CONS_MARKED_P (&cblk->conses[pos])) | ||
| 6059 | { | ||
| 6060 | this_free++; | ||
| 6061 | cblk->conses[pos].u.chain = cons_free_list; | ||
| 6062 | cons_free_list = &cblk->conses[pos]; | ||
| 6039 | #if GC_MARK_STACK | 6063 | #if GC_MARK_STACK |
| 6040 | cons_free_list->car = Vdead; | 6064 | cons_free_list->car = Vdead; |
| 6041 | #endif | 6065 | #endif |
| 6042 | } | 6066 | } |
| 6043 | else | 6067 | else |
| 6044 | { | 6068 | { |
| 6045 | num_used++; | 6069 | num_used++; |
| 6046 | CONS_UNMARK (&cblk->conses[i]); | 6070 | CONS_UNMARK (&cblk->conses[pos]); |
| 6047 | } | 6071 | } |
| 6072 | } | ||
| 6073 | } | ||
| 6074 | } | ||
| 6075 | |||
| 6048 | lim = CONS_BLOCK_SIZE; | 6076 | lim = CONS_BLOCK_SIZE; |
| 6049 | /* If this block contains only free conses and we have already | 6077 | /* If this block contains only free conses and we have already |
| 6050 | seen more than two blocks worth of free conses then deallocate | 6078 | seen more than two blocks worth of free conses then deallocate |