gc: Prevent recursive garbage collection
This commit is contained in:
parent
1a41df2389
commit
7e592cdb96
2 changed files with 9 additions and 1 deletions
8
src/gc.c
8
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 *
|
||||
|
|
|
|||
2
src/gc.h
2
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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue