From: Michael D. Lowis Date: Tue, 17 Jul 2018 03:16:36 +0000 (-0400) Subject: sketched out gc api X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=71662ee52d8b67e73d96f02a847b9f5188b09b5b;p=proto%2Fsclpl.git sketched out gc api --- diff --git a/source/rt/gc.c b/source/rt/gc.c new file mode 100644 index 0000000..abf50fe --- /dev/null +++ b/source/rt/gc.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#define NENTRIES 4096u +#define DIRTY_BIT 1u + +/* garbage collected block definition */ +typedef struct obj_t { + void (*dtor)(void*); /* destructor function for cleaning up on free() */ + size_t refs; /* count of references to this object */ + uint8_t data[]; /* user data portion of the block */ +} obj_t; + +/* log entry definition */ +typedef struct { + void* ref; /* pointer to the updated cell */ + void* val; /* pointer to the original cell value */ +} entry_t; + +size_t EntryCount; +entry_t EntryLog[NENTRIES]; + +void gc_init(void* stkbtm) { + EntryCount = 0; +} + +void gc_collect(void) { + +} + +void* gc_alloc(size_t sz, void (*dtor)(void*)) { + obj_t* obj = malloc(sizeof(obj_t) + sz); + if (obj) { + obj->dtor = dtor; + obj->refs = 0u; + } else { + perror("refcreate() failed :"); + abort(); + } + return obj->data; +} + +void gc_setref(void** ref, void* val) { + if (!((uintptr_t)*ref & DIRTY_BIT)) { + EntryLog[EntryCount].ref = ref; + EntryLog[EntryCount].val = val; + if (!((uintptr_t)*ref & DIRTY_BIT)) { + *(uintptr_t*)ref |= DIRTY_BIT; + EntryCount++; + } + if (EntryCount == NENTRIES) + gc_collect(); + } + *ref = val; +} + +void* gc_getref(void** ref) { + return (void*)((uintptr_t)*ref & ~DIRTY_BIT); +} + +