diff --git a/bin/ikarus b/bin/ikarus index cf28c8e..0c361e5 100755 Binary files a/bin/ikarus and b/bin/ikarus differ diff --git a/bin/ikarus-collect.c b/bin/ikarus-collect.c index 497690c..88331a4 100644 --- a/bin/ikarus-collect.c +++ b/bin/ikarus-collect.c @@ -79,7 +79,7 @@ typedef struct gc_t{ ikp tconc_ep; ikp tconc_base; ikpages* tconc_queue; - ik_guardian_table* final_guardians; + //ik_guardian_table* final_guardians; } gc_t; static unsigned int @@ -581,91 +581,112 @@ is_live(ikp x, gc_t* gc){ return 0; } -static ik_guardian_table* -move_guardian(ikp tc, ikp obj, ik_guardian_table* t){ - if(t && (t->count < ik_guardian_table_size)){ - ik_guardian_pair* p = &t->p[t->count]; - p->tc = tc; - p->obj = obj; - t->count++; - return t; - } else { - ik_guardian_table* nt = - (ik_guardian_table*)ik_mmap(sizeof(ik_guardian_table)); - nt->next = t; - nt->count = 1; - nt->p[0].tc = tc; - nt->p[0].obj = obj; - return nt; - } -} - static inline int next_gen(int i){ return ((i == generation_count) ? generation_count : (i+1)); } +static ik_ptr_page* +move_guarded(ikp x, ik_ptr_page* dst){ + if((dst == 0) || (dst->count == ik_ptr_page_size)){ + ik_ptr_page* y = ik_mmap(sizeof(ik_ptr_page)); + y->count = 0; + y->next = dst; + dst = y; + } + dst->ptr[dst->count++] = x; + return dst; +} + + static void forward_guardians(gc_t* gc){ ikpcb* pcb = gc->pcb; int gen; + ik_ptr_page* forward_list[generation_count]; for(gen = gc->collect_gen; gen>=0; gen--){ /* must move backwards from older to younger generations */ - ikp todo = pcb->guardians[gen]; - pcb->guardians[gen] = null_object; - ikp forward = pcb->guardians[next_gen(gen)]; - ikp dropped = null_object; - while(todo != null_object){ - ikp next = ref(todo, off_cdr); - ikp a = ref(todo, off_car); - /* ikp tc = ref(a, off_car); */ - ikp obj = ref(a, off_cdr); - if(is_live(obj, gc)){ - ref(todo, off_cdr) = forward; - forward = todo; - } else { - ref(todo, off_cdr) = dropped; - dropped = todo; + ik_ptr_page* todo = pcb->guardians[gen]; + pcb->guardians[gen] = 0; + ik_ptr_page* forward = 0; + ik_ptr_page* dropped = 0; + while(todo){ + int i; + int n = todo->count; + for(i=0; iptr[i]; + ikp obj = ref(a, off_cdr); + if(is_live(obj, gc)){ + forward = move_guarded(a, forward); + } else { + dropped = move_guarded(a, dropped); + } } + ik_ptr_page* next = todo->next; + ik_munmap(todo, sizeof(ik_ptr_page)); todo = next; } - pcb->guardians[next_gen(gen)] = forward; + forward_list[gen] = forward; pcb->guardians_dropped[gen] = dropped; } - for(gen = next_gen(gc->collect_gen); gen>=0; gen--){ - pcb->guardians[gen] = add_object(gc, pcb->guardians[gen], "guardians"); + for(gen=0; gen<=gc->collect_gen; gen++){ + ik_ptr_page* src = forward_list[gen]; + ik_ptr_page* dst = pcb->guardians[next_gen(gen)]; + while(src){ + int i; + int n = src->count; + for(i=0; iptr[i], "prot"); + dst = move_guarded(a, dst); + } + ik_ptr_page* next = src->next; + ik_munmap(src, sizeof(ik_ptr_page)); + src = next; + } + pcb->guardians[next_gen(gen)] = dst; } - for(gen = gc->collect_gen; gen>=0; gen--){ - pcb->guardians_dropped[gen] = - add_object(gc, pcb->guardians_dropped[gen], "guardians dropped"); + for(gen = 0; gen<=gc->collect_gen; gen++){ + ik_ptr_page* src = pcb->guardians_dropped[gen]; + while(src){ + int i; + int n = src->count; + for(i=0; iptr[i] = add_object(gc, src->ptr[i], "prot"); + } + src = src->next; + } } - } static void empty_dropped_guardians(gc_t* gc){ ikpcb* pcb = gc->pcb; int gen; - for(gen = gc->collect_gen; gen>=0; gen--){ - ikp ls = pcb->guardians_dropped[gen]; - while(ls != null_object){ - ikp next = ref(ls, off_cdr); - ikp a = ref(ls, off_car); - ikp tc = ref(a, off_car); - ikp obj = ref(a, off_cdr); - assert(tagof(tc) == pair_tag); - ikp d = ref(tc, off_cdr); - assert(tagof(d) == pair_tag); - ref(d, off_car) = obj; - ref(d, off_cdr) = a; - ref(a, off_car) = false_object; - ref(a, off_cdr) = false_object; - ref(tc, off_cdr) = a; - pcb->dirty_vector[page_index(tc)] = -1; - pcb->dirty_vector[page_index(d)] = -1; - ls = next; + for(gen = 0; gen<=gc->collect_gen; gen++){ + ik_ptr_page* src = pcb->guardians_dropped[gen]; + while(src){ + int i; + int n = src->count; + for(i=0; iptr[i]; + ikp tc = ref(a, off_car); + ikp obj = ref(a, off_cdr); + assert(tagof(tc) == pair_tag); + ikp d = ref(tc, off_cdr); + assert(tagof(d) == pair_tag); + ref(d, off_car) = obj; + ref(d, off_cdr) = a; + ref(a, off_car) = false_object; + ref(a, off_cdr) = false_object; + ref(tc, off_cdr) = a; + pcb->dirty_vector[page_index(tc)] = -1; + pcb->dirty_vector[page_index(d)] = -1; + } + ik_ptr_page* next = src->next; + ik_munmap(src, sizeof(ik_ptr_page)); + src = next; } - pcb->guardians_dropped[gen] = null_object; + pcb->guardians_dropped[gen] = 0; } } diff --git a/bin/ikarus-runtime.c b/bin/ikarus-runtime.c index 9d67c3c..31c79fa 100644 --- a/bin/ikarus-runtime.c +++ b/bin/ikarus-runtime.c @@ -264,14 +264,6 @@ ikpcb* ik_make_pcb(){ ikpcb* pcb = ik_malloc(sizeof(ikpcb)); bzero(pcb, sizeof(ikpcb)); pcb->collect_key = false_object; - { - int i; - for(i=0; iguardians[i] = null_object; - pcb->guardians_forward[i] = null_object; - pcb->guardians_dropped[i] = null_object; - } - } #define HEAPSIZE (1024 * 4096) #define STAKSIZE (1024 * 4096) //#define STAKSIZE (256 * 4096) @@ -893,40 +885,27 @@ ikrt_write_char(){ -#if 0 -ikp -ikrt_register_guardian(ikp tc, ikp obj, ikpcb* pcb){ - ik_guardian_table* g = pcb->guardians[0]; - if((!g) || (g->count == ik_guardian_table_size)){ - if(sizeof(ik_guardian_table) != pagesize){ - fprintf(stderr, "ERR: invalid guardian table size\n"); - exit(-1); - } - ik_guardian_table* p = - (ik_guardian_table*)ik_mmap(sizeof(ik_guardian_table)); - p->next = g; - p->count = 0; - pcb->guardians[0] = p; - g=p; - } - ik_guardian_pair* p = &(g->p[g->count]); - p->tc = tc; - p->obj = obj; - g->count++; - return 0; +ikp +ikrt_register_guardian_pair(ikp p0, ikpcb* pcb){ + ik_ptr_page* x = pcb->guardians[0]; + if((x == NULL) || (x->count == ik_ptr_page_size)){ + assert(sizeof(ik_ptr_page) == pagesize); + ik_ptr_page* y = ik_mmap(pagesize); + y->count = 0; + y->next = x; + pcb->guardians[0] = y; + x = y; + } + x->ptr[x->count++] = p0; + return void_object; } -#endif ikp ikrt_register_guardian(ikp tc, ikp obj, ikpcb* pcb){ ikp p0 = ik_alloc(pcb, pair_size) + pair_tag; - ikp p1 = ik_alloc(pcb, pair_size) + pair_tag; ref(p0, off_car) = tc; ref(p0, off_cdr) = obj; - ref(p1, off_car) = p0; - ref(p1, off_cdr) = pcb->guardians[0]; - pcb->guardians[0] = p1; - return void_object; + return ikrt_register_guardian_pair(p0, pcb); } diff --git a/bin/ikarus.h b/bin/ikarus.h index af25e2c..01766b1 100644 --- a/bin/ikarus.h +++ b/bin/ikarus.h @@ -90,20 +90,16 @@ typedef struct ikdl{ /* double-link */ struct ikdl* next; } ikdl; -typedef struct ik_guardian_pair{ - ikp tc; - ikp obj; -} ik_guardian_pair; -#define ik_guardian_table_size \ - ((pagesize - sizeof(int) - sizeof(struct ik_guardian_table*))/sizeof(ik_guardian_pair)) +#define ik_ptr_page_size \ + ((pagesize - sizeof(int) - sizeof(struct ik_ptr_page*))/sizeof(ikp)) -typedef struct ik_guardian_table{ +typedef struct ik_ptr_page{ int count; - struct ik_guardian_table* next; - ik_guardian_pair p[ik_guardian_table_size]; -} ik_guardian_table; - + struct ik_ptr_page* next; + ikp ptr[ik_ptr_page_size]; +} ik_ptr_page; + typedef struct ikpcb{ /* the first locations may be accessed by some */ @@ -135,9 +131,8 @@ typedef struct ikpcb{ int stack_size; ikp symbol_table; ikp gensym_table; - ikp guardians[generation_count]; - ikp guardians_forward[generation_count]; - ikp guardians_dropped[generation_count]; + ik_ptr_page* guardians[generation_count]; + ik_ptr_page* guardians_dropped[generation_count]; unsigned int* dirty_vector_base; unsigned int* segment_vector_base; unsigned char* memory_base;