From 953a44b3fd61302e6b86d549109a718a001c9b3c Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 17 Oct 2021 14:30:33 +0200 Subject: Fix heap corruption bug due to bad initialization --- src/bootstrap/environment.c | 1 + src/bootstrap/gc.c | 41 +++++++++++++++++++++++------------------ src/bootstrap/main.c | 2 +- 3 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c index 570c5d4..d5e954b 100644 --- a/src/bootstrap/environment.c +++ b/src/bootstrap/environment.c @@ -21,6 +21,7 @@ Environment * env_create(Environment *parent) { Environment *env = alloc_env(); env->parent = parent; + env->marked = false; env->buf = NULL; env->size = 0; env->cap = ENV_BUF_CAP; diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c index 381ab6b..5f023bc 100644 --- a/src/bootstrap/gc.c +++ b/src/bootstrap/gc.c @@ -35,13 +35,9 @@ typedef struct GC { ActiveEnvs active_envs; } GC; -// FIXME: small value for testing purposes -// #define GC_OBJS_CAP 1024 * 1024 * 10 -// #define GC_ROOTS_CAP 1024 -// #define GC_ENVS_CAP 1024 * 1024 * 2 #define GC_OBJS_CAP 1024 * 1024 -#define GC_ROOTS_CAP 1024 * 1024 -#define GC_ENVS_CAP 1024 * 1024 +#define GC_ROOTS_CAP 1024 +#define GC_ENVS_CAP 1024 * 4 static GC gc; @@ -82,7 +78,8 @@ void push_active_env(Environment *env) { if (gc.active_envs.size == gc.active_envs.cap) { gc.active_envs.cap *= 2; - gc.active_envs.buf = realloc(gc.active_envs.buf, gc.active_envs.cap * sizeof(Environment *)); + gc.active_envs.buf = realloc(gc.active_envs.buf, + gc.active_envs.cap * sizeof(Environment *)); } gc.active_envs.buf[gc.active_envs.size++] = env; } @@ -148,9 +145,9 @@ mark_environment(Environment *env) { } env->marked = true; for (size_t i = 0; i < env->size; i++) { - EnvEntry entry = env->buf[i]; - mark_obj(entry.symbol); - mark_obj(entry.value); + EnvEntry *entry = &env->buf[i]; + mark_obj(entry->symbol); + mark_obj(entry->value); } } @@ -177,11 +174,7 @@ mark_and_sweep(void) { for (size_t i = 0; i < gc.active_envs.size; i++) { mark_environment(gc.active_envs.buf[i]); } - for (size_t i = 0; i < gc.roots.size; i++) { - if (gc.roots.buf[i]->marked) { - continue; - } mark_obj(gc.roots.buf[i]); } @@ -231,8 +224,7 @@ dump_gc(void) { display(gc.roots.buf[i]); printf("\n"); } - printf("------------- OBJECTS ------------- \n"); - // for (size_t i = 0; i < gc.obj_cap; i++) { + printf("--------- OBJECTS (TOP 20) -------- \n"); for (size_t i = 0; i < 20; i++) { printf("i: %ld -> ", i); Object *obj = &gc.objects[i]; @@ -249,8 +241,20 @@ dump_gc(void) { } printf("\n"); } - printf("FREE OBJECTS: %ld\n", gc.free_objects.size); - printf("ENVIRONMENTS: %ld\n", gc.envs.size); + printf("-------------- MISC --------------- \n"); + printf("gc.roots.size: %ld\n", gc.roots.size); + printf("gc.roots.cap: %ld\n", gc.roots.cap); + printf("gc.active_envs.size: %ld\n", gc.active_envs.size); + printf("gc.active_envs.cap: %ld\n", gc.active_envs.cap); + printf("gc.obj_cap: %ld\n", gc.obj_cap); + printf("gc.free_objects.size: %ld\n", gc.free_objects.size); + printf("gc.free_objects.cap: %ld\n", gc.free_objects.cap); + printf("gc.free_objects.position: %ld\n", gc.free_objects.position); + printf("gc.free_envs.size: %ld\n", gc.free_envs.size); + printf("gc.free_envs.cap: %ld\n", gc.free_envs.cap); + printf("gc.free_envs.position: %ld\n", gc.free_envs.position); + printf("gc.envs.size: %ld\n", gc.envs.size); + printf("gc.envs.cap: %ld\n", gc.envs.cap); } Object * @@ -278,5 +282,6 @@ alloc_object(ObjectType type) { gc.free_objects.size--; Object *obj = get_obj(slot); obj->type = type; + obj->marked = false; return obj; } diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 7251e60..bf2354b 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -115,10 +115,10 @@ process_source(const StringView *source) { size_t root_stack_size = gc.roots.size; Object *root = parse_tree(&visitor); gc.roots.size = root_stack_size; - push_root(root); if (root == obj_err || errors_n != 0) { break; } + push_root(root); Object *result = eval(global_env, root); if (result != obj_nil) { -- cgit v1.2.1