aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/gc.c')
-rw-r--r--src/bootstrap/gc.c67
1 files changed, 10 insertions, 57 deletions
diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c
index 11a1f5a..473930a 100644
--- a/src/bootstrap/gc.c
+++ b/src/bootstrap/gc.c
@@ -1,48 +1,4 @@
1// Stack of root nodes. 1#include "gc.h"
2typedef struct RootNodes {
3 Object **buf;
4 size_t size;
5 size_t cap;
6} RootNodes;
7
8// Stack of active environments.
9typedef struct ActiveEnvs {
10 Environment **buf;
11 size_t size;
12 size_t cap;
13} ActiveEnvs;
14
15typedef struct Environments {
16 Environment *buf;
17 size_t size;
18 size_t cap;
19} Environments;
20
21typedef struct FreeList {
22 size_t *buf;
23 size_t size;
24 size_t cap;
25 size_t position;
26} FreeList;
27
28typedef struct GC {
29 RootNodes roots;
30 Environments envs;
31 Object *objects;
32 size_t obj_cap;
33 FreeList free_objects;
34 FreeList free_envs;
35 ActiveEnvs active_envs;
36} GC;
37
38#define GC_OBJS_CAP 1024 * 1024
39#define GC_ROOTS_CAP 1024
40#define GC_ENVS_CAP 1024 * 4
41
42static GC gc;
43
44void mark_and_sweep(void);
45void dump_gc(void);
46 2
47Environment * 3Environment *
48alloc_env(void) { 4alloc_env(void) {
@@ -115,9 +71,9 @@ init_gc(void) {
115 .cap = GC_ENVS_CAP, 71 .cap = GC_ENVS_CAP,
116 }, 72 },
117 .active_envs = (ActiveEnvs){ 73 .active_envs = (ActiveEnvs){
118 .buf = malloc(GC_ROOTS_CAP * sizeof(Environment*)), 74 .buf = malloc(GC_ACTIVE_ENVS_CAP * sizeof(Environment*)),
119 .size = 0, 75 .size = 0,
120 .cap = GC_ROOTS_CAP, 76 .cap = GC_ACTIVE_ENVS_CAP,
121 }, 77 },
122 }; 78 };
123 79
@@ -131,13 +87,6 @@ init_gc(void) {
131 } 87 }
132} 88}
133 89
134Object *
135get_obj(size_t offset) {
136 return &gc.objects[offset];
137}
138
139void mark_obj(Object *obj);
140
141void 90void
142mark_environment(Environment *env) { 91mark_environment(Environment *env) {
143 if (env == NULL || env->marked) { 92 if (env == NULL || env->marked) {
@@ -190,11 +139,15 @@ mark_and_sweep(void) {
190 if (!obj->marked) { 139 if (!obj->marked) {
191 // Free heap allocated memory for this object if needed. 140 // Free heap allocated memory for this object if needed.
192 if (obj->type == OBJ_TYPE_SYMBOL) { 141 if (obj->type == OBJ_TYPE_SYMBOL) {
193 free(obj->symbol); 142 if (obj->symbol != NULL) {
143 free(obj->symbol);
144 }
194 obj->symbol = NULL; 145 obj->symbol = NULL;
195 obj->symbol_n = 0; 146 obj->symbol_n = 0;
196 } else if (obj->type == OBJ_TYPE_STRING) { 147 } else if (obj->type == OBJ_TYPE_STRING) {
197 free(obj->string); 148 if (obj->symbol != NULL) {
149 free(obj->string);
150 }
198 obj->string = NULL; 151 obj->string = NULL;
199 obj->string_n = 0; 152 obj->string_n = 0;
200 } 153 }
@@ -280,7 +233,7 @@ alloc_object(ObjectType type) {
280 } 233 }
281 size_t slot = gc.free_objects.buf[gc.free_objects.position++]; 234 size_t slot = gc.free_objects.buf[gc.free_objects.position++];
282 gc.free_objects.size--; 235 gc.free_objects.size--;
283 Object *obj = get_obj(slot); 236 Object *obj = &gc.objects[slot];
284 obj->type = type; 237 obj->type = type;
285 obj->marked = false; 238 obj->marked = false;
286 return obj; 239 return obj;