diff options
author | Koichi Sasada <ko1@atdot.net> | 2021-01-22 18:14:36 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2021-01-22 18:15:57 +0900 |
commit | e586345b7753e942c2946905c5acdc666fb0d47e (patch) | |
tree | 252870e1e7cd56dfaa88b5554a7ed20df44f6a09 /gc.c | |
parent | a1bb110b5614e676ba8ac3f24f7bfde9c82ea4f9 (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.c | 11 |
1 files changed, 10 insertions, 1 deletions
@@ -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; } |