From 71662ee52d8b67e73d96f02a847b9f5188b09b5b Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 16 Jul 2018 23:16:36 -0400 Subject: [PATCH] sketched out gc api --- source/rt/gc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 source/rt/gc.c 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); +} + + -- 2.54.0