Fix memory leak at the same named alias [Bug #18516]

When aliasing a method to the same name method, set a separate bit
flag on that method definition, instead of the reference count
increment.  Although this kind of alias has no actual effect at
runtime, is used as the hack to suppress the method re-definition
warning.
This commit is contained in:
Nobuyoshi Nakada 2022-01-27 00:28:39 +09:00
parent 7ff1bf3178
commit e89d80702b
Notes: git 2022-01-27 15:46:41 +09:00
3 changed files with 27 additions and 1 deletions

View File

@ -181,6 +181,7 @@ struct rb_method_definition_struct {
unsigned int iseq_overload: 1;
int alias_count : 27;
int complemented_count : 28;
unsigned int no_redef_warning: 1;
union {
rb_method_iseq_t iseq;

View File

@ -264,4 +264,22 @@ class TestAlias < Test::Unit::TestCase
end
end;
end
def test_alias_memory_leak
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", rss: true)
begin;
class A
500.times do
1000.times do |i|
define_method(:"foo_#{i}") {}
alias :"foo_#{i}" :"foo_#{i}"
remove_method :"foo_#{i}"
end
GC.start
end
end
end;
end
end

View File

@ -856,6 +856,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
if (RTEST(ruby_verbose) &&
type != VM_METHOD_TYPE_UNDEF &&
(old_def->alias_count == 0) &&
(!old_def->no_redef_warning) &&
!make_refined &&
old_def->type != VM_METHOD_TYPE_UNDEF &&
old_def->type != VM_METHOD_TYPE_ZSUPER &&
@ -1086,7 +1087,13 @@ method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me,
rb_method_visibility_t visi, VALUE defined_class)
{
rb_method_entry_t *newme = rb_method_entry_make(klass, mid, defined_class, visi,
me->def->type, method_definition_addref(me->def), 0, NULL);
me->def->type, me->def, 0, NULL);
if (newme == me) {
me->def->no_redef_warning = TRUE;
}
else {
method_definition_addref(me->def);
}
method_added(klass, mid);
return newme;
}