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; }