From f8f60cf1ab814793870e34cc8fad539781c1e102 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 3 Apr 2015 17:11:30 -0400 Subject: [PATCH] Fleshed out more of the collector logic --- source/runtime/gc.c | 15 +++++++++------ source/runtime/heap.c | 24 +++++++++++++++++------- source/runtime/heap.h | 1 + source/runtime/segment.c | 8 +++++++- source/runtime/segment.h | 2 ++ 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/source/runtime/gc.c b/source/runtime/gc.c index 56f2222..07b3bff 100644 --- a/source/runtime/gc.c +++ b/source/runtime/gc.c @@ -2,6 +2,7 @@ #include "heap.h" #include #include +#include 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); diff --git a/source/runtime/heap.c b/source/runtime/heap.c index 038d2ad..1fcccdd 100644 --- a/source/runtime/heap.c +++ b/source/runtime/heap.c @@ -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) diff --git a/source/runtime/heap.h b/source/runtime/heap.h index 361e409..f56f757 100644 --- a/source/runtime/heap.h +++ b/source/runtime/heap.h @@ -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); diff --git a/source/runtime/segment.c b/source/runtime/segment.c index 625ea03..3177376 100644 --- a/source/runtime/segment.c +++ b/source/runtime/segment.c @@ -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)); +} + diff --git a/source/runtime/segment.h b/source/runtime/segment.h index 623855d..611699d 100644 --- a/source/runtime/segment.h +++ b/source/runtime/segment.h @@ -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 */ -- 2.49.0