]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
sketched out gc api
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 17 Jul 2018 03:16:36 +0000 (23:16 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 17 Jul 2018 03:16:36 +0000 (23:16 -0400)
source/rt/gc.c [new file with mode: 0644]

diff --git a/source/rt/gc.c b/source/rt/gc.c
new file mode 100644 (file)
index 0000000..abf50fe
--- /dev/null
@@ -0,0 +1,62 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#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);
+}
+
+