summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-12-30 09:46:42 -0500
committerPeter Zhu <peter@peterzhu.ca>2025-12-30 10:59:21 -0500
commitf2833e358cf58c3e69038cab80e87e40b7694541 (patch)
tree6289c447cd42a116494ddf66d3c06a44c51417e0 /test
parentc05e10605e46106397fb4af4ea0f322c4d6d68ea (diff)
Fix generational GC for weak references
Fixes issue pointed out in https://bugs.ruby-lang.org/issues/21084#note-7. The following script crashes: wmap = ObjectSpace::WeakMap.new GC.disable # only manual GCs GC.start GC.start retain = [] 50.times do k = Object.new wmap[k] = true retain << k end GC.start # wmap promoted, other objects still young retain.clear GC.start(full_mark: false) wmap.keys.each(&:itself) # call method on keys to cause crash
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_weakmap.rb23
1 files changed, 23 insertions, 0 deletions
diff --git a/test/ruby/test_weakmap.rb b/test/ruby/test_weakmap.rb
index a2904776bc..1050c74b3d 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -265,4 +265,27 @@ class TestWeakMap < Test::Unit::TestCase
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