mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
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
This commit is contained in:
parent
c05e10605e
commit
f2833e358c
Notes:
git
2025-12-30 15:59:50 +00:00
@ -5329,7 +5329,13 @@ rb_gc_impl_handle_weak_references_alive_p(void *objspace_ptr, VALUE obj)
|
||||
{
|
||||
rb_objspace_t *objspace = objspace_ptr;
|
||||
|
||||
return RVALUE_MARKED(objspace, obj);
|
||||
bool marked = RVALUE_MARKED(objspace, obj);
|
||||
|
||||
if (marked) {
|
||||
rgengc_check_relation(objspace, obj);
|
||||
}
|
||||
|
||||
return marked;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5337,7 +5343,9 @@ gc_update_weak_references(rb_objspace_t *objspace)
|
||||
{
|
||||
VALUE *obj_ptr;
|
||||
rb_darray_foreach(objspace->weak_references, i, obj_ptr) {
|
||||
gc_mark_set_parent(objspace, *obj_ptr);
|
||||
rb_gc_handle_weak_references(*obj_ptr);
|
||||
gc_mark_set_parent_invalid(objspace);
|
||||
}
|
||||
|
||||
size_t capa = rb_darray_capa(objspace->weak_references);
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user