Merge: doc: fixed some typos and other misc. corrections
[nit.git] / clib / gc.c
index 8f65664..ad051d9 100644 (file)
--- 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;
        }
@@ -247,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 );
+}