From 214ed4cbc6f33675230602dd09268b436da96f7d Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Thu, 9 Jun 2022 15:59:08 +0100 Subject: [Feature #18901] Support size pool movement for Arrays This commit enables Arrays to move between size pools during compaction. This can occur if the array is mutated such that it would fit in a different size pool when embedded. The move is carried out in two stages: 1. The RVALUE is moved to a destination heap during object movement phase of compaction 2. The array data is re-embedded and the original buffer free'd if required. This happens during the update references step --- test/ruby/test_gc_compact.rb | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'test/ruby') diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 3927958e9c..8ecb41438a 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -209,6 +209,46 @@ class TestGCCompact < Test::Unit::TestCase assert_equal([:call, :line], results) end + def test_moving_arrays_down_size_pools + omit if !GC.using_rvargc? + assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV) + begin; + ARY_COUNT = 500 + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + arys = ARY_COUNT.times.map do + ary = "abbbbbbbbbb".chars + ary.uniq! + end + + stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) + assert_operator(stats.dig(:moved_down, :T_ARRAY), :>=, ARY_COUNT) + assert(arys) # warning: assigned but unused variable - arys + end; + end + + def test_moving_arrays_up_size_pools + omit if !GC.using_rvargc? + assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV) + begin; + ARY_COUNT = 500 + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + ary = "hello".chars + arys = ARY_COUNT.times.map do + x = [] + ary.each { |e| x << e } + x + end + + stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) + assert_operator(stats.dig(:moved_up, :T_ARRAY), :>=, ARY_COUNT) + assert(arys) # warning: assigned but unused variable - arys + end; + end + def test_moving_strings_up_size_pools assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV) begin; -- cgit v1.2.3