diff options
-rw-r--r-- | src/bootstrap/gc.c | 58 | ||||
-rw-r--r-- | src/bootstrap/gc.h | 4 |
2 files changed, 24 insertions, 38 deletions
diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c index d281536..259cccd 100644 --- a/src/bootstrap/gc.c +++ b/src/bootstrap/gc.c | |||
@@ -2,17 +2,17 @@ | |||
2 | 2 | ||
3 | Environment * | 3 | Environment * |
4 | alloc_env(void) { | 4 | alloc_env(void) { |
5 | if (gc.free_envs.size == 0) { | 5 | if (array_size(gc.free_envs.offsets) == 0) { |
6 | mark_and_sweep(); | 6 | mark_and_sweep(); |
7 | if (gc.free_envs.size == 0) { | 7 | if (array_size(gc.free_envs.offsets) == 0) { |
8 | fprintf(stderr, "NO MORE ENV MEMORY AVAILABLE WHERE IS YOUR GOD NOW MWAHAHA\n"); | 8 | fprintf(stderr, "NO MORE ENV MEMORY AVAILABLE WHERE IS YOUR GOD NOW MWAHAHA\n"); |
9 | dump_gc(); | 9 | dump_gc(); |
10 | exit(EXIT_FAILURE); | 10 | exit(EXIT_FAILURE); |
11 | // TODO: grow heap tables. | 11 | // TODO: grow heap tables. |
12 | } | 12 | } |
13 | } | 13 | } |
14 | size_t slot = gc.free_envs.buf[gc.free_envs.position++]; | 14 | size_t slot = gc.free_envs.offsets[gc.free_envs.position++]; |
15 | gc.free_envs.size--; | 15 | array_head(gc.free_envs.offsets)->size--; |
16 | return &gc.envs[slot]; | 16 | return &gc.envs[slot]; |
17 | } | 17 | } |
18 | 18 | ||
@@ -38,34 +38,22 @@ pop_active_env(void) { | |||
38 | 38 | ||
39 | void | 39 | void |
40 | init_gc(void) { | 40 | init_gc(void) { |
41 | gc = (GC){ | 41 | gc = (GC){0}; |
42 | .free_objects = (FreeList){ | 42 | |
43 | .buf = malloc(GC_OBJS_CAP * sizeof(size_t)), | ||
44 | .size = GC_OBJS_CAP, | ||
45 | .cap = GC_OBJS_CAP, | ||
46 | }, | ||
47 | .free_envs = (FreeList){ | ||
48 | .buf = malloc(GC_ENVS_CAP * sizeof(size_t)), | ||
49 | .size = GC_ENVS_CAP, | ||
50 | .cap = GC_ENVS_CAP, | ||
51 | }, | ||
52 | .objects = NULL, | ||
53 | .envs = NULL, | ||
54 | .roots = NULL, | ||
55 | .active_envs = NULL, | ||
56 | }; | ||
57 | array_init(gc.objects, GC_OBJS_CAP); | 43 | array_init(gc.objects, GC_OBJS_CAP); |
58 | array_init(gc.roots, GC_ROOTS_CAP); | 44 | array_init(gc.roots, GC_ROOTS_CAP); |
59 | array_init(gc.active_envs, GC_ACTIVE_ENVS_CAP); | 45 | array_init(gc.active_envs, GC_ACTIVE_ENVS_CAP); |
60 | array_init(gc.envs, GC_ENVS_CAP); | 46 | array_init(gc.envs, GC_ENVS_CAP); |
47 | array_init(gc.free_objects.offsets, GC_OBJS_CAP); | ||
48 | array_init(gc.free_envs.offsets, GC_ENVS_CAP); | ||
61 | 49 | ||
62 | // The free list stores the offset from the initial position for all | 50 | // The free list stores the offset from the initial position for all |
63 | // available slots. | 51 | // available slots. |
64 | for (size_t i = 0; i < GC_OBJS_CAP; i++) { | 52 | for (size_t i = 0; i < GC_OBJS_CAP; i++) { |
65 | gc.free_objects.buf[i] = i; | 53 | array_push(gc.free_objects.offsets, i); |
66 | } | 54 | } |
67 | for (size_t i = 0; i < GC_ENVS_CAP; i++) { | 55 | for (size_t i = 0; i < GC_ENVS_CAP; i++) { |
68 | gc.free_envs.buf[i] = i; | 56 | array_push(gc.free_envs.offsets, i); |
69 | } | 57 | } |
70 | } | 58 | } |
71 | 59 | ||
@@ -111,9 +99,9 @@ mark_and_sweep(void) { | |||
111 | 99 | ||
112 | // Reset the free list. | 100 | // Reset the free list. |
113 | gc.free_objects.position = 0; | 101 | gc.free_objects.position = 0; |
114 | gc.free_objects.size = 0; | 102 | array_head(gc.free_objects.offsets)->size = 0; |
115 | gc.free_envs.position = 0; | 103 | gc.free_envs.position = 0; |
116 | gc.free_envs.size = 0; | 104 | array_head(gc.free_envs.offsets)->size = 0; |
117 | 105 | ||
118 | // Sweep. | 106 | // Sweep. |
119 | for (size_t i = 0; i < array_cap(gc.objects); i++) { | 107 | for (size_t i = 0; i < array_cap(gc.objects); i++) { |
@@ -125,7 +113,7 @@ mark_and_sweep(void) { | |||
125 | } else if (obj->type == OBJ_TYPE_STRING) { | 113 | } else if (obj->type == OBJ_TYPE_STRING) { |
126 | array_free(obj->string); | 114 | array_free(obj->string); |
127 | } | 115 | } |
128 | gc.free_objects.buf[gc.free_objects.size++] = i; | 116 | gc.free_objects.offsets[array_head(gc.free_objects.offsets)->size++] = i; |
129 | } | 117 | } |
130 | obj->marked = false; | 118 | obj->marked = false; |
131 | } | 119 | } |
@@ -133,7 +121,7 @@ mark_and_sweep(void) { | |||
133 | Environment *env = &gc.envs[i]; | 121 | Environment *env = &gc.envs[i]; |
134 | if (!env->marked) { | 122 | if (!env->marked) { |
135 | array_free(env->entries); | 123 | array_free(env->entries); |
136 | gc.free_envs.buf[gc.free_envs.size++] = i; | 124 | gc.free_envs.offsets[array_head(gc.free_envs.offsets)->size++] = i; |
137 | } | 125 | } |
138 | env->marked = false; | 126 | env->marked = false; |
139 | } | 127 | } |
@@ -153,7 +141,7 @@ dump_gc(void) { | |||
153 | display(obj); | 141 | display(obj); |
154 | bool is_free = false; | 142 | bool is_free = false; |
155 | for (size_t j = 0; j < array_cap(gc.objects); j++) { | 143 | for (size_t j = 0; j < array_cap(gc.objects); j++) { |
156 | if (gc.free_objects.buf[j] == i) { | 144 | if (gc.free_objects.offsets[j] == i) { |
157 | is_free = true; | 145 | is_free = true; |
158 | break; | 146 | break; |
159 | } | 147 | } |
@@ -169,11 +157,11 @@ dump_gc(void) { | |||
169 | printf("gc.active_envs.size: %ld\n", array_size(gc.active_envs)); | 157 | printf("gc.active_envs.size: %ld\n", array_size(gc.active_envs)); |
170 | printf("gc.active_envs.cap: %ld\n", array_cap(gc.active_envs)); | 158 | printf("gc.active_envs.cap: %ld\n", array_cap(gc.active_envs)); |
171 | printf("gc.obj_cap: %ld\n", array_cap(gc.objects)); | 159 | printf("gc.obj_cap: %ld\n", array_cap(gc.objects)); |
172 | printf("gc.free_objects.size: %ld\n", gc.free_objects.size); | 160 | printf("gc.free_objects.size: %ld\n", array_size(gc.free_objects.offsets)); |
173 | printf("gc.free_objects.cap: %ld\n", gc.free_objects.cap); | 161 | printf("gc.free_objects.cap: %ld\n", array_cap(gc.free_objects.offsets)); |
174 | printf("gc.free_objects.position: %ld\n", gc.free_objects.position); | 162 | printf("gc.free_objects.position: %ld\n", gc.free_objects.position); |
175 | printf("gc.free_envs.size: %ld\n", gc.free_envs.size); | 163 | printf("array_size(gc.free_envs.offsets): %ld\n", array_size(gc.free_envs.offsets)); |
176 | printf("gc.free_envs.cap: %ld\n", gc.free_envs.cap); | 164 | printf("gc.free_envs.cap: %ld\n", array_cap(gc.free_envs.offsets)); |
177 | printf("gc.free_envs.position: %ld\n", gc.free_envs.position); | 165 | printf("gc.free_envs.position: %ld\n", gc.free_envs.position); |
178 | printf("gc.envs.size: %ld\n", array_size(gc.envs)); | 166 | printf("gc.envs.size: %ld\n", array_size(gc.envs)); |
179 | printf("gc.envs.cap: %ld\n", array_cap(gc.envs)); | 167 | printf("gc.envs.cap: %ld\n", array_cap(gc.envs)); |
@@ -181,9 +169,9 @@ dump_gc(void) { | |||
181 | 169 | ||
182 | Object * | 170 | Object * |
183 | alloc_object(ObjectType type) { | 171 | alloc_object(ObjectType type) { |
184 | if (gc.free_objects.size == 0) { | 172 | if (array_head(gc.free_objects.offsets)->size == 0) { |
185 | mark_and_sweep(); | 173 | mark_and_sweep(); |
186 | if (gc.free_objects.size == 0) { | 174 | if (array_head(gc.free_objects.offsets)->size == 0) { |
187 | fprintf(stderr, "NO MORE OBJ MEMORY AVAILABLE WHERE IS YOUR GOD NOW MWAHAHA\n"); | 175 | fprintf(stderr, "NO MORE OBJ MEMORY AVAILABLE WHERE IS YOUR GOD NOW MWAHAHA\n"); |
188 | dump_gc(); | 176 | dump_gc(); |
189 | exit(EXIT_FAILURE); | 177 | exit(EXIT_FAILURE); |
@@ -200,8 +188,8 @@ alloc_object(ObjectType type) { | |||
200 | // later. | 188 | // later. |
201 | } | 189 | } |
202 | } | 190 | } |
203 | size_t slot = gc.free_objects.buf[gc.free_objects.position++]; | 191 | size_t slot = gc.free_objects.offsets[gc.free_objects.position++]; |
204 | gc.free_objects.size--; | 192 | array_head(gc.free_objects.offsets)->size--; |
205 | Object *obj = &gc.objects[slot]; | 193 | Object *obj = &gc.objects[slot]; |
206 | obj->type = type; | 194 | obj->type = type; |
207 | obj->marked = false; | 195 | obj->marked = false; |
diff --git a/src/bootstrap/gc.h b/src/bootstrap/gc.h index 90a1196..0a0bbd0 100644 --- a/src/bootstrap/gc.h +++ b/src/bootstrap/gc.h | |||
@@ -5,9 +5,7 @@ | |||
5 | #include "environment.h" | 5 | #include "environment.h" |
6 | 6 | ||
7 | typedef struct FreeList { | 7 | typedef struct FreeList { |
8 | size_t *buf; | 8 | size_t *offsets; |
9 | size_t size; | ||
10 | size_t cap; | ||
11 | size_t position; | 9 | size_t position; |
12 | } FreeList; | 10 | } FreeList; |
13 | 11 | ||