From b08f68cf52e38c3bd60308857b7b3f4abbcf69ae Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Sat, 17 Oct 2015 02:25:22 -0400 Subject: [PATCH] Perform major GC if necessary --- gc.c | 3 ++- include/cyclone/types.h | 2 +- runtime.c | 16 +++++++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/gc.c b/gc.c index 630381ca..f0021df9 100644 --- a/gc.c +++ b/gc.c @@ -71,7 +71,7 @@ void *gc_try_alloc(gc_heap *h, size_t size) return NULL; } -void *gc_alloc(gc_heap *h, size_t size) +void *gc_alloc(gc_heap *h, size_t size, int *heap_grown) { void *result = NULL; size_t max_freed, sum_freed, total_size; @@ -95,6 +95,7 @@ max_freed = 0; (total_size - sum_freed) > (total_size * 0.75))) // Grow ratio && ((!h->max_size) || (total_size < h->max_size))) { gc_grow_heap(h, size, 0); + *heap_grown = 1; } result = gc_try_alloc(h, size); if (!result) { diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 10e88a35..bc9ecc91 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -69,7 +69,7 @@ struct gc_header_type_t { gc_heap *gc_heap_create(size_t size, size_t max_size, size_t chunk_size); int gc_grow_heap(gc_heap *h, size_t size, size_t chunk_size); void *gc_try_alloc(gc_heap *h, size_t size); -void *gc_alloc(gc_heap *h, size_t size); +void *gc_alloc(gc_heap *h, size_t size, int *heap_grown); size_t gc_allocated_bytes(object obj); gc_heap *gc_heap_last(gc_heap *h); size_t gc_heap_total_size(gc_heap *h); diff --git a/runtime.c b/runtime.c index 1be5d1c8..8b5bc315 100644 --- a/runtime.c +++ b/runtime.c @@ -2378,12 +2378,12 @@ 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, gc_thread_data *thd, int *alloci) { +char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown) { if (!is_object_type(obj)) return obj; switch(type_of(obj)){ case cons_tag: { - list hobj = gc_alloc(Cyc_heap, sizeof(cons_type)); + list hobj = gc_alloc(Cyc_heap, sizeof(cons_type), heap_grown); hobj->hdr.mark = 0; type_of(hobj) = cons_tag; car(hobj) = car(obj); @@ -2403,7 +2403,7 @@ char *gc_move(char *obj, gc_thread_data *thd, int *alloci) { temp = obj; \ if (check_overflow(low_limit, temp) && \ check_overflow(temp, high_limit)){ \ - (obj) = (object) gc_move(temp, Cyc_thread, &alloci); \ + (obj) = (object) gc_move(temp, Cyc_thread, &alloci, &heap_grown); \ } \ } @@ -2415,6 +2415,7 @@ void GC(cont, args, num_args) closure cont; object *args; int num_args; object high_limit = stack_begin; // TODO: move to thread-specific struct int i; 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 + int heap_grown = 0; // Prevent overrunning buffer if (num_args > NUM_GC_ANS) { @@ -2472,8 +2473,13 @@ void GC(cont, args, num_args) closure cont; object *args; int num_args; scani++; } - // TODO: at some point during all of this, check the 'major GC' flag - // to see if we need to do a gc_collect + // Check if we need to do a major GC + if (heap_grown) { + size_t freed = 0; + // TODO: not good enough, need to pass current cont/args + // what about mutation barrier, do we care at this point??? + gc_collect(Cyc_heap, &freed); + } longjmp(jmp_main,1); // Return globals gc_cont, gc_ans }