diff --git a/gc.c b/gc.c index 7716ea8c..630381ca 100644 --- a/gc.c +++ b/gc.c @@ -262,7 +262,8 @@ size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr) return max_freed; } -void gc_thr_grow_move_buffer(gc_thread_data *d){ +void gc_thr_grow_move_buffer(gc_thread_data *d) +{ if (!d) return; if (d->moveBufLen == 0) { // Special case @@ -272,7 +273,17 @@ void gc_thr_grow_move_buffer(gc_thread_data *d){ d->moveBufLen *= 2; } - d->moveBuf = realloc(d->moveBuf, d->moveBufLen); + d->moveBuf = realloc(d->moveBuf, d->moveBufLen * sizeof(void *)); +} + +void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj) +{ + if (*alloci == d->moveBufLen) { + gc_thr_grow_move_buffer(d); + } + + d->moveBuf[*alloci] = obj; + (*alloci)++; } // void gc_init() diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 29352735..10e88a35 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -23,7 +23,7 @@ typedef void *object; /* Thread data structures */ typedef struct gc_thread_data_t gc_thread_data; struct gc_thread_data_t { - char *moveBuf; /* list of objects moved to heap during GC */ + void **moveBuf; /* list of objects moved to heap during GC */ int moveBufLen; }; @@ -77,6 +77,7 @@ void gc_mark(gc_heap *h, object obj); size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr); void gc_collect(gc_heap *h, size_t *sum_freed); void gc_thr_grow_move_buffer(gc_thread_data *d); +void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj); /* GC debugging flags */ //#define DEBUG_GC 0 diff --git a/runtime.c b/runtime.c index d31c16c0..4350f534 100644 --- a/runtime.c +++ b/runtime.c @@ -2378,7 +2378,7 @@ void gc_collect(gc_heap *h, size_t *sum_freed) // TODO: move globals to thread-specific structures. // for example - gc_cont, gc_ans, gc_num_ans -char *gc_move(char *obj) { +char *gc_move(char *obj, gc_thread_data *thd, int *alloci) { if (!is_object_type(obj)) return obj; switch(type_of(obj)){ @@ -2390,10 +2390,9 @@ char *gc_move(char *obj) { cdr(hobj) = cdr(hobj); forward(obj) = hobj; type_of(obj) = forward_tag; -// TODO: add hobj to bump pointer, so we can scan/move the whole live object 'tree' -// will require we pass the 'bump' space to this function, -// and will require us to check somewhere for overflow of this space, and -// realloc/expand it if necessary + // keep track of each allocation so we can scan/move + // the whole live object 'tree' + gc_thr_add_to_move_buffer(thd, alloci, hobj); return (char *)hobj; } // TODO: other types @@ -2404,7 +2403,7 @@ char *gc_move(char *obj) { temp = obj; \ if (check_overflow(low_limit, temp) && \ check_overflow(temp, high_limit)){ \ - (obj) = (object) gc_move(temp); \ + (obj) = (object) gc_move(temp, Cyc_thread, &alloci); \ } \ } @@ -2415,13 +2414,11 @@ void GC(cont, args, num_args) closure cont; object *args; int num_args; object low_limit = &tmp; // This is one end of the stack... object high_limit = stack_begin; // TODO: move to thread-specific struct int i; - int moveBufLen = 128, mbIdx = 0; - void **moved = alloca(sizeof(void *) * moveBufLen); int scani = 0, alloci = 0; // TODO: not quite sure how to do this yet, want to user pointers but realloc can move them... need to think about how this will work // Prevent overrunning buffer - if (num_ans > NUM_GC_ANS) { - printf("Fatal error - too many arguments (%d) to GC\n", num_ans); + if (num_args > NUM_GC_ANS) { + printf("Fatal error - too many arguments (%d) to GC\n", num_args); exit(1); }