ruby-changes:39182
From: nobu <ko1@a...>
Date: Thu, 16 Jul 2015 14:18:50 +0900 (JST)
Subject: [ruby-changes:39182] nobu:r51263 (trunk): vm.c: fix mark with rewinding cfp
nobu 2015-07-16 14:18:40 +0900 (Thu, 16 Jul 2015) New Revision: 51263 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51263 Log: vm.c: fix mark with rewinding cfp * vm.c (m_core_hash_merge_ptr): copy the arguments to the machine stack before rewinding the control frame pointer and leaving the arguments outside valid region of the value stack. [ruby-core:69969] [Bug #11352] Modified files: trunk/ChangeLog trunk/test/ruby/test_literal.rb trunk/vm.c Index: ChangeLog =================================================================== --- ChangeLog (revision 51262) +++ ChangeLog (revision 51263) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Jul 16 14:18:37 2015 Nobuyoshi Nakada <nobu@r...> + + * vm.c (m_core_hash_merge_ptr): copy the arguments to the machine + stack before rewinding the control frame pointer and leaving the + arguments outside valid region of the value stack. + [ruby-core:69969] [Bug #11352] + + Thu Jul 16 11:38:21 2015 Eric Wong <e@8...> * process.c (close_unless_reserved): declare type of `fd' arg Index: vm.c =================================================================== --- vm.c (revision 51262) +++ vm.c (revision 51263) @@ -2400,6 +2400,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L2400 core_hash_merge_ary(VALUE hash, VALUE ary) { core_hash_merge(hash, RARRAY_LEN(ary), RARRAY_CONST_PTR(ary)); + RB_GC_GUARD(ary); return hash; } @@ -2407,8 +2408,14 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L2408 m_core_hash_merge_ptr(int argc, VALUE *argv, VALUE recv) { VALUE hash = argv[0]; + VALUE *args; - REWIND_CFP(core_hash_merge(hash, argc-1, argv+1)); + --argc; ++argv; + VM_ASSERT(argc <= 256); + args = ALLOCA_N(VALUE, argc); + MEMCPY(args, argv, VALUE, argc); + argv = args; + REWIND_CFP(core_hash_merge(hash, argc, argv)); return hash; } Index: test/ruby/test_literal.rb =================================================================== --- test/ruby/test_literal.rb (revision 51262) +++ test/ruby/test_literal.rb (revision 51263) @@ -192,7 +192,9 @@ class TestRubyLiteral < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/ruby/test_literal.rb#L192 assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("[#{(1..1_000_000).to_a.join(", ")}]").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems] assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("{#{(1..1_000_000).map{|n| "#{n} => x"}.join(', ')}}").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems] assert_normal_exit %q{GC.disable=true; x = nil; raise if eval("{#{(1..1_000_000).map{|n| "#{n} => #{n}"}.join(', ')}}").size != 1_000_000}, "", timeout: 300, child_env: %[--disable-gems] + end + def test_big_hash_literal bug7466 = '[ruby-dev:46658]' h = { 0xFE042 => 0xE5CD, @@ -327,6 +329,19 @@ class TestRubyLiteral < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/ruby/test_literal.rb#L329 } k = h.keys assert_equal([129, 0xFE331], [k.size, k.last], bug7466) + + code = [ + "h = {", + (1..128).map {|i| "#{i} => 0,"}, + (129..140).map {|i| "#{i} => [],"}, + "}", + ].join + assert_separately([], <<-"end;") + GC.stress = true + #{code} + GC.stress = false + assert_equal(140, h.size) + end; end def test_range -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/