Skip to content

Commit 7e7e2dd

Browse files
committed
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.
1 parent b4f5516 commit 7e7e2dd

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

test/ruby/test_shapes.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,30 @@ def init
517517
end;
518518
end
519519

520+
def test_evacuate_generic_ivar_memory_leak
521+
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
522+
o = []
523+
o.instance_variable_set(:@a, 1)
524+
525+
i = 0
526+
o = Object.new
527+
while RubyVM::Shape.shapes_available > 0
528+
o.instance_variable_set(:"@i#{i}", 1)
529+
i += 1
530+
end
531+
532+
ary = 1_000_000.times.map { [] }
533+
begin;
534+
ary.each do |o|
535+
o.instance_variable_set(:@a, 1)
536+
o.instance_variable_set(:@b, 1)
537+
end
538+
ary.clear
539+
ary = nil
540+
GC.start
541+
end;
542+
end
543+
520544
def test_use_all_shapes_module
521545
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
522546
begin;

variable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,7 +1379,7 @@ rb_obj_convert_to_too_complex(VALUE obj, st_table *table)
13791379
RB_VM_LOCK_ENTER();
13801380
{
13811381
struct st_table *gen_ivs = generic_ivtbl_no_ractor_check(obj);
1382-
st_lookup(gen_ivs, (st_data_t)&obj, (st_data_t *)&old_ivptr);
1382+
st_lookup(gen_ivs, (st_data_t)obj, (st_data_t *)&old_ivptr);
13831383

13841384
struct gen_ivtbl *ivtbl = xmalloc(sizeof(struct gen_ivtbl));
13851385
ivtbl->as.complex.table = table;

0 commit comments

Comments
 (0)