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

ruby-changes:56362

From: Nobuyoshi <ko1@a...>
Date: Thu, 4 Jul 2019 01:04:46 +0900 (JST)
Subject: [ruby-changes:56362] Nobuyoshi Nakada: d0cd0866d8 (master): Disable GC during rb_objspace_reachable_object_p

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

From d0cd0866d82a58933e5dccd073c753c0c2ad4eb5 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 4 Jul 2019 00:58:52 +0900
Subject: Disable GC during rb_objspace_reachable_object_p

Try to fix CI breakage by [Feature #15974].

diff --git a/gc.c b/gc.c
index db830b9..94aa6ce 100644
--- a/gc.c
+++ b/gc.c
@@ -2954,39 +2954,7 @@ should_be_finalizable(VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L2954
     rb_check_frozen(obj);
 }
 
-struct reachable_object_data {
-    VALUE obj;
-    VALUE set;
-    bool found;
-};
-
-static void
-reachable_object_callback(VALUE child, void *dp)
-{
-    struct reachable_object_data *data = dp;
-    if (child == data->obj)
-        data->found = true;
-
-    if (data->found)
-        return;
-
-    // Maintain a set of objects already searched, so that we don't follow a cycle
-    if (rb_hash_lookup2(data->set, child, Qfalse))
-        return;
-    rb_hash_aset(data->set, child, Qtrue);
-
-    rb_objspace_reachable_objects_from(child, reachable_object_callback, data);
-}
-
-static int
-rb_objspace_reachable_object_p(VALUE obj, VALUE root)
-{
-    struct reachable_object_data data = {obj, rb_ident_hash_new()};
-    rb_obj_hide(data.set);
-    rb_objspace_reachable_objects_from(root, reachable_object_callback, &data);
-    rb_hash_clear(data.set);
-    return data.found;
-}
+static int rb_objspace_reachable_object_p(VALUE obj, VALUE root);
 
 /*
  *  call-seq:
@@ -9369,6 +9337,59 @@ rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, https://github.com/ruby/ruby/blob/trunk/gc.c#L9337
     POP_MARK_FUNC_DATA();
 }
 
+struct reachable_object_data {
+    VALUE obj;
+    VALUE set;
+};
+
+static void
+reachable_object_callback(VALUE child, void *dp)
+{
+    struct reachable_object_data *data = dp;
+    if (child == data->obj) {
+        rb_throw_obj(data->set, Qtrue);
+    }
+
+    // Maintain a set of objects already searched, so that we don't follow a cycle
+    if (rb_hash_lookup2(data->set, child, Qfalse))
+        return;
+    rb_hash_aset(data->set, child, Qtrue);
+
+    rb_objspace_reachable_objects_from(child, reachable_object_callback, data);
+}
+
+static VALUE
+call_reachable_object(RB_BLOCK_CALL_FUNC_ARGLIST(set, arg))
+{
+    struct reachable_object_data *data = (void *)arg;
+    VALUE obj = data->set;
+    data->set = rb_obj_hide(set);
+    gc_mark_children(&rb_objspace, obj);
+    rb_hash_clear(set);
+    return Qfalse;
+}
+
+static int
+rb_objspace_reachable_object_p(VALUE obj, VALUE root)
+{
+    rb_objspace_t *objspace = &rb_objspace;
+    int reachable = FALSE;
+    if (is_markable_object(objspace, obj)) {
+        struct reachable_object_data data = {obj, root};
+	struct mark_func_data_struct mfd = {&data, reachable_object_callback};
+        int prev_dont_gc = dont_gc;
+        enum ruby_tag_type state;
+
+        dont_gc = TRUE;
+	PUSH_MARK_FUNC_DATA(&mfd);
+        reachable = RTEST(rb_catch_protect(rb_ident_hash_new(), call_reachable_object, (VALUE)&data, &state));
+	POP_MARK_FUNC_DATA();
+        dont_gc = prev_dont_gc;
+        if (state) EC_JUMP_TAG(GET_EC(), state);
+    }
+    return reachable;
+}
+
 /*
   ------------------------ Extended allocator ------------------------
 */
-- 
cgit v0.10.2


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

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