From e900bba9454f8d1a75ac5aa68a15ac21e04c5340 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Tue, 9 Apr 2019 23:03:40 +0000 Subject: [PATCH] Pin weakmap references Weak map references can't move because the st_table needs their address as a key. But, we also need to remove T_NONE from the map so they aren't reused. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67485 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- gc.c | 14 ++++++++++++++ test/test_weakref.rb | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/gc.c b/gc.c index 75c0f6917e..464f300c78 100644 --- a/gc.c +++ b/gc.c @@ -9767,10 +9767,24 @@ wmap_mark_map(st_data_t key, st_data_t val, st_data_t arg) } #endif +static int +wmap_pin_obj(st_data_t key, st_data_t val, st_data_t arg) +{ + rb_objspace_t *objspace = (rb_objspace_t *)arg; + VALUE obj = (VALUE)val; + if (obj && is_live_object(objspace, obj)) { + gc_pin(objspace, obj); + } else { + return ST_DELETE; + } + return ST_CONTINUE; +} + static void wmap_mark(void *ptr) { struct weakmap *w = ptr; + if (w->wmap2obj) st_foreach(w->wmap2obj, wmap_pin_obj, (st_data_t)&rb_objspace); #if WMAP_DELETE_DEAD_OBJECT_IN_MARK if (w->obj2wmap) st_foreach(w->obj2wmap, wmap_mark_map, (st_data_t)&rb_objspace); #endif diff --git a/test/test_weakref.rb b/test/test_weakref.rb index fcf1fb8b42..f2308dbb5a 100644 --- a/test/test_weakref.rb +++ b/test/test_weakref.rb @@ -40,14 +40,14 @@ class TestWeakRef < Test::Unit::TestCase weakrefs << WeakRef.new(obj) ObjectSpace.garbage_collect end - #assert_nothing_raised(NoMethodError, bug7304) { + assert_nothing_raised(NoMethodError, bug7304) { weakrefs.each do |weak| begin weak.foo - rescue WeakRef::RefError, NoMethodError + rescue WeakRef::RefError end end - #} + } end def test_weakref_finalize