diff --git a/bin/Makefile b/bin/Makefile index 993588d..8395138 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -1,7 +1,7 @@ CFLAGS = -I/opt/local/include -Wall -DNDEBUG -O3 #-fomit-frame-pointer #CFLAGS = -I/opt/local/include -Wall -g -LDFLAGS = -L/opt/local/lib -g -ldl -lgmp -rdynamic +LDFLAGS = -L/opt/local/lib -g -ldl -lgmp #-rdynamic CC = gcc all: ikarus diff --git a/bin/ikarus b/bin/ikarus index 23c6933..f21510f 100755 Binary files a/bin/ikarus and b/bin/ikarus differ diff --git a/bin/ikarus-collect.c b/bin/ikarus-collect.c index 830a30a..6feb0ca 100644 --- a/bin/ikarus-collect.c +++ b/bin/ikarus-collect.c @@ -66,7 +66,6 @@ static unsigned int meta_mt[meta_count] = { pointers_mt }; -#define generation_count 5 /* generations 0 (nursery), 1, 2, 3, 4 */ typedef struct{ @@ -243,6 +242,7 @@ static ikp add_object_proc(gc_t* gc, ikp x); static void collect_stack(gc_t*, ikp top, ikp base); static void collect_loop(gc_t*); +static void guardians_loop(gc_t*); static void fix_weak_pointers(gc_t*); static void gc_add_tconcs(gc_t*); @@ -320,8 +320,13 @@ ik_collect(int mem_req, ikpcb* pcb){ pcb->arg_list = add_object(&gc, pcb->arg_list, "args_list_foo"); /* now we trace all live objects */ collect_loop(&gc); + + /* next we trace all guardian/guarded objects, + the procedure does a collect_loop at the end */ + guardians_loop(&gc); - fix_weak_pointers(&gc); + /* does not allocate, only bwp's dead pointers */ + fix_weak_pointers(&gc); /* now deallocate all unused pages */ deallocate_unused_pages(&gc); @@ -412,46 +417,17 @@ ik_collect(int mem_req, ikpcb* pcb){ return pcb; } +static void +guardians_loop(gc_t* gc){ + +} #define disp_frame_offset -13 #define disp_multivalue_rp -9 #define CODE_EXTENSION_SIZE (pagesize) -//X static ikp -//X gc_alloc_new_code_extending(int size, int old_gen, gc_t* gc){ -//X int mapsize = align_to_next_page(size); -//X if(mapsize < CODE_EXTENSION_SIZE){ -//X mapsize = CODE_EXTENSION_SIZE; -//X } -//X if(gc->gen[old_gen].code_base){ -//X qupages_t* p = ik_malloc(sizeof(qupages_t)); -//X ikp aq = gc->gen[old_gen].code_aq; -//X ikp ap = gc->gen[old_gen].code_ap; -//X ikp ep = gc->gen[old_gen].code_ep; -//X p->p = aq; -//X p->q = ap; -//X p->next = gc->code_queue; -//X gc->code_queue = p; -//X ikp x = ap; -//X while(x < ep){ -//X ref(x, 0) = 0; -//X x += wordsize; -//X } -//X } -//X ikp mem = ik_mmap_typed( -//X mapsize, -//X code_mt | next_gen_tag[old_gen], -//X gc->pcb); -//X gc->segment_vector = gc->pcb->segment_vector; -//X gc->gen[old_gen].code_ap = mem + size; -//X gc->gen[old_gen].code_aq = mem; -//X gc->gen[old_gen].code_ep = mem + mapsize; -//X gc->gen[old_gen].code_base = mem; -//X return mem; -//X } -//X static int alloc_code_count = 0; diff --git a/bin/ikarus-runtime.c b/bin/ikarus-runtime.c index 4d195be..e02d01c 100644 --- a/bin/ikarus-runtime.c +++ b/bin/ikarus-runtime.c @@ -821,3 +821,27 @@ ikrt_write_char(){ fprintf(stderr, "ikrt_write_char\n"); return void_object; } + + + +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: invaldi guardian table size\n"); + exit(-1); + } + ik_guardian_table* p = + (ik_guardian_table*)ik_alloc(pcb, 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; +} diff --git a/bin/ikarus.h b/bin/ikarus.h index 0c98416..56bc56d 100644 --- a/bin/ikarus.h +++ b/bin/ikarus.h @@ -59,6 +59,11 @@ inthash(int key) { +#define wordsize 4 +#define wordshift 2 +#define pagesize 4096 +#define generation_count 5 /* generations 0 (nursery), 1, 2, 3, 4 */ + typedef unsigned char* ikp; void ik_error(ikp args); @@ -78,6 +83,20 @@ 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)) + +typedef struct ik_guardian_table{ + int count; + struct ik_guardian_table* next; + ik_guardian_pair p[ik_guardian_table_size]; +} ik_guardian_table; + typedef struct { /* the first locations may be accessed by some */ @@ -104,6 +123,7 @@ typedef struct { ikp stack_base; int stack_size; ikp oblist; + ik_guardian_table* guardians[generation_count]; unsigned int* dirty_vector_base; unsigned int* segment_vector_base; unsigned char* memory_base; @@ -147,9 +167,6 @@ ikp ik_asm_reenter(ikpcb*, ikp code_object, ikp val); ikp ik_underflow_handler(ikpcb*); ikp ik_alloc(ikpcb* pcb, int size); #include "ikarus-data.h" -#define wordsize 4 -#define wordshift 2 -#define pagesize 4096 #define ik_eof_p(x) ((x) == ik_eof_object) #define page_index(x) (((unsigned int)(x)) >> pageshift) diff --git a/lab/optimize-gc.txt b/lab/optimize-gc.txt index 870a53d..9a0278a 100644 --- a/lab/optimize-gc.txt +++ b/lab/optimize-gc.txt @@ -17,3 +17,6 @@ Copyright (c) 2006 Abdulaziz Ghuloum > 4.23 real 3.23 user 1.00 sys +As of r127: + 3.79 real 3.15 user 0.63 sys +