diff --git a/libsuicmez/suicmez_gc.c b/libsuicmez/suicmez_gc.c deleted file mode 100644 index d6e3e02..0000000 --- a/libsuicmez/suicmez_gc.c +++ /dev/null @@ -1,216 +0,0 @@ -#include "suicmez_gc.h" -#include -#include -#include -#include - -typedef struct { - /* Young generation */ - uint8_t *from_space; - uint8_t *from_ptr; - - uint8_t *to_space; - uint8_t *to_ptr; - - size_t young_size; - - /* Old generation */ - uint8_t *old; - uint8_t *old_ptr; - size_t old_size; - - /* Card table */ - uint8_t *card_table; - size_t card_count; - - /* Roots = pointer slots */ - void **roots[MAX_ROOTS]; - size_t root_count; -} SuicmezGC; - -static SuicmezGC gc; - -static int is_young(void *p) { - return (uint8_t*)p >= gc.from_space && - (uint8_t*)p < gc.from_ptr; -} - -static int is_old(void *p) { - return (uint8_t*)p >= gc.old && - (uint8_t*)p < gc.old_ptr; -} - -static size_t card_index(void *p) { - return ((uint8_t*)p - gc.old) / CARD_SIZE; -} - -void gc_add_root(void **slot) { - gc.roots[gc.root_count++] = slot; -} - -void gc_remove_root(void **slot) { - for (size_t i = 0; i < gc.root_count; i++) { - if (gc.roots[i] == slot) { - gc.roots[i] = gc.roots[--gc.root_count]; - return; - } - } -} - -void gc_write_barrier(void *owner, void *value) { - if (is_old(owner) && is_young(value)) { - size_t idx = card_index(owner); - gc.card_table[idx] = 1; - } -} - -static Obj *promote(Obj *obj) { - size_t sz = obj->header.size; - if (gc.old_ptr + sz > gc.old + gc.old_size) { - fprintf(stderr, "GC: old gen overflow\n"); - abort(); - } - - Obj *new_obj = (Obj*)gc.old_ptr; - memcpy(new_obj, obj, sz); - gc.old_ptr += sz; - - return new_obj; -} - -static Obj *forward(Obj *obj) { - if (!obj) return NULL; - - if (is_old(obj)) - return obj; - - if (!is_young(obj)) - return obj; - - if (obj->header.forwarding) - return obj->header.forwarding; - - if (obj->header.age >= PROMOTION_AGE) { - Obj *p = promote(obj); - obj->header.forwarding = p; - return p; - } - - size_t sz = obj->header.size; - Obj *new_obj = (Obj*)gc.to_ptr; - memcpy(new_obj, obj, sz); - - gc.to_ptr += sz; - - new_obj->header.age++; - new_obj->header.forwarding = NULL; - obj->header.forwarding = new_obj; - - return new_obj; -} - -static void gc_minor_collect(void) { - gc.to_ptr = gc.to_space; - - /* 1. Roots */ - for (size_t i = 0; i < gc.root_count; i++) { - void **slot = gc.roots[i]; - *slot = forward((Obj*)*slot); - } - - /* 2. Remembered set */ - for (size_t c = 0; c < gc.card_count; c++) { - if (!gc.card_table[c]) continue; - gc.card_table[c] = 0; - - uint8_t *start = gc.old + c * CARD_SIZE; - uint8_t *end = start + CARD_SIZE; - if (end > gc.old_ptr) end = gc.old_ptr; - - for (uint8_t *p = start; p < end;) { - Obj *obj = (Obj*)p; - size_t fields = - (obj->header.size - sizeof(ObjHeader)) / sizeof(void*); - - for (size_t i = 0; i < fields; i++) { - obj->fields[i] = forward((Obj*)obj->fields[i]); - } - p += obj->header.size; - } - } - - /* 3. Cheney scan */ - uint8_t *scan = gc.to_space; - while (scan < gc.to_ptr) { - Obj *obj = (Obj*)scan; - size_t fields = - (obj->header.size - sizeof(ObjHeader)) / sizeof(void*); - - for (size_t i = 0; i < fields; i++) { - obj->fields[i] = forward((Obj*)obj->fields[i]); - } - - scan += obj->header.size; - } - - /* 4. Swap spaces */ - uint8_t *tmp = gc.from_space; - gc.from_space = gc.to_space; - gc.to_space = tmp; - gc.from_ptr = gc.to_ptr; - - /* 5. Clear forwarding pointers */ - scan = gc.from_space; - while (scan < gc.from_ptr) { - Obj *obj = (Obj*)scan; - obj->header.forwarding = NULL; - scan += obj->header.size; - } -} - -void *gc_alloc_young(size_t payload_size) { - size_t size = payload_size + sizeof(ObjHeader); - - if (gc.from_ptr + size > gc.from_space + gc.young_size) { - gc_minor_collect(); - if (gc.from_ptr + size > gc.from_space + gc.young_size) { - fprintf(stderr, "GC: out of memory\n"); - abort(); - } - } - - Obj *obj = (Obj*)gc.from_ptr; - obj->header.size = size; - obj->header.age = 0; - obj->header.flags = 0; - obj->header.forwarding = NULL; - - gc.from_ptr += size; - return obj; -} - -void gc_init(void) { - gc.young_size = YOUNG_SIZE; - gc.old_size = OLD_SIZE; - - gc.from_space = malloc(gc.young_size); - gc.to_space = malloc(gc.young_size); - gc.old = malloc(gc.old_size); - - gc.from_ptr = gc.from_space; - gc.to_ptr = gc.to_space; - gc.old_ptr = gc.old; - - gc.card_count = gc.old_size / CARD_SIZE; - gc.card_table = calloc(gc.card_count, 1); - - gc.root_count = 0; -} - - -void gc_shutdown(void) { - free(gc.from_space); - free(gc.to_space); - free(gc.old); - free(gc.card_table); -} \ No newline at end of file diff --git a/libsuicmez/suicmez_gc.h b/libsuicmez/suicmez_gc.h deleted file mode 100644 index c5f4557..0000000 --- a/libsuicmez/suicmez_gc.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef SUICMEZ_GC_H -#define SUICMEZ_GC_H - -#include -#include - -#define YOUNG_SIZE (1024 * 1024 * 2) -#define SURVIVOR_SIZE (512 * 1024) -#define OLD_SIZE (16 * 1024 * 1024) -#define CARD_SIZE 512 -#define PROMOTION_AGE 2 -#define MAX_ROOTS 1024 -#define MARKED 0x1 - -/* Forward declare Obj so ObjHeader can reference it */ -typedef struct Obj Obj; - -/* Header must come first */ -typedef struct ObjHeader { - uint32_t size; // total object size incl header - uint16_t age; - uint16_t flags; - Obj *forwarding; // non-NULL if moved -} ObjHeader; - -/* Full object definition */ -struct Obj { - ObjHeader header; - void *fields[]; -}; - -// --- API --- -// Initialize the GC -void gc_init(void); - -// Shutdown GC -void gc_shutdown(void); - -// Allocate object in young generation -void* gc_alloc_young(size_t size); - -// Root management -void gc_add_root(void **ptr); -void gc_remove_root(void **ptr); - -// Write barrier for old->young references -void gc_write_barrier(void *src, void *dst); - -// Minor GC slice (incremental) -void gc_minor_collect_slice(size_t max_objects); - -// Trigger major GC (async background) -void gc_major_collect(void); - -#endif // SUICMEZ_GC_H \ No newline at end of file