From e586345b7753e942c2946905c5acdc666fb0d47e Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 22 Jan 2021 18:14:36 +0900 Subject: [PATCH] check is_incremental_marking() again is_incremental_marking() can be changed after checking the flag without locking, especially on `GC.stress = true`. --- gc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gc.c b/gc.c index 73f8bcc88a..9dbad1821e 100644 --- a/gc.c +++ b/gc.c @@ -7803,6 +7803,7 @@ rb_gc_writebarrier(VALUE a, VALUE b) if (RGENGC_CHECK_MODE && SPECIAL_CONST_P(a)) rb_bug("rb_gc_writebarrier: a is special const"); if (RGENGC_CHECK_MODE && SPECIAL_CONST_P(b)) rb_bug("rb_gc_writebarrier: b is special const"); + retry: if (!is_incremental_marking(objspace)) { if (!RVALUE_OLD_P(a) || RVALUE_OLD_P(b)) { // do nothing @@ -7812,12 +7813,20 @@ rb_gc_writebarrier(VALUE a, VALUE b) } } else { + bool retry = false; /* slow path */ RB_VM_LOCK_ENTER_NO_BARRIER(); { - gc_writebarrier_incremental(a, b, objspace); + if (is_incremental_marking(objspace)) { + gc_writebarrier_incremental(a, b, objspace); + } + else { + retry = true; + } } RB_VM_LOCK_LEAVE_NO_BARRIER(); + + if (retry) goto retry; } return; }