]> git.mdlowis.com Git - archive/atc.git/commitdiff
Fleshed out more of the collector logic
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 3 Apr 2015 21:11:30 +0000 (17:11 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 3 Apr 2015 21:11:30 +0000 (17:11 -0400)
source/runtime/gc.c
source/runtime/heap.c
source/runtime/heap.h
source/runtime/segment.c
source/runtime/segment.h

index 56f2222fe1d261b52c9725141528114888dd6f61..07b3bff8fe35aeb4f32826e1b607373218a25eea 100644 (file)
@@ -2,6 +2,7 @@
 #include "heap.h"
 #include <assert.h>
 #include <stdlib.h>
+#include <setjmp.h>
 
 typedef struct {
     uint64_t objmap;
@@ -40,15 +41,16 @@ void gc_add_root(void* address, size_t size)
 
 void* gc_object(uint64_t objmap, size_t num_slots)
 {
-    (void)objmap;
-    return heap_allocate(Heap, num_slots+1);
+    obj_t* obj = heap_allocate(Heap, num_slots+1);
+    obj->objmap = objmap;
+    obj++;
+    return obj;
 }
 
 void* gc_allocate(size_t size)
 {
     size_t slot_sz   = sizeof(uintptr_t);
-    size_t remainder = size % slot_sz;
-    size_t num_slots = (size / slot_sz) + ((remainder == 0) ? 0 : (slot_sz - remainder));
+    size_t num_slots = (size + slot_sz - 1) / slot_sz;
     return heap_allocate(Heap, num_slots + 1);
 }
 
@@ -79,14 +81,15 @@ static void gc_scan_stack(void) {
 }
 
 static void gc_scan_roots(void) {
-    root_t* root = Roots;
-    for (; root != NULL; root = root->next)
+    for (root_t* root = Roots; root != NULL; root = root->next)
         gc_scan_region(root->address, root->address + (root->size / sizeof(uintptr_t)));
 }
 
 void gc_collect(void)
 {
+    jmp_buf registers;
     heap_start_collection(Heap);
+    (void)setjmp(registers); // Save off register sets
     gc_scan_stack();
     gc_scan_roots();
     gc_scan_object(NULL);
index 038d2ad68ce69747ee935bb49396be4b4d89dd27..1fcccdd8f43f5c104543eb0fa98f17d6f3d3fda3 100644 (file)
@@ -10,16 +10,20 @@ heap_t* heap_create(void)
     return (heap_t*)calloc(1u, sizeof(heap_t));;
 }
 
-void heap_destroy(heap_t* heap)
-{
-    unsigned int i;
-    block_t* current = heap->blocks;
-    /* Free all the large blocks */
+static void destroy_large_blocks(block_t* current) {
     while (NULL != current) {
         block_t* deadite = current;
         current = current->next;
         free(deadite);
     }
+}
+
+void heap_destroy(heap_t* heap)
+{
+    unsigned int i;
+    /* Free all the large blocks */
+    destroy_large_blocks(heap->blocks);
+    destroy_large_blocks(heap->greylist);
     /* Free all of the small block segments */
     for (i = 0; i < NUM_HEAP_STACKS; i++) {
         segment_destroy(heap->heaps[i]);
@@ -59,12 +63,18 @@ void* heap_allocate(heap_t* heap, uintptr_t num_slots)
 
 void heap_start_collection(heap_t* heap)
 {
-    (void)heap;
+    heap->greylist = heap->blocks;
+    heap->blocks = NULL;
+    for (uintptr_t i = 0; i < NUM_HEAP_STACKS; i++) {
+        for(segment_t* curr = heap->heaps[i]; curr != NULL; curr = curr->next) {
+            segment_clear_map(heap->heaps[i]);
+        }
+    }
 }
 
 void heap_finish_collection(heap_t* heap)
 {
-    (void)heap;
+    destroy_large_blocks(heap->greylist);
 }
 
 void* heap_find_and_mark(heap_t* heap, uintptr_t* addr)
index 361e40933a0ceb6a56703bc202edf8ec4831eb8f..f56f7571819369945ad404c77fa9cde243579b36 100644 (file)
@@ -23,6 +23,7 @@ typedef struct block_t {
 typedef struct {
     segment_t* heaps[NUM_HEAP_STACKS];
     block_t* blocks;
+    block_t* greylist;
 } heap_t;
 
 heap_t* heap_create(void);
index 625ea037274cbc6c83644fc192843b392c46d9c7..31773760d48b57fd2205a580bb2af437eb430de1 100644 (file)
@@ -21,7 +21,7 @@ segment_t* segment_create(uintptr_t num_slots, segment_t* next)
     seg->next = next;
     seg->blocksize = num_slots;
     seg->end = (seg->start + (num_slots * NUM_BLOCKS));
-    memset(seg->blockmap, 0xFFu, sizeof(seg->blockmap));
+    segment_clear_map(seg);
     return seg;
 }
 
@@ -56,3 +56,9 @@ void* segment_alloc(segment_t* seg) {
     }
     return obj;
 }
+
+void segment_clear_map(segment_t* seg)
+{
+    memset(seg->blockmap, 0xFFu, sizeof(seg->blockmap));
+}
+
index 623855d8b9aa94e14f6f95bf47855ca62ae396eb..611699db2a67c926c6be6c796340e0652183dae6 100644 (file)
@@ -28,4 +28,6 @@ bool segment_full(segment_t* seg);
 
 void* segment_alloc(segment_t* seg);
 
+void segment_clear_map(segment_t* seg);
+
 #endif /* SEGMENT_H */