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

ruby-changes:39647

From: ko1 <ko1@a...>
Date: Mon, 31 Aug 2015 17:08:16 +0900 (JST)
Subject: [ruby-changes:39647] ko1:r51728 (trunk): * class.c (move_refined_method): should insert a write barrier

ko1	2015-08-31 17:07:59 +0900 (Mon, 31 Aug 2015)

  New Revision: 51728

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51728

  Log:
    * class.c (move_refined_method): should insert a write barrier
      from an original class to a created (cloned) method entry.
    * test/ruby/test_refinement.rb: add a test.

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/test/ruby/test_refinement.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51727)
+++ ChangeLog	(revision 51728)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Aug 31 17:04:45 2015  Koichi Sasada  <ko1@a...>
+
+	* class.c (move_refined_method): should insert a write barrier
+	  from an original class to a created (cloned) method entry.
+
+	* test/ruby/test_refinement.rb: add a test.
+
 Sun Aug 30 02:42:22 2015  Aaron Patterson <tenderlove@r...>
 
 	* ext/openssl/ossl_ssl.c (ossl_ssl_method_tab): Only add SSLv3 support
Index: class.c
===================================================================
--- class.c	(revision 51727)
+++ class.c	(revision 51728)
@@ -911,7 +911,8 @@ static enum rb_id_table_iterator_result https://github.com/ruby/ruby/blob/trunk/class.c#L911
 move_refined_method(ID key, VALUE value, void *data)
 {
     rb_method_entry_t *me = (rb_method_entry_t *) value;
-    struct rb_id_table *tbl = (struct rb_id_table *) data;
+    VALUE klass = (VALUE)data;
+    struct rb_id_table *tbl = RCLASS_M_TBL(klass);
 
     if (me->def->type == VM_METHOD_TYPE_REFINED) {
 	if (me->def->body.refined.orig_me) {
@@ -919,6 +920,7 @@ move_refined_method(ID key, VALUE value, https://github.com/ruby/ruby/blob/trunk/class.c#L920
 	    RB_OBJ_WRITE(me, &me->def->body.refined.orig_me, NULL);
 	    new_me = rb_method_entry_clone(me);
 	    rb_id_table_insert(tbl, key, (VALUE)new_me);
+	    RB_OBJ_WRITTEN(klass, Qundef, new_me);
 	    rb_method_entry_copy(me, orig_me);
 	    return ID_TABLE_CONTINUE;
 	}
@@ -953,7 +955,7 @@ rb_prepend_module(VALUE klass, VALUE mod https://github.com/ruby/ruby/blob/trunk/class.c#L955
 	RCLASS_SET_ORIGIN(klass, origin);
 	RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
 	RCLASS_M_TBL_INIT(klass);
-	rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)RCLASS_M_TBL(klass));
+	rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass);
     }
     changed = include_modules_at(klass, klass, module, FALSE);
     if (changed < 0)
Index: test/ruby/test_refinement.rb
===================================================================
--- test/ruby/test_refinement.rb	(revision 51727)
+++ test/ruby/test_refinement.rb	(revision 51728)
@@ -744,6 +744,7 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L744
                  PrependIntoRefinement::User.invoke_baz_on(x))
   end
 
+  PrependAfterRefine_CODE = <<-EOC
   module PrependAfterRefine
     class C
       def foo
@@ -777,6 +778,18 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L778
       prepend Mixin
     end
   end
+  EOC
+  eval PrependAfterRefine_CODE
+
+  def test_prepend_after_refine_wb_miss
+    assert_normal_exit %Q{
+      GC.stress = true
+      10.times{
+        #{PrependAfterRefine_CODE}
+        undef PrependAfterRefine
+      }
+    }
+  end
 
   def test_prepend_after_refine
     x = eval_using(PrependAfterRefine::M,

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

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