From 4295a8c560f84241d289628e33a4700d903d12d4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 5 Dec 2022 22:30:10 +0900 Subject: [PATCH] gc.c (final_marking_phase): mark gray objects after marking If pre-allocate object is modified (e.g. singleton class added) in certain timing, some objects may be swept even if it's alive. The problem was reported by Denis Kasak via private communication. --- src/gc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gc.c b/src/gc.c index 923aaf0ec..7b9f098b5 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1131,24 +1131,26 @@ final_marking_phase(mrb_state *mrb, mrb_gc *gc) } mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); - gc_mark_gray_list(mrb, gc); - mrb_assert(gc->gray_list == NULL); - gc->gray_list = gc->atomic_gray_list; - gc->atomic_gray_list = NULL; - gc_mark_gray_list(mrb, gc); - mrb_assert(gc->gray_list == NULL); - /* mark pre-allocated exception */ clear_error_object(mrb, mrb->nomem_err); clear_error_object(mrb, mrb->stack_err); #ifdef MRB_GC_FIXED_ARENA clear_error_object(mrb, mrb->arena_err); #endif + + gc_mark_gray_list(mrb, gc); + mrb_assert(gc->gray_list == NULL); + gc->gray_list = gc->atomic_gray_list; + gc->atomic_gray_list = NULL; + gc_mark_gray_list(mrb, gc); + mrb_assert(gc->gray_list == NULL); } static void prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc) { + // mrb_assert(gc->atomic_gray_list == NULL); + // mrb_assert(gc->gray_list == NULL); gc->state = MRB_GC_STATE_SWEEP; gc->sweeps = gc->heaps; gc->live_after_mark = gc->live;