summaryrefslogtreecommitdiff
path: root/test/ruby/test_weakmap.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_weakmap.rb')
-rw-r--r--test/ruby/test_weakmap.rb83
1 files changed, 80 insertions, 3 deletions
diff --git a/test/ruby/test_weakmap.rb b/test/ruby/test_weakmap.rb
index c72e7310db..4f5823ecf4 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -78,10 +78,26 @@ class TestWeakMap < Test::Unit::TestCase
@wm[i] = Object.new
@wm.inspect
end
- assert_match(/\A\#<#{@wm.class.name}:[^:]++:(?:\s\d+\s=>\s\#<(?:Object|collected):[^:<>]*+>(?:,|>\z))+/,
+ assert_match(/\A\#<#{@wm.class.name}:0x[\da-f]+(?::(?: \d+ => \#<(?:Object|collected):0x[\da-f]+>,?)+)?>\z/,
@wm.inspect)
end
+ def test_delete
+ k1 = "foo"
+ x1 = Object.new
+ @wm[k1] = x1
+ assert_equal x1, @wm[k1]
+ assert_equal x1, @wm.delete(k1)
+ assert_nil @wm[k1]
+ assert_nil @wm.delete(k1)
+
+ fallback = @wm.delete(k1) do |key|
+ assert_equal k1, key
+ 42
+ end
+ assert_equal 42, fallback
+ end
+
def test_each
m = __callee__[/test_(.*)/, 1]
x1 = Object.new
@@ -177,14 +193,17 @@ class TestWeakMap < Test::Unit::TestCase
end;
end
- def test_compaction_bug_19529
+ def test_compaction
+ omit "compaction is not supported on this platform" unless GC.respond_to?(:compact)
+
+ # [Bug #19529]
obj = Object.new
100.times do |i|
GC.compact
@wm[i] = obj
end
- assert_separately(%w(--disable-gems), <<-'end;')
+ assert_ruby_status([], <<-'end;')
wm = ObjectSpace::WeakMap.new
obj = Object.new
100.times do
@@ -193,6 +212,34 @@ class TestWeakMap < Test::Unit::TestCase
end
GC.compact
end;
+
+ assert_separately(%w(-robjspace), <<-'end;')
+ wm = ObjectSpace::WeakMap.new
+ key = Object.new
+ val = Object.new
+ wm[key] = val
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_equal(val, wm[key])
+ end;
+
+ assert_ruby_status(["-W0"], <<-'end;')
+ wm = ObjectSpace::WeakMap.new
+
+ ary = 10_000.times.map do
+ o = Object.new
+ wm[o] = 1
+ o
+ end
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+ end;
+ end
+
+ def test_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress { ObjectSpace::WeakMap.new }
end
def test_replaced_values_bug_19531
@@ -211,4 +258,34 @@ class TestWeakMap < Test::Unit::TestCase
assert_equal b, @wm[1]
end
+
+ def test_use_after_free_bug_20688
+ assert_normal_exit(<<~RUBY)
+ weakmap = ObjectSpace::WeakMap.new
+ 10_000.times { weakmap[Object.new] = Object.new }
+ RUBY
+ end
+
+ def test_generational_gc
+ EnvUtil.without_gc do
+ wmap = ObjectSpace::WeakMap.new
+
+ (GC::INTERNAL_CONSTANTS[:RVALUE_OLD_AGE] - 1).times { GC.start }
+
+ retain = []
+ 50.times do
+ k = Object.new
+ wmap[k] = true
+ retain << k
+ end
+
+ GC.start # WeakMap promoted, other objects still young
+
+ retain.clear
+
+ GC.start(full_mark: false)
+
+ wmap.keys.each(&:itself) # call method on keys to cause crash
+ end
+ end
end