summaryrefslogtreecommitdiff
path: root/test/ruby/test_gc_compact.rb
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2020-11-25 09:24:50 -0800
committerAaron Patterson <tenderlove@ruby-lang.org>2020-11-25 11:29:14 -0800
commitc32218de1ba094223420a4ea017707f48d0009c5 (patch)
treeacee8f29e3d3fdd53f1c0d386eed8203cc532ff9 /test/ruby/test_gc_compact.rb
parent7aaf6676c416e773b0b3053de2e250a73c2b2e77 (diff)
Disable auto compaction on platforms that can't support it
Both explicit compaction routines (gc_compact and the verify references form) need to clear the heap before executing compaction. Otherwise some objects may not be alive, and we'll need the read barrier. The heap must only contain *live* objects if we want to disable the read barrier during explicit compaction. The previous commit was missing the "clear the heap" phase from the "verify references" explicit compaction function. Fixes [Bug #17306]
Diffstat (limited to 'test/ruby/test_gc_compact.rb')
-rw-r--r--test/ruby/test_gc_compact.rb112
1 files changed, 69 insertions, 43 deletions
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
index 3aad9e6d5f..4a8cff33f4 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -1,56 +1,82 @@
# frozen_string_literal: true
require 'test/unit'
require 'fiddle'
+require 'etc'
class TestGCCompact < Test::Unit::TestCase
- def test_enable_autocompact
- before = GC.auto_compact
- GC.auto_compact = true
- assert GC.auto_compact
- ensure
- GC.auto_compact = before
- end
+ class AutoCompact < Test::Unit::TestCase
+ def setup
+ skip "autocompact not supported on this platform" unless supports_auto_compact?
+ super
+ end
- def test_disable_autocompact
- before = GC.auto_compact
- GC.auto_compact = false
- refute GC.auto_compact
- ensure
- GC.auto_compact = before
- end
+ def test_enable_autocompact
+ before = GC.auto_compact
+ GC.auto_compact = true
+ assert GC.auto_compact
+ ensure
+ GC.auto_compact = before
+ end
- def test_major_compacts
- before = GC.auto_compact
- GC.auto_compact = true
- compact = GC.stat :compact_count
- GC.start
- assert_operator GC.stat(:compact_count), :>, compact
- ensure
- GC.auto_compact = before
- end
+ def test_disable_autocompact
+ before = GC.auto_compact
+ GC.auto_compact = false
+ refute GC.auto_compact
+ ensure
+ GC.auto_compact = before
+ end
- def test_implicit_compaction_does_something
- before = GC.auto_compact
- list = []
- list2 = []
+ def test_major_compacts
+ before = GC.auto_compact
+ GC.auto_compact = true
+ compact = GC.stat :compact_count
+ GC.start
+ assert_operator GC.stat(:compact_count), :>, compact
+ ensure
+ GC.auto_compact = before
+ end
- # Try to make some fragmentation
- 500.times {
- list << Object.new
- Object.new
- Object.new
- }
- count = GC.stat :compact_count
- GC.auto_compact = true
- loop do
- break if count < GC.stat(:compact_count)
- list2 << Object.new
+ def test_implicit_compaction_does_something
+ before = GC.auto_compact
+ list = []
+ list2 = []
+
+ # Try to make some fragmentation
+ 500.times {
+ list << Object.new
+ Object.new
+ Object.new
+ }
+ count = GC.stat :compact_count
+ GC.auto_compact = true
+ loop do
+ break if count < GC.stat(:compact_count)
+ list2 << Object.new
+ end
+ compact_stats = GC.latest_compact_info
+ refute_predicate compact_stats[:considered], :empty?
+ refute_predicate compact_stats[:moved], :empty?
+ ensure
+ GC.auto_compact = before
end
- compact_stats = GC.latest_compact_info
- refute_predicate compact_stats[:considered], :empty?
- refute_predicate compact_stats[:moved], :empty?
- ensure
- GC.auto_compact = before
+
+ private
+
+ def supports_auto_compact?
+ return true unless defined?(Etc::SC_PAGE_SIZE)
+
+ begin
+ return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
+ rescue NotImplementedError
+ rescue ArgumentError
+ end
+
+ true
+ end
+ end
+
+ def os_page_size
+ return true unless defined?(Etc::SC_PAGE_SIZE)
end
def test_gc_compact_stats