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

ruby-changes:56365

From: Nobuyoshi <ko1@a...>
Date: Thu, 4 Jul 2019 04:04:17 +0900 (JST)
Subject: [ruby-changes:56365] Nobuyoshi Nakada: 23c92b6f82 (master): Revert self-referencing finalizer warning [Feature #15974]

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

From 23c92b6f820f670994026423d4c7b5abcf51eafa Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Wed, 3 Jul 2019 14:44:20 +0900
Subject: Revert self-referencing finalizer warning [Feature #15974]

It has caused CI failures.

* d0cd0866d82a58933e5dccd073c753c0c2ad4eb5

  Disable GC during rb_objspace_reachable_object_p

* 89cef1c56b3a0f9c5e6ccc22a5044477a4fd16c1

  Version guard for [Feature #15974]

* 796eeb6339952d92ae1b353d450c7883e589852d.

  Fix up [Feature #15974]

* 928260c2a613bbdd4402c300e0bf86ae7562e52a.

  Warn in verbose mode on defining a finalizer that captures the object

diff --git a/gc.c b/gc.c
index 084923f..2b7b039 100644
--- a/gc.c
+++ b/gc.c
@@ -2954,8 +2954,6 @@ should_be_finalizable(VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L2954
     rb_check_frozen(obj);
 }
 
-static int rb_objspace_reachable_object_p(VALUE obj, VALUE root);
-
 /*
  *  call-seq:
  *     ObjectSpace.define_finalizer(obj, aProc=proc())
@@ -2965,10 +2963,6 @@ static int rb_objspace_reachable_object_p(VALUE obj, VALUE root); https://github.com/ruby/ruby/blob/trunk/gc.c#L2963
  *  as an argument to <i>aProc</i>. If <i>aProc</i> is a lambda or
  *  method, make sure it can be called with a single argument.
  *
- *  In verbose mode (<code>-w</code>) a warning will be issued if
- *  the object is reachable from <i>aProc</i>, which may prevent
- *  finalization.
- *
  */
 
 static VALUE
@@ -2985,11 +2979,6 @@ define_final(int argc, VALUE *argv, VALUE os) https://github.com/ruby/ruby/blob/trunk/gc.c#L2979
 	should_be_callable(block);
     }
 
-    if (RTEST(ruby_verbose)) {
-        if (rb_objspace_reachable_object_p(obj, block))
-            rb_warn("object is reachable from finalizer - it may never be run");
-    }
-
     return define_final0(obj, block);
 }
 
@@ -9337,59 +9326,6 @@ rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, https://github.com/ruby/ruby/blob/trunk/gc.c#L9326
     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 ------------------------
 */
diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb
index fef7667..b7e4747 100644
--- a/spec/ruby/core/objectspace/define_finalizer_spec.rb
+++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb
@@ -65,32 +65,4 @@ describe "ObjectSpace.define_finalizer" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/objectspace/define_finalizer_spec.rb#L65
 
     ruby_exe(code).lines.sort.should == ["finalized1\n", "finalized2\n"]
   end
-
-  ruby_version_is "2.7" do
-    it "warns in verbose mode if it is self-referencing" do
-      code = <<-RUBY
-        obj = "Test"
-        handler = Proc.new { puts "finalized" }
-        ObjectSpace.define_finalizer(obj, handler)
-        exit 0
-      RUBY
-
-      ruby_exe(code, :options => "-w", :args => "2>&1").should include("warning: object is reachable from finalizer - it may never be run")
-    end
-
-    it "warns in verbose mode if it is indirectly self-referencing" do
-      code = <<-RUBY
-        def scoped(indirect)
-          Proc.new { puts "finalized" }
-        end
-        obj = "Test"
-        indirect = [obj]
-        handler = scoped(indirect)
-        ObjectSpace.define_finalizer(obj, handler)
-        exit 0
-      RUBY
-
-      ruby_exe(code, :options => "-w", :args => "2>&1").should include("warning: object is reachable from finalizer - it may never be run")
-    end
-  end
 end
diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb
index 9007e05..c352b75 100644
--- a/test/ruby/test_objectspace.rb
+++ b/test/ruby/test_objectspace.rb
@@ -56,7 +56,7 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_objectspace.rb#L56
   end
 
   def test_finalizer
-    assert_in_out_err(["-W0", "-e", <<-END], "", %w(:ok :ok :ok :ok))
+    assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
       a = []
       ObjectSpace.define_finalizer(a) { p :ok }
       b = a.dup
@@ -76,8 +76,8 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_objectspace.rb#L76
       ObjectSpace.define_finalizer([], fin)
       CODE
     end
-    assert_in_out_err(["-W0"], code[""], ["finalized"])
-    assert_in_out_err(["-W0"], code["private "], ["finalized"])
+    assert_in_out_err([], code[""], ["finalized"])
+    assert_in_out_err([], code["private "], ["finalized"])
     c = EnvUtil.labeled_class("C\u{3042}").new
     o = Object.new
     assert_raise_with_message(ArgumentError, /C\u{3042}/) {
@@ -131,32 +131,6 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_objectspace.rb#L131
     END
   end
 
-  def test_self_referencing_finalizer
-    assert_separately(["-w"], "#{<<~"begin;"}\n#{<<~'end;'}")
-    begin;
-      obj = +"Test"
-      handler = proc {puts "finalized"}
-      assert_warning(/object is reachable from finalizer/) do
-        ObjectSpace.define_finalizer(obj, handler)
-      end
-    end;
-  end
-
-  def test_indirectly_self_referencing_finalizer
-    assert_separately(["-w"], "#{<<~"begin;"}\n#{<<~'end;'}")
-    begin;
-      def scoped(indirect)
-        proc {puts "finalized"}
-      end
-      obj = +"Test"
-      indirect = [obj]
-      handler = scoped(indirect)
-      assert_warning(/object is reachable from finalizer/) do
-        ObjectSpace.define_finalizer(obj, handler)
-      end
-    end;
-  end
-
   def test_each_object
     klass = Class.new
     new_obj = klass.new
-- 
cgit v0.10.2


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

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