#include "heap.h"
#include <assert.h>
#include <stdlib.h>
+#include <setjmp.h>
typedef struct {
uint64_t objmap;
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);
}
}
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);
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]);
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)
typedef struct {
segment_t* heaps[NUM_HEAP_STACKS];
block_t* blocks;
+ block_t* greylist;
} heap_t;
heap_t* heap_create(void);
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;
}
}
return obj;
}
+
+void segment_clear_map(segment_t* seg)
+{
+ memset(seg->blockmap, 0xFFu, sizeof(seg->blockmap));
+}
+
void* segment_alloc(segment_t* seg);
+void segment_clear_map(segment_t* seg);
+
#endif /* SEGMENT_H */