From 367961e7119fe709a8f7b7ef34587f30ad05bccc Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Fri, 23 Jan 2026 21:04:16 +0100 Subject: [PATCH] GC: Run it automatically Finally running it automatically :). Method for when to run it was copied from Crafting Interpreters by Robert Nystrom. Should have bought that book earlier :D --- examples/mandelbrot.apfl | 2 +- src/gc.c | 20 ++++++++++++++++++-- src/gc.h | 3 +++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/examples/mandelbrot.apfl b/examples/mandelbrot.apfl index 3c3ec27..284d127 100644 --- a/examples/mandelbrot.apfl +++ b/examples/mandelbrot.apfl @@ -36,6 +36,6 @@ iterdim height { b -> iterdim width { a -> line = & line (if (mandel maxiter a::b 0::0) {"#"} {" "}) } - gc 'collect + print line } diff --git a/src/gc.c b/src/gc.c index 1e700e0..a87b5d5 100644 --- a/src/gc.c +++ b/src/gc.c @@ -11,6 +11,9 @@ #include "scope.h" #include "value.h" +#define GC_INITIAL_NEXT_GC 1024 * 1024 +#define GC_GROWTH_FACTOR 2 + // #define GC_DEBUG_COLLECT_EVERY_ALLOCATION 1 // #define GC_DEBUG_STATS 1 // #define GC_DEBUG_WIPE_RECLAIMED_OBJECTS 1 @@ -55,12 +58,19 @@ gc_allocator(void *opaque, void *oldptr, size_t oldsize, size_t newsize) apfl_ctx ctx = opaque; struct gc *gc = &ctx->gc; + gc->bytes_allocated += newsize; + gc->bytes_allocated -= oldsize; + #ifdef GC_DEBUG_COLLECT_EVERY_ALLOCATION if (newsize != 0 && !gc->is_collecting) { - apfl_gc_full(gc); + apfl_gc_full(ctx); } #endif + if (gc->bytes_allocated > gc->next_gc && !gc->is_collecting) { + apfl_gc_full(ctx); + } + void *out = ALLOCATOR_CALL(gc->base_allocator, oldptr, oldsize, newsize); if (newsize != 0 && out == NULL && !gc->is_collecting) { // We're out of memory! Try to get out of this situation by doing a full @@ -106,6 +116,10 @@ apfl_gc_init(apfl_ctx ctx, struct apfl_allocator allocator) .cap = 0, }; gc->tmproot_for_adding = NULL; + + gc->bytes_allocated = 0; + gc->next_gc = GC_INITIAL_NEXT_GC; + gc->is_collecting = false; } @@ -433,7 +447,7 @@ sweep(apfl_ctx ctx) deinit_object(ctx, object); #ifdef GC_DEBUG_WIPE_RECLAIMED_OBJECTS - memset(object, 0, sizeof(struct gc_object)); + memset(object, 0x77, sizeof(struct gc_object)); object->type = 0xFF; // Some intentionally undefined type #endif @@ -496,6 +510,8 @@ apfl_gc_full(apfl_ctx ctx) sweep(ctx); DUMP_ON_COLLECT(); + gc->next_gc = gc->bytes_allocated * GC_GROWTH_FACTOR; + gc->is_collecting = false; } diff --git a/src/gc.h b/src/gc.h index b139d65..d642fca 100644 --- a/src/gc.h +++ b/src/gc.h @@ -54,6 +54,9 @@ struct gc { struct gc_tmproots tmproots; struct gc_object *tmproot_for_adding; + size_t bytes_allocated; + size_t next_gc; + bool is_collecting; };