From 87b1a0d4a833dd0b2164481be45f7d1c59375040 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 15 Oct 2021 17:58:05 +0200 Subject: Add boilerplate for GC allocator --- src/bootstrap/gc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/bootstrap/main.c | 7 +++++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/bootstrap/gc.c (limited to 'src/bootstrap') diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c new file mode 100644 index 0000000..fff4201 --- /dev/null +++ b/src/bootstrap/gc.c @@ -0,0 +1,48 @@ +typedef struct GC { + Object *obj_list; + // Free list keeps track of the offset numbers from the obj_list + size_t *free_list; + size_t obj_size; + size_t obj_cap; + size_t fl_pos; + size_t available_slots; +} GC; + +// FIXME: small value for testing purposes +#define GC_INITIAL_HEAP 100000 + +static GC gc; + +void +init_gc(void) { + gc = (GC){ + .obj_cap = GC_INITIAL_HEAP, + .available_slots = GC_INITIAL_HEAP, + }; + gc.free_list = malloc(GC_INITIAL_HEAP * sizeof(size_t *)); + gc.obj_list = malloc(GC_INITIAL_HEAP * sizeof(Object *)); + + // The free list stores the offset from the initial position for all + // available slots. + for (size_t i = 0; i < gc.obj_cap; i++) { + gc.free_list[i] = i; + } +} + +Object * +alloc_object(ObjectType type) { + if (gc.available_slots == 0) { + // TODO: trigger garbage collection. + if (gc.available_slots == 0) { + // TODO: grow heap tables. + // NOTE: When growing the tables, we might lose the pointer + // references! Should we work with offsets all the way? That is for + // cdr and car? Should we have a utility function? + } + } + size_t slot = gc.free_list[gc.fl_pos++]; + gc.available_slots--; + Object *obj = gc.obj_list + slot; + obj->type = type; + return obj; +} diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 5191fd0..575a924 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -12,6 +13,7 @@ #include "objects.c" #include "parser.c" #include "environment.c" +#include "gc.c" #include "primitives.c" // @@ -26,6 +28,9 @@ void init(void) { + // Initialize garbage collector. + init_gc(); + // Initialize singletons. obj_nil = alloc_object(OBJ_TYPE_NIL); obj_true = alloc_object(OBJ_TYPE_BOOL); @@ -99,7 +104,6 @@ process_source(const StringView *source) { while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) { Object *root = parse_tree(&visitor); if (root == obj_err || errors_n != 0) { - free_objects(root); break; } @@ -109,7 +113,6 @@ process_source(const StringView *source) { display(result); printf("\n"); } - free_objects(root); } if (tokens.buf != NULL) { -- cgit v1.2.1