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/