summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2021-01-22 18:14:36 +0900
committerKoichi Sasada <ko1@atdot.net>2021-01-22 18:15:57 +0900
commite586345b7753e942c2946905c5acdc666fb0d47e (patch)
tree252870e1e7cd56dfaa88b5554a7ed20df44f6a09 /gc.c
parenta1bb110b5614e676ba8ac3f24f7bfde9c82ea4f9 (diff)
check is_incremental_marking() again
is_incremental_marking() can be changed after checking the flag without locking, especially on `GC.stress = true`.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c11
1 files changed, 10 insertions, 1 deletions
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;
}