diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2025-12-30 09:46:42 -0500 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2025-12-30 10:59:21 -0500 |
| commit | f2833e358cf58c3e69038cab80e87e40b7694541 (patch) | |
| tree | 6289c447cd42a116494ddf66d3c06a44c51417e0 /test | |
| parent | c05e10605e46106397fb4af4ea0f322c4d6d68ea (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.rb | 23 |
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 |
