diff options
Diffstat (limited to 'test/ruby/test_gc_compact.rb')
| -rw-r--r-- | test/ruby/test_gc_compact.rb | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 26d7c71687..cb5e9d6ccb 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -8,8 +8,8 @@ end class TestGCCompact < Test::Unit::TestCase module CompactionSupportInspector - def supports_auto_compact? - GC::OPTS.include?("GC_COMPACTION_SUPPORTED") + def supports_compact? + GC.respond_to?(:compact) end end @@ -17,7 +17,7 @@ class TestGCCompact < Test::Unit::TestCase include CompactionSupportInspector def setup - omit "autocompact not supported on this platform" unless supports_auto_compact? + omit "GC compaction not supported on this platform" unless supports_compact? super end end @@ -30,7 +30,7 @@ class TestGCCompact < Test::Unit::TestCase def test_enable_autocompact before = GC.auto_compact GC.auto_compact = true - assert GC.auto_compact + assert_predicate GC, :auto_compact ensure GC.auto_compact = before end @@ -83,7 +83,7 @@ class TestGCCompact < Test::Unit::TestCase include CompactionSupportInspector def assert_not_implemented(method, *args) - omit "autocompact is supported on this platform" if supports_auto_compact? + omit "autocompact is supported on this platform" if supports_compact? assert_raise(NotImplementedError) { GC.send(method, *args) } refute(GC.respond_to?(method), "GC.#{method} should be defined as rb_f_notimplement") @@ -151,12 +151,12 @@ class TestGCCompact < Test::Unit::TestCase def walk_ast ast children = ast.children.grep(RubyVM::AbstractSyntaxTree::Node) children.each do |child| - assert child.type + assert_predicate child, :type walk_ast child end end ast = RubyVM::AbstractSyntaxTree.parse_file #{__FILE__.dump} - assert GC.compact + assert_predicate GC, :compact walk_ast ast end; end @@ -207,7 +207,7 @@ class TestGCCompact < Test::Unit::TestCase end def test_updating_references_for_embed_shared_arrays - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10) begin; @@ -256,7 +256,7 @@ class TestGCCompact < Test::Unit::TestCase end def test_updating_references_for_embed_frozen_shared_arrays - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10) begin; @@ -284,7 +284,7 @@ class TestGCCompact < Test::Unit::TestCase end def test_moving_arrays_down_heaps - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10) begin; @@ -300,13 +300,13 @@ class TestGCCompact < Test::Unit::TestCase }.resume stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) - assert_operator(stats.dig(:moved_down, :T_ARRAY) || 0, :>=, ARY_COUNT - 10) + assert_operator(stats.dig(:moved_down, :T_ARRAY) || 0, :>=, ARY_COUNT - 25) refute_empty($arys.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') }) end; end def test_moving_arrays_up_heaps - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10) begin; @@ -315,7 +315,7 @@ class TestGCCompact < Test::Unit::TestCase GC.verify_compaction_references(expand_heap: true, toward: :empty) Fiber.new { - ary = "hello".chars + ary = "hello world".chars # > 6 elements to exceed pool 0 embed capacity $arys = ARY_COUNT.times.map do x = [] ary.each { |e| x << e } @@ -324,13 +324,13 @@ class TestGCCompact < Test::Unit::TestCase }.resume stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) - assert_operator(stats.dig(:moved_up, :T_ARRAY) || 0, :>=, ARY_COUNT - 10) + assert_operator(stats.dig(:moved_up, :T_ARRAY) || 0, :>=, (0.9995 * ARY_COUNT).to_i) refute_empty($arys.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') }) end; end def test_moving_objects_between_heaps - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 60) begin; @@ -356,13 +356,29 @@ class TestGCCompact < Test::Unit::TestCase stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) - assert_operator(stats.dig(:moved_up, :T_OBJECT) || 0, :>=, OBJ_COUNT - 10) + assert_operator(stats.dig(:moved_up, :T_OBJECT) || 0, :>=, OBJ_COUNT - 25) refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') }) end; end + def test_compact_objects_of_varying_sizes + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 + + assert_ruby_status([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10) + begin; + $objects = [] + 160.times do |n| + obj = Class.new.new + n.times { |i| obj.instance_variable_set("@foo" + i.to_s, 0) } + $objects << obj + end + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + end; + end + def test_moving_strings_up_heaps - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30) begin; @@ -371,19 +387,19 @@ class TestGCCompact < Test::Unit::TestCase GC.verify_compaction_references(expand_heap: true, toward: :empty) Fiber.new { - str = "a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 4 + str = "a" * GC.stat_heap(0, :slot_size) * 4 $ary = STR_COUNT.times.map { +"" << str } }.resume stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) - assert_operator(stats[:moved_up][:T_STRING], :>=, STR_COUNT - 10) + assert_operator(stats[:moved_up][:T_STRING], :>=, STR_COUNT - 25) refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') }) end; end def test_moving_strings_down_heaps - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30) begin; @@ -392,18 +408,18 @@ class TestGCCompact < Test::Unit::TestCase GC.verify_compaction_references(expand_heap: true, toward: :empty) Fiber.new { - $ary = STR_COUNT.times.map { ("a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 4).squeeze! } + $ary = STR_COUNT.times.map { ("a" * GC.stat_heap(0, :slot_size) * 4).squeeze! } }.resume stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) - assert_operator(stats[:moved_down][:T_STRING], :>=, STR_COUNT - 10) + assert_operator(stats[:moved_down][:T_STRING], :>=, STR_COUNT - 25) refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') }) end; end def test_moving_hashes_down_heaps - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 + omit if GC::INTERNAL_CONSTANTS[:HEAP_COUNT] == 1 # AR and ST hashes are in the same size pool on 32 bit omit unless RbConfig::SIZEOF["uint64_t"] <= RbConfig::SIZEOF["void*"] @@ -421,7 +437,7 @@ class TestGCCompact < Test::Unit::TestCase stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) - assert_operator(stats[:moved_down][:T_HASH], :>=, HASH_COUNT - 10) + assert_operator(stats[:moved_down][:T_HASH], :>=, HASH_COUNT - 25) end; end @@ -452,4 +468,21 @@ class TestGCCompact < Test::Unit::TestCase assert_raise(FrozenError) { a.set_a } end; end + + def test_moving_complex_generic_ivar + omit "not compiled with SHAPE_DEBUG" unless defined?(RubyVM::Shape) + + assert_separately([], <<~RUBY) + RubyVM::Shape.exhaust_shapes + + obj = [] + obj.instance_variable_set(:@fixnum, 123) + obj.instance_variable_set(:@str, "hello") + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + assert_equal(123, obj.instance_variable_get(:@fixnum)) + assert_equal("hello", obj.instance_variable_get(:@str)) + RUBY + end end |
