From 424374d3302d8d25165007e7afedf14b1a76d23e Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 2 Feb 2022 15:32:38 -0500 Subject: [PATCH] Fix case when gc_marks_continue does not yield slots gc_marks_continue will start sweeping when it finishes marking. However, if the heap we are trying to allocate into is full, then the sweeping may not yield any free slots. If we don't call gc_sweep_continue immediate after this, then another GC will be started halfway during lazy sweeping. gc_sweep_continue will either grow the heap or finish sweeping. --- gc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gc.c b/gc.c index 4eaceef80714a5..0309559481b3b7 100644 --- a/gc.c +++ b/gc.c @@ -2204,13 +2204,14 @@ heap_prepare(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap { GC_ASSERT(heap->free_pages == NULL); - if (is_lazy_sweeping(objspace)) { - gc_sweep_continue(objspace, size_pool, heap); - } - else if (is_incremental_marking(objspace)) { + if (is_incremental_marking(objspace)) { gc_marks_continue(objspace, size_pool, heap); } + if (heap->free_pages == NULL && is_lazy_sweeping(objspace)) { + gc_sweep_continue(objspace, size_pool, heap); + } + if (heap->free_pages == NULL && (will_be_incremental_marking(objspace) || heap_increment(objspace, size_pool, heap) == FALSE) && gc_start(objspace, GPR_FLAG_NEWOBJ) == FALSE) {