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
This commit is contained in:
Laria 2026-01-23 21:04:16 +01:00
parent 740a968a12
commit 367961e711
3 changed files with 22 additions and 3 deletions

View file

@ -36,6 +36,6 @@ iterdim height { b ->
iterdim width { a ->
line = & line (if (mandel maxiter a::b 0::0) {"#"} {" "})
}
gc 'collect
print line
}

View file

@ -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;
}

View file

@ -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;
};