Fix memory leak when evacuating generic ivars

The lookup in the table is using the wrong key when converting generic
instance variables to too complex, which means that it never looks up
the entry which leaks memory when the entry is overwritten.
This commit is contained in:
Peter Zhu 2023-11-21 09:19:15 -05:00
parent b4f551686b
commit 7e7e2dde24
2 changed files with 25 additions and 1 deletions

View File

@ -517,6 +517,30 @@ class TestShapes < Test::Unit::TestCase
end;
end
def test_evacuate_generic_ivar_memory_leak
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
o = []
o.instance_variable_set(:@a, 1)
i = 0
o = Object.new
while RubyVM::Shape.shapes_available > 0
o.instance_variable_set(:"@i#{i}", 1)
i += 1
end
ary = 1_000_000.times.map { [] }
begin;
ary.each do |o|
o.instance_variable_set(:@a, 1)
o.instance_variable_set(:@b, 1)
end
ary.clear
ary = nil
GC.start
end;
end
def test_use_all_shapes_module
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;

View File

@ -1379,7 +1379,7 @@ rb_obj_convert_to_too_complex(VALUE obj, st_table *table)
RB_VM_LOCK_ENTER();
{
struct st_table *gen_ivs = generic_ivtbl_no_ractor_check(obj);
st_lookup(gen_ivs, (st_data_t)&obj, (st_data_t *)&old_ivptr);
st_lookup(gen_ivs, (st_data_t)obj, (st_data_t *)&old_ivptr);
struct gen_ivtbl *ivtbl = xmalloc(sizeof(struct gen_ivtbl));
ivtbl->as.complex.table = table;