[前][次][番号順一覧][スレッド一覧]

ruby-changes:71183

From: Koichi <ko1@a...>
Date: Mon, 14 Feb 2022 17:18:17 +0900 (JST)
Subject: [ruby-changes:71183] 76e594d515 (master): fix GC event synchronization

https://git.ruby-lang.org/ruby.git/commit/?id=76e594d515

From 76e594d5157bd763636adb096d4aa06688ac03ac Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Mon, 14 Feb 2022 16:10:18 +0900
Subject: fix GC event synchronization

(1) gc_verify_internal_consistency() use barrier locking
    for consistency while `during_gc == true` at the end
    of the sweep on `RGENGC_CHECK_MODE >= 2`.
(2) `rb_objspace_reachable_objects_from()` is called without
    VM synchronization and it checks `during_gc != true`.

So (1) and (2) causes BUG because of `during_gc == true`.
To prevent this error, wait for VM barrier on `during_gc == false`
and introduce VM locking on `rb_objspace_reachable_objects_from()`.

http://ci.rvm.jp/results/trunk-asserts@phosphorus-docker/3830088
---
 gc.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/gc.c b/gc.c
index d4b798b381..1c80a5573f 100644
--- a/gc.c
+++ b/gc.c
@@ -5722,10 +5722,6 @@ gc_sweep_finish(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L5722
 
     gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0);
     gc_mode_transition(objspace, gc_mode_none);
-
-#if RGENGC_CHECK_MODE >= 2
-    gc_verify_internal_consistency(objspace);
-#endif
 }
 
 static int
@@ -9340,6 +9336,14 @@ gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_l https://github.com/ruby/ruby/blob/trunk/gc.c#L9336
     mjit_gc_exit_hook();
     gc_exit_clock(objspace, event);
     RB_VM_LOCK_LEAVE_LEV(lock_lev);
+
+#if RGENGC_CHECK_MODE >= 2
+    if (event == gc_enter_event_sweep_continue && gc_mode(objspace) == gc_mode_none) {
+        GC_ASSERT(!during_gc);
+        // sweep finished
+        gc_verify_internal_consistency(objspace);
+    }
+#endif
 }
 
 static void *
@@ -11226,19 +11230,23 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void * https://github.com/ruby/ruby/blob/trunk/gc.c#L11230
 {
     rb_objspace_t *objspace = &rb_objspace;
 
-    if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
+    RB_VM_LOCK_ENTER();
+    {
+        if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
 
-    if (is_markable_object(objspace, obj)) {
-        rb_ractor_t *cr = GET_RACTOR();
-        struct gc_mark_func_data_struct mfd = {
-            .mark_func = func,
-            .data = data,
-        }, *prev_mfd = cr->mfd;
+        if (is_markable_object(objspace, obj)) {
+            rb_ractor_t *cr = GET_RACTOR();
+            struct gc_mark_func_data_struct mfd = {
+                .mark_func = func,
+                .data = data,
+            }, *prev_mfd = cr->mfd;
 
-        cr->mfd = &mfd;
-	gc_mark_children(objspace, obj);
-        cr->mfd = prev_mfd;
+            cr->mfd = &mfd;
+            gc_mark_children(objspace, obj);
+            cr->mfd = prev_mfd;
+        }
     }
+    RB_VM_LOCK_LEAVE();
 }
 
 struct root_objects_data {
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]