aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-15 17:58:05 +0200
committerBad Diode <bd@badd10de.dev>2021-10-15 17:58:05 +0200
commit87b1a0d4a833dd0b2164481be45f7d1c59375040 (patch)
tree87828c2149c7db2880b22a306b2c5d3511185cae
parent14814ecbf53760654aab34e0613abf347a54113f (diff)
downloadbdl-87b1a0d4a833dd0b2164481be45f7d1c59375040.tar.gz
bdl-87b1a0d4a833dd0b2164481be45f7d1c59375040.zip
Add boilerplate for GC allocator
-rw-r--r--src/bootstrap/gc.c48
-rwxr-xr-xsrc/bootstrap/main.c7
2 files changed, 53 insertions, 2 deletions
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 @@
1typedef struct GC {
2 Object *obj_list;
3 // Free list keeps track of the offset numbers from the obj_list
4 size_t *free_list;
5 size_t obj_size;
6 size_t obj_cap;
7 size_t fl_pos;
8 size_t available_slots;
9} GC;
10
11// FIXME: small value for testing purposes
12#define GC_INITIAL_HEAP 100000
13
14static GC gc;
15
16void
17init_gc(void) {
18 gc = (GC){
19 .obj_cap = GC_INITIAL_HEAP,
20 .available_slots = GC_INITIAL_HEAP,
21 };
22 gc.free_list = malloc(GC_INITIAL_HEAP * sizeof(size_t *));
23 gc.obj_list = malloc(GC_INITIAL_HEAP * sizeof(Object *));
24
25 // The free list stores the offset from the initial position for all
26 // available slots.
27 for (size_t i = 0; i < gc.obj_cap; i++) {
28 gc.free_list[i] = i;
29 }
30}
31
32Object *
33alloc_object(ObjectType type) {
34 if (gc.available_slots == 0) {
35 // TODO: trigger garbage collection.
36 if (gc.available_slots == 0) {
37 // TODO: grow heap tables.
38 // NOTE: When growing the tables, we might lose the pointer
39 // references! Should we work with offsets all the way? That is for
40 // cdr and car? Should we have a utility function?
41 }
42 }
43 size_t slot = gc.free_list[gc.fl_pos++];
44 gc.available_slots--;
45 Object *obj = gc.obj_list + slot;
46 obj->type = type;
47 return obj;
48}
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 @@
1#include <assert.h> 1#include <assert.h>
2#include <getopt.h> 2#include <getopt.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <stdint.h>
4#include <stdio.h> 5#include <stdio.h>
5#include <stdlib.h> 6#include <stdlib.h>
6#include <string.h> 7#include <string.h>
@@ -12,6 +13,7 @@
12#include "objects.c" 13#include "objects.c"
13#include "parser.c" 14#include "parser.c"
14#include "environment.c" 15#include "environment.c"
16#include "gc.c"
15#include "primitives.c" 17#include "primitives.c"
16 18
17// 19//
@@ -26,6 +28,9 @@
26 28
27void 29void
28init(void) { 30init(void) {
31 // Initialize garbage collector.
32 init_gc();
33
29 // Initialize singletons. 34 // Initialize singletons.
30 obj_nil = alloc_object(OBJ_TYPE_NIL); 35 obj_nil = alloc_object(OBJ_TYPE_NIL);
31 obj_true = alloc_object(OBJ_TYPE_BOOL); 36 obj_true = alloc_object(OBJ_TYPE_BOOL);
@@ -99,7 +104,6 @@ process_source(const StringView *source) {
99 while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) { 104 while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) {
100 Object *root = parse_tree(&visitor); 105 Object *root = parse_tree(&visitor);
101 if (root == obj_err || errors_n != 0) { 106 if (root == obj_err || errors_n != 0) {
102 free_objects(root);
103 break; 107 break;
104 } 108 }
105 109
@@ -109,7 +113,6 @@ process_source(const StringView *source) {
109 display(result); 113 display(result);
110 printf("\n"); 114 printf("\n");
111 } 115 }
112 free_objects(root);
113 } 116 }
114 117
115 if (tokens.buf != NULL) { 118 if (tokens.buf != NULL) {