X-Git-Url: http://nitlanguage.org diff --git a/clib/gc.c b/clib/gc.c index de0a723..ad051d9 100644 --- a/clib/gc.c +++ b/clib/gc.c @@ -80,7 +80,6 @@ static val_t GC_evacuation(obj_t object) { bigint objectSize; val_t newAdress; Nit_NativeArray array; - BOX_struct box; assert(ISOBJ(object) && !ISNULL(object)); if (GET_MARKBIT(object) != (bigint)0) { @@ -92,7 +91,6 @@ static val_t GC_evacuation(obj_t object) { array = (Nit_NativeArray)object; size = sizeof(struct Nit_NativeArray) + ((array->size - 1) * sizeof(val_t)); } else if (OBJ_IS_BOX(object)) { - box = (BOX_struct)object; size = sizeof(struct TBOX_struct); } else { objectSize = (bigint)((object)[0].vft[1].i); @@ -148,6 +146,8 @@ static void GC_collect(void) { struct stack_frame_t *frame = stack_frame_head; GC_static_object *staticObject = staticObjects.top; val_t object; + struct nitni_ref *global_ref; + struct nitni_ref_array_link *local_ref_array_link; /* for native interface */ gc_allocation_pointer = gc_heap_pointer; gc_scavenging_pointer = gc_heap_pointer; @@ -161,6 +161,16 @@ static void GC_collect(void) { staticObject = staticObject->next; } + /* Process global reference to Nit objects from C code */ + global_ref = nitni_global_ref_list->head; + while (global_ref != NULL) { + object = global_ref->val; + if (!ISNULL(object) && ISOBJ(object)) { + global_ref->val = GC_evacuation((obj_t)object); + } + global_ref = global_ref->next; + } + /* Process function frames (local variables) */ while (frame != NULL) { for (j = 0; j < frame->REG_size; j++) { @@ -169,6 +179,20 @@ static void GC_collect(void) { frame->REG[j] = GC_evacuation((obj_t)object); } } + + /* Process C references to Nit objects */ + local_ref_array_link = frame->nitni_local_ref_head; + while ( local_ref_array_link != NULL ) + { + for (j = 0; j < local_ref_array_link->count; j++) { + object = local_ref_array_link->reg[j]->val; + if (!ISNULL(object) && ISOBJ(object)) { + local_ref_array_link->reg[j]->val = GC_evacuation((obj_t)object); + } + } + local_ref_array_link = local_ref_array_link->next; + } + if (frame == frame->prev) break; frame = frame->prev; } @@ -194,7 +218,13 @@ static void GC_prepare_heap_size(size_t size) { } void Nit_gc_print_usage(void) { - printf("GC: Size %d usage %d (%.2f%%)\n", gc_heap_size, gc_used_size, 100.0*gc_used_size/gc_heap_size); +#if __STDC_VERSION >= 199901L + /* If we are compiling with standard C99 or more recent, we can use %zu. */ + printf("GC: Size %zu usage %zu (%.2f%%)\n", gc_heap_size, gc_used_size, 100.0*gc_used_size/gc_heap_size); +#else + /* We are not compiling with a standard that allows us to use %zu, let's cast the two unsigned integers into the biggest we can !*/ + printf("GC: Size %lu usage %lu (%.2f%%)\n", (unsigned long)gc_heap_size, (unsigned long)gc_used_size, 100.0*gc_used_size/gc_heap_size); +#endif } /** Enlarge the heap and collect dead objects. Can also shrink the heap. @@ -241,3 +271,7 @@ void GC_add_static_object(val_t *pointer) { GC_List_Push(&staticObjects, pointer); } +/* Is invoked by intern method Sys:force_garbage_collection */ +void Nit_gc_force_garbage_collection( void ) { + GC_enlarge_and_collect( 0 ); +}