ruby-changes:55278
From: tenderlove <ko1@a...>
Date: Wed, 10 Apr 2019 08:03:45 +0900 (JST)
Subject: [ruby-changes:55278] tenderlove:r67485 (trunk): Pin weakmap references
tenderlove 2019-04-10 08:03:40 +0900 (Wed, 10 Apr 2019) New Revision: 67485 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67485 Log: 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. Modified files: trunk/gc.c trunk/test/test_weakref.rb Index: test/test_weakref.rb =================================================================== --- test/test_weakref.rb (revision 67484) +++ test/test_weakref.rb (revision 67485) @@ -40,14 +40,14 @@ class TestWeakRef < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/test_weakref.rb#L40 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 Index: gc.c =================================================================== --- gc.c (revision 67484) +++ gc.c (revision 67485) @@ -9767,10 +9767,24 @@ wmap_mark_map(st_data_t key, st_data_t v https://github.com/ruby/ruby/blob/trunk/gc.c#L9767 } #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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/