diff --git a/src/gc.c b/src/gc.c index 99e28aa..a2f4f75 100644 --- a/src/gc.c +++ b/src/gc.c @@ -43,7 +43,7 @@ gc_allocator(void *opaque, void *oldptr, size_t oldsize, size_t newsize) struct gc *gc = opaque; void *out = ALLOCATOR_CALL(gc->base_allocator, oldptr, oldsize, newsize); - if (newsize != 0 && out == NULL) { + if (newsize != 0 && out == NULL && !gc->is_collecting) { // We're out of memory! Try to get out of this situation by doing a full // GC run. apfl_gc_full(gc); @@ -87,6 +87,7 @@ apfl_gc_init(struct gc *gc, struct apfl_allocator allocator, gc_roots_getter roo .cap = 0, }; gc->tmproot_for_adding = NULL; + gc->is_collecting = false; } static struct gc_block * @@ -373,12 +374,17 @@ sweep(struct gc *gc) void apfl_gc_full(struct gc *gc) { + assert(!gc->is_collecting); + gc->is_collecting = true; + mark_roots(gc); apfl_gc_debug_dump_graph(gc, stderr); trace_while_having_grey(gc); apfl_gc_debug_dump_graph(gc, stderr); sweep(gc); apfl_gc_debug_dump_graph(gc, stderr); + + gc->is_collecting = false; } static const char * diff --git a/src/gc.h b/src/gc.h index af1d90c..07bf016 100644 --- a/src/gc.h +++ b/src/gc.h @@ -50,6 +50,8 @@ struct gc { void *roots_getter_opaque; struct gc_tmproots tmproots; struct gc_object *tmproot_for_adding; + + bool is_collecting; };