diff options
Diffstat (limited to 'src/bootstrap/gc.c')
-rw-r--r-- | src/bootstrap/gc.c | 67 |
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" |
2 | typedef struct RootNodes { | ||
3 | Object **buf; | ||
4 | size_t size; | ||
5 | size_t cap; | ||
6 | } RootNodes; | ||
7 | |||
8 | // Stack of active environments. | ||
9 | typedef struct ActiveEnvs { | ||
10 | Environment **buf; | ||
11 | size_t size; | ||
12 | size_t cap; | ||
13 | } ActiveEnvs; | ||
14 | |||
15 | typedef struct Environments { | ||
16 | Environment *buf; | ||
17 | size_t size; | ||
18 | size_t cap; | ||
19 | } Environments; | ||
20 | |||
21 | typedef struct FreeList { | ||
22 | size_t *buf; | ||
23 | size_t size; | ||
24 | size_t cap; | ||
25 | size_t position; | ||
26 | } FreeList; | ||
27 | |||
28 | typedef 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 | |||
42 | static GC gc; | ||
43 | |||
44 | void mark_and_sweep(void); | ||
45 | void dump_gc(void); | ||
46 | 2 | ||
47 | Environment * | 3 | Environment * |
48 | alloc_env(void) { | 4 | alloc_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 | ||
134 | Object * | ||
135 | get_obj(size_t offset) { | ||
136 | return &gc.objects[offset]; | ||
137 | } | ||
138 | |||
139 | void mark_obj(Object *obj); | ||
140 | |||
141 | void | 90 | void |
142 | mark_environment(Environment *env) { | 91 | mark_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; |