Change of strategy in the garbage collector.

Previously: when a generation (say 2) is collected, 
  everything in gen 0 moves to gen 1
  everything in gen 1 moves to gen 2
  everything in gen 2 moves to gen 3

Now: when a generation (say 2 again) is collected
  everything in gen 0 moves to gen 3
  everything in gen 1 moves to gen 3
  everything in gen 2 moves to gen 3

So, some objects get a leap from young to old if they're lucky to be
in the right time.

Consequences: when an object is moved by the collector, we don't
need to track old->new pointers and masks because all moved objects
are clean now.  This both simplifies the collector and makes it more
efficient and might open the door for further optimization
opportunities.  For bootstrap time, we get about 5% overall 
saving and about 20% GC-time saving.  Not bad.

BEFORE:
running stats for macro expansion:
    45 collections
    2558 ms elapsed cpu time, including 212 ms collecting
    2576 ms elapsed real time, including 216 ms collecting
    186972152 bytes allocated
running stats for code generation and serialization:
    86 collections
    4365 ms elapsed cpu time, including 1444 ms collecting
    4374 ms elapsed real time, including 1449 ms collecting
    362819096 bytes allocated
running stats for the entire bootstrap process:
    131 collections
    6928 ms elapsed cpu time, including 1657 ms collecting
    6953 ms elapsed real time, including 1666 ms collecting
    549818232 bytes allocated

AFTER:
running stats for macro expansion:
    45 collections
    2506 ms elapsed cpu time, including 169 ms collecting
    2511 ms elapsed real time, including 171 ms collecting
    186968056 bytes allocated
running stats for code generation and serialization:
    86 collections
    4083 ms elapsed cpu time, including 1189 ms collecting
    4085 ms elapsed real time, including 1191 ms collecting
    362810904 bytes allocated
running stats for the entire bootstrap process:
    131 collections
    6591 ms elapsed cpu time, including 1359 ms collecting
    6599 ms elapsed real time, including 1362 ms collecting
    549805944 bytes allocated
Happy Happy Joy Joy
This commit is contained in:
Abdulaziz Ghuloum 2007-12-15 10:43:29 -05:00
parent 5a98c9e460
commit 372c3e369b
2 changed files with 76 additions and 163 deletions

View File

@ -1 +1 @@
1249
1250

View File

@ -88,16 +88,16 @@ static unsigned int meta_mt[meta_count] = {
};
typedef struct gc_t{
meta_t meta[generation_count][meta_count];
meta_t meta [meta_count];
qupages_t* queues [meta_count];
ikpcb* pcb;
unsigned int* segment_vector;
int collect_gen;
int collect_gen_tag;
ikp tconc_ap;
ikp tconc_ep;
ikp tconc_base;
ikpages* tconc_queue;
//ik_guardian_table* final_guardians;
} gc_t;
static unsigned int
@ -110,12 +110,12 @@ next_gen_tag[generation_count] = {
};
static ikp
meta_alloc_extending(int size, int old_gen, gc_t* gc, int meta_id){
meta_alloc_extending(int size, gc_t* gc, int meta_id){
int mapsize = align_to_next_page(size);
if(mapsize < extension_amount[meta_id]){
mapsize = extension_amount[meta_id];
}
meta_t* meta = &gc->meta[old_gen][meta_id];
meta_t* meta = &gc->meta[meta_id];
if((meta_id != meta_data) && meta->base){
qupages_t* p = ik_malloc(sizeof(qupages_t));
ikp aq = meta->aq;
@ -133,7 +133,7 @@ meta_alloc_extending(int size, int old_gen, gc_t* gc, int meta_id){
}
ikp mem = ik_mmap_typed(
mapsize,
meta_mt[meta_id] | next_gen_tag[old_gen],
meta_mt[meta_id] | gc->collect_gen_tag,
gc->pcb);
gc->segment_vector = gc->pcb->segment_vector;
meta->ap = mem + size;
@ -147,14 +147,14 @@ meta_alloc_extending(int size, int old_gen, gc_t* gc, int meta_id){
static inline ikp
meta_alloc(int size, int old_gen, gc_t* gc, int meta_id){
meta_alloc(int size, gc_t* gc, int meta_id){
assert(size == align(size));
meta_t* meta = &gc->meta[old_gen][meta_id];
meta_t* meta = &gc->meta[meta_id];
ikp ap = meta->ap;
ikp ep = meta->ep;
ikp nap = ap + size;
if(nap > ep){
return meta_alloc_extending(size, old_gen, gc, meta_id);
return meta_alloc_extending(size, gc, meta_id);
} else {
meta->ap = nap;
return ap;
@ -162,17 +162,17 @@ meta_alloc(int size, int old_gen, gc_t* gc, int meta_id){
}
static inline ikp
gc_alloc_new_ptr(int size, int old_gen, gc_t* gc){
gc_alloc_new_ptr(int size, gc_t* gc){
assert(size == align(size));
return meta_alloc(size, old_gen, gc, meta_ptrs);
return meta_alloc(size, gc, meta_ptrs);
}
static inline ikp
gc_alloc_new_large_ptr(int size, int old_gen, gc_t* gc){
gc_alloc_new_large_ptr(int size, gc_t* gc){
int memreq = align_to_next_page(size);
ikp mem =
ik_mmap_typed(memreq,
pointers_mt | large_object_tag | next_gen_tag[old_gen],
pointers_mt | large_object_tag | gc->collect_gen_tag,
gc->pcb);
gc->segment_vector = gc->pcb->segment_vector;
qupages_t* p = ik_malloc(sizeof(qupages_t));
@ -186,12 +186,12 @@ gc_alloc_new_large_ptr(int size, int old_gen, gc_t* gc){
static inline void
enqueue_large_ptr(ikp mem, int size, int old_gen, gc_t* gc){
enqueue_large_ptr(ikp mem, int size, gc_t* gc){
int i = page_index(mem);
int j = page_index(mem+size-1);
while(i<=j){
gc->segment_vector[i] =
pointers_mt | large_object_tag | next_gen_tag[old_gen];
pointers_mt | large_object_tag | gc->collect_gen_tag;
i++;
}
qupages_t* p = ik_malloc(sizeof(qupages_t));
@ -202,42 +202,32 @@ enqueue_large_ptr(ikp mem, int size, int old_gen, gc_t* gc){
}
#if 0
static inline ikp
gc_alloc_new_symbol(int old_gen, gc_t* gc){
assert(symbol_size == align(symbol_size));
return meta_alloc(symbol_size, old_gen, gc, meta_symbol);
}
#endif
static inline ikp
gc_alloc_new_symbol_record(int old_gen, gc_t* gc){
gc_alloc_new_symbol_record(gc_t* gc){
assert(symbol_record_size == align(symbol_record_size));
return meta_alloc(symbol_record_size, old_gen, gc, meta_symbol);
return meta_alloc(symbol_record_size, gc, meta_symbol);
}
static inline ikp
gc_alloc_new_pair(int old_gen, gc_t* gc){
return meta_alloc(pair_size, old_gen, gc, meta_pair);
gc_alloc_new_pair(gc_t* gc){
return meta_alloc(pair_size, gc, meta_pair);
}
static inline ikp
gc_alloc_new_weak_pair(int old_gen, gc_t* gc){
meta_t* meta = &gc->meta[old_gen][meta_weak];
gc_alloc_new_weak_pair(gc_t* gc){
meta_t* meta = &gc->meta[meta_weak];
ikp ap = meta->ap;
ikp ep = meta->ep;
ikp nap = ap + pair_size;
if(nap > ep){
ikp mem = ik_mmap_typed(
pagesize,
meta_mt[meta_weak] | next_gen_tag[old_gen],
meta_mt[meta_weak] | gc->collect_gen_tag,
gc->pcb);
gc->segment_vector = gc->pcb->segment_vector;
meta->ap = mem + pair_size;
@ -252,19 +242,19 @@ gc_alloc_new_weak_pair(int old_gen, gc_t* gc){
}
static inline ikp
gc_alloc_new_data(int size, int old_gen, gc_t* gc){
gc_alloc_new_data(int size, gc_t* gc){
assert(size == align(size));
return meta_alloc(size, old_gen, gc, meta_data);
return meta_alloc(size, gc, meta_data);
}
static inline ikp
gc_alloc_new_code(int size, int old_gen, gc_t* gc){
gc_alloc_new_code(int size, gc_t* gc){
assert(size == align(size));
if(size < pagesize){
return meta_alloc(size, old_gen, gc, meta_code);
return meta_alloc(size, gc, meta_code);
} else {
int memreq = align_to_next_page(size);
ikp mem = ik_mmap_code(memreq, next_gen_tag[old_gen], gc->pcb);
ikp mem = ik_mmap_code(memreq, gc->collect_gen, gc->pcb);
gc->segment_vector = gc->pcb->segment_vector;
qupages_t* p = ik_malloc(sizeof(qupages_t));
p->p = mem;
@ -300,8 +290,7 @@ gc_tconc_push_extending(gc_t* gc, ikp tcbucket){
}
ikp ap =
ik_mmap_typed(pagesize,
meta_mt[meta_ptrs] | next_gen_tag[gc->collect_gen],
//meta_mt[meta_ptrs] | next_gen_tag[0],
meta_mt[meta_ptrs] | gc->collect_gen_tag,
gc->pcb);
add_to_collect_count(gc->pcb, pagesize);
gc->segment_vector = gc->pcb->segment_vector;
@ -405,6 +394,7 @@ ik_collect(int mem_req, ikpcb* pcb){
gc.segment_vector = pcb->segment_vector;
gc.collect_gen = collection_id_to_gen(pcb->collection_id);
gc.collect_gen_tag = next_gen_tag[gc.collect_gen];
pcb->collection_id++;
#ifndef NDEBUG
fprintf(stderr, "ik_collect entry %d free=%d (collect gen=%d/id=%d)\n",
@ -918,7 +908,7 @@ add_code_entry(gc_t* gc, ikp entry){
ikp annotation = ref(x, disp_code_annotation);
int required_mem = align(disp_code_data + code_size);
if(required_mem >= pagesize){
int new_tag = next_gen_tag[gen];
int new_tag = gc->collect_gen_tag;
int idx = page_index(x);
gc->segment_vector[idx] = new_tag | code_mt;
int i;
@ -932,7 +922,7 @@ add_code_entry(gc_t* gc, ikp entry){
gc->queues[meta_code] = p;
return entry;
} else {
ikp y = gc_alloc_new_code(required_mem, gen, gc);
ikp y = gc_alloc_new_code(required_mem, gc);
ref(y, 0) = code_tag;
ref(y, disp_code_code_size) = fix(code_size);
ref(y, disp_code_reloc_vector) = reloc_vec;
@ -1066,16 +1056,16 @@ static void collect_stack(gc_t* gc, ikp top, ikp end){
static void
add_list(gc_t* gc, unsigned int t, int gen, ikp x, ikp* loc){
add_list(gc_t* gc, unsigned int t, ikp x, ikp* loc){
int collect_gen = gc->collect_gen;
while(1){
ikp fst = ref(x, off_car);
ikp snd = ref(x, off_cdr);
ikp y;
if((t & type_mask) != weak_pairs_type){
y = gc_alloc_new_pair(gen, gc) + pair_tag;
y = gc_alloc_new_pair(gc) + pair_tag;
} else {
y = gc_alloc_new_weak_pair(gen, gc) + pair_tag;
y = gc_alloc_new_weak_pair(gc) + pair_tag;
}
*loc = y;
ref(x,off_car) = forward_ptr;
@ -1089,7 +1079,7 @@ add_list(gc_t* gc, unsigned int t, int gen, ikp x, ikp* loc){
}
else {
t = gc->segment_vector[page_index(snd)];
gen = t & gen_mask;
int gen = t & gen_mask;
if(gen > collect_gen){
ref(y, off_cdr) = snd;
return;
@ -1145,7 +1135,7 @@ add_object_proc(gc_t* gc, ikp x)
}
if(tag == pair_tag){
ikp y;
add_list(gc, t, gen, x, &y);
add_list(gc, t, x, &y);
return y;
}
#if 0
@ -1175,7 +1165,7 @@ add_object_proc(gc_t* gc, ikp x)
fprintf(stderr, "large closure size=0x%08x\n", size);
}
int asize = align(size);
ikp y = gc_alloc_new_ptr(asize, gen, gc) + closure_tag;
ikp y = gc_alloc_new_ptr(asize, gc) + closure_tag;
ref(y, asize-closure_tag-wordsize) = 0;
memcpy(y-closure_tag, x-closure_tag, size);
ref(y,-closure_tag) = add_code_entry(gc, ref(y,-closure_tag));
@ -1195,11 +1185,11 @@ add_object_proc(gc_t* gc, ikp x)
int memreq = align(size + disp_vector_data);
if(memreq >= pagesize){
if((t & large_object_mask) == large_object_tag){
enqueue_large_ptr(x-vector_tag, size+disp_vector_data, gen, gc);
enqueue_large_ptr(x-vector_tag, size+disp_vector_data, gc);
return x;
} else {
ikp y = gc_alloc_new_large_ptr(size+disp_vector_data, gen, gc) +
vector_tag;
ikp y = gc_alloc_new_large_ptr(size+disp_vector_data, gc)
+ vector_tag;
ref(y, disp_vector_length-vector_tag) = fst;
ref(y, memreq-vector_tag-wordsize) = 0;
memcpy(y+off_vector_data, x+off_vector_data, size);
@ -1208,7 +1198,7 @@ add_object_proc(gc_t* gc, ikp x)
return y;
}
} else {
ikp y = gc_alloc_new_ptr(memreq, gen, gc) + vector_tag;
ikp y = gc_alloc_new_ptr(memreq, gc) + vector_tag;
ref(y, disp_vector_length-vector_tag) = fst;
ref(y, memreq-vector_tag-wordsize) = 0;
memcpy(y+off_vector_data, x+off_vector_data, size);
@ -1221,7 +1211,7 @@ add_object_proc(gc_t* gc, ikp x)
#endif
}
else if(fst == symbol_record_tag){
ikp y = gc_alloc_new_symbol_record(gen, gc) + record_tag;
ikp y = gc_alloc_new_symbol_record(gc) + record_tag;
ref(y, -record_tag) = symbol_record_tag;
ref(y, off_symbol_record_string) = ref(x, off_symbol_record_string);
ref(y, off_symbol_record_ustring) = ref(x, off_symbol_record_ustring);
@ -1239,7 +1229,7 @@ add_object_proc(gc_t* gc, ikp x)
/* size = n * object_alignment + 4 =>
memreq = n * object_alignment + 8
= (n+1) * object_alignment => aligned */
ikp y = gc_alloc_new_ptr(size+wordsize, gen, gc) + vector_tag;
ikp y = gc_alloc_new_ptr(size+wordsize, gc) + vector_tag;
ref(y, -vector_tag) = fst;
{
int i;
@ -1257,7 +1247,7 @@ add_object_proc(gc_t* gc, ikp x)
} else {
/* size = n * object_alignment =>
memreq = n * object_alignment + 4 + 4 (pad) */
ikp y = gc_alloc_new_ptr(size+(2*wordsize), gen, gc) + vector_tag;
ikp y = gc_alloc_new_ptr(size+(2*wordsize), gc) + vector_tag;
ref(y, -vector_tag) = fst;
{
int i;
@ -1288,10 +1278,10 @@ add_object_proc(gc_t* gc, ikp x)
}
#endif
ikp next = ref(x, off_continuation_next);
ikp y = gc_alloc_new_ptr(continuation_size, gen, gc) + vector_tag;
ikp y = gc_alloc_new_ptr(continuation_size, gc) + vector_tag;
ref(x, -vector_tag) = forward_ptr;
ref(x, wordsize-vector_tag) = y;
ikp new_top = gc_alloc_new_data(align(size), gen, gc);
ikp new_top = gc_alloc_new_data(align(size), gc);
memcpy(new_top, top, size);
collect_stack(gc, new_top, new_top + size);
ref(y, -vector_tag) = continuation_tag;
@ -1305,7 +1295,7 @@ add_object_proc(gc_t* gc, ikp x)
}
else if(tagof(fst) == pair_tag){
/* tcbucket */
ikp y = gc_alloc_new_ptr(tcbucket_size, gen, gc) + vector_tag;
ikp y = gc_alloc_new_ptr(tcbucket_size, gc) + vector_tag;
ref(y,off_tcbucket_tconc) = fst;
ikp key = ref(x, off_tcbucket_key);
ref(y,off_tcbucket_key) = key;
@ -1323,7 +1313,7 @@ add_object_proc(gc_t* gc, ikp x)
return y;
}
else if((((int)fst) & port_mask) == port_tag){
ikp y = gc_alloc_new_ptr(port_size, gen, gc) + vector_tag;
ikp y = gc_alloc_new_ptr(port_size, gc) + vector_tag;
ref(y, -vector_tag) = fst;
int i;
for(i=wordsize; i<port_size; i+=wordsize){
@ -1334,7 +1324,7 @@ add_object_proc(gc_t* gc, ikp x)
return y;
}
else if(fst == flonum_tag){
ikp new = gc_alloc_new_data(flonum_size, gen, gc) + vector_tag;
ikp new = gc_alloc_new_data(flonum_size, gc) + vector_tag;
ref(new, -vector_tag) = flonum_tag;
flonum_data(new) = flonum_data(x);
ref(x, -vector_tag) = forward_ptr;
@ -1344,14 +1334,14 @@ add_object_proc(gc_t* gc, ikp x)
else if((((int)fst) & bignum_mask) == bignum_tag){
int len = ((unsigned int)fst) >> bignum_length_shift;
int memreq = align(disp_bignum_data + len*wordsize);
ikp new = gc_alloc_new_data(memreq, gen, gc) + vector_tag;
ikp new = gc_alloc_new_data(memreq, gc) + vector_tag;
memcpy(new-vector_tag, x-vector_tag, memreq);
ref(x, -vector_tag) = forward_ptr;
ref(x, wordsize-vector_tag) = new;
return new;
}
else if(fst == ratnum_tag){
ikp y = gc_alloc_new_data(ratnum_size, gen, gc) + vector_tag;
ikp y = gc_alloc_new_data(ratnum_size, gc) + vector_tag;
ikp num = ref(x, disp_ratnum_num-vector_tag);
ikp den = ref(x, disp_ratnum_den-vector_tag);
ref(x, -vector_tag) = forward_ptr;
@ -1371,7 +1361,7 @@ add_object_proc(gc_t* gc, ikp x)
if(is_fixnum(fst)){
int strlen = unfix(fst);
int memreq = align(strlen*string_char_size + disp_string_data);
ikp new_str = gc_alloc_new_data(memreq, gen, gc) + string_tag;
ikp new_str = gc_alloc_new_data(memreq, gc) + string_tag;
ref(new_str, off_string_length) = fst;
memcpy(new_str+off_string_data,
x + off_string_data,
@ -1392,7 +1382,7 @@ add_object_proc(gc_t* gc, ikp x)
else if(tag == bytevector_tag){
int len = unfix(fst);
int memreq = align(len + disp_bytevector_data + 1);
ikp new_bv = gc_alloc_new_data(memreq, gen, gc) + bytevector_tag;
ikp new_bv = gc_alloc_new_data(memreq, gc) + bytevector_tag;
ref(new_bv, off_bytevector_length) = fst;
memcpy(new_bv+off_bytevector_data,
x + off_bytevector_data,
@ -1549,9 +1539,8 @@ collect_loop(gc_t* gc){
}
}
{/* see if there are any remaining in the main ptr segment */
int i;
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_pair];
{
meta_t* meta = &gc->meta[meta_pair];
ikp p = meta->aq;
ikp q = meta->ap;
if(p < q){
@ -1567,8 +1556,8 @@ collect_loop(gc_t* gc){
} while (p < q);
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_symbol];
{
meta_t* meta = &gc->meta[meta_symbol];
ikp p = meta->aq;
ikp q = meta->ap;
if(p < q){
@ -1584,8 +1573,8 @@ collect_loop(gc_t* gc){
} while (p < q);
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_ptrs];
{
meta_t* meta = &gc->meta[meta_ptrs];
ikp p = meta->aq;
ikp q = meta->ap;
if(p < q){
@ -1601,8 +1590,8 @@ collect_loop(gc_t* gc){
} while (p < q);
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_code];
{
meta_t* meta = &gc->meta[meta_code];
ikp p = meta->aq;
ikp q = meta->ap;
if(p < q){
@ -1623,9 +1612,10 @@ collect_loop(gc_t* gc){
/* phew */
} while (! done);
{
int i;
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_pair];
/* zero out remaining pointers */
/* FIXME: did you hear of code reuse? */
{
meta_t* meta = &gc->meta[meta_pair];
ikp p = meta->ap;
ikp q = meta->ep;
while(p < q){
@ -1633,8 +1623,8 @@ collect_loop(gc_t* gc){
p += wordsize;
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_symbol];
{
meta_t* meta = &gc->meta[meta_symbol];
ikp p = meta->ap;
ikp q = meta->ep;
while(p < q){
@ -1642,8 +1632,8 @@ collect_loop(gc_t* gc){
p += wordsize;
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_ptrs];
{
meta_t* meta = &gc->meta[meta_ptrs];
ikp p = meta->ap;
ikp q = meta->ep;
while(p < q){
@ -1651,8 +1641,8 @@ collect_loop(gc_t* gc){
p += wordsize;
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_weak];
{
meta_t* meta = &gc->meta[meta_weak];
ikp p = meta->ap;
ikp q = meta->ep;
while(p < q){
@ -1660,8 +1650,8 @@ collect_loop(gc_t* gc){
p += wordsize;
}
}
for(i=0; i<=gc->collect_gen; i++){
meta_t* meta = &gc->meta[i][meta_code];
{
meta_t* meta = &gc->meta[meta_code];
ikp p = meta->ap;
ikp q = meta->ep;
while(p < q){
@ -1901,100 +1891,23 @@ static void
fix_new_pages(gc_t* gc){
ikpcb* pcb = gc->pcb;
unsigned int* segment_vec = pcb->segment_vector;
unsigned int* dirty_vec = pcb->dirty_vector;
unsigned char* memory_base = pcb->memory_base;
unsigned char* memory_end = pcb->memory_end;
int lo_idx = page_index(memory_base);
int hi_idx = page_index(memory_end);
int i = lo_idx;
while(i < hi_idx){
segment_vec[i] &= ~new_gen_mask;
/*
unsigned int t = segment_vec[i];
// if((t & new_gen_mask) ||
// ((t & type_mask) == weak_pairs_type)){
if(t & new_gen_mask){
segment_vec[i] = t & ~new_gen_mask;
int page_gen = t & old_gen_mask;
if(((t & type_mask) == pointers_type) ||
((t & type_mask) == symbols_type) ||
((t & type_mask) == weak_pairs_type) ){
ikp p = (ikp)(i << pageshift);
unsigned int d = 0;
int j;
for(j=0; j<cards_per_page; j++){
ikp q = p + cardsize;
unsigned int card_d = 0;
while(p < q){
ikp x = ref(p, 0);
if(is_fixnum(x) || (tagof(x) == immediate_tag)){
/* nothing */
} else {
card_d = card_d | segment_vec[page_index(x)];
}
p += wordsize;
}
card_d = (card_d & meta_dirty_mask) >> meta_dirty_shift;
d = d | (card_d<<(j*meta_dirty_shift));
}
dirty_vec[i] = d & cleanup_mask[page_gen];
}
else if((t & type_mask) == code_type){
/* FIXME: scan codes */
ikp page_base = (ikp)(i << pageshift);
ikp p = page_base;
ikp q = p + pagesize;
#if 0
junk int err = mprotect(page_base, pagesize, PROT_READ|PROT_WRITE|PROT_EXEC);
if(err){
fprintf(stderr, "cannot protect code page: %s\n", strerror(errno));
exit(-1);
}
#endif
unsigned int d = 0;
while(p < q){
if(ref(p, 0) != code_tag){
p = q;
}
else {
ikp rvec = ref(p, disp_code_reloc_vector);
int size = (int)ref(rvec, off_vector_length);
ikp vp = rvec + off_vector_data;
ikp vq = vp + size;
unsigned int code_d = segment_vec[page_index(rvec)];
while(vp < vq){
ikp x = ref(vp, 0);
if(is_fixnum(x) || (tagof(x) == immediate_tag)){
/* do nothing */
} else {
code_d = code_d | segment_vec[page_index(x)];
}
vp += wordsize;
}
code_d = (code_d & meta_dirty_mask) >> meta_dirty_shift;
int j = ((int)p - (int)page_base)/cardsize;
assert(j < cards_per_page);
d = d | (code_d<<(j*meta_dirty_shift));
p += align(disp_code_data + unfix(ref(p, disp_code_code_size)));
}
}
#ifndef NDEBUG
fprintf(stderr, " %p = 0x%08x & 0x%08x = 0x%08x\n",
page_base, d, cleanup_mask[page_gen], d &
cleanup_mask[page_gen]);
#endif
dirty_vec[i] = d & cleanup_mask[page_gen];
}
else {
if(t & scannable_mask){
fprintf(stderr, "unscanned 0x%08x\n", t);
exit(-1);
}
}
}
*/
i++;
}
}
static void
add_one_tconc(ikpcb* pcb, ikp p){
ikp tcbucket = ref(p,0);