1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

merge revision(s) 7ff1bf317887c0d7b21e91ad548d07b9f05c540c,e89d80702bd98a8276243a7fcaa2a158b3bfb659: [Backport #18516]

An alias can suppress method redefinition warning

    ---
     test/ruby/test_alias.rb | 11 +++++++++++
     1 file changed, 11 insertions(+)

    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.
    ---
     method.h                |  1 +
     test/ruby/test_alias.rb | 18 ++++++++++++++++++
     vm_method.c             |  9 ++++++++-
     3 files changed, 27 insertions(+), 1 deletion(-)
This commit is contained in:
NAKAMURA Usaku 2022-03-19 22:34:37 +09:00
parent 2d886af0a5
commit 5da2a3e316
4 changed files with 39 additions and 2 deletions

View file

@ -164,6 +164,7 @@ struct rb_method_definition_struct {
BITFIELD(rb_method_type_t, type, VM_METHOD_TYPE_MINIMUM_BITS);
int alias_count : 28;
int complemented_count : 28;
unsigned int no_redef_warning: 1;
union {
rb_method_iseq_t iseq;

View file

@ -227,4 +227,33 @@ class TestAlias < Test::Unit::TestCase
assert_equal(:foo, k.instance_method(:bar).original_name)
assert_equal(:foo, name)
end
def test_alias_suppressing_redefinition
assert_in_out_err(%w[-w], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
class A
def foo; end
alias foo foo
def foo; end
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

@ -2,7 +2,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 6
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 214
#define RUBY_PATCHLEVEL 215
#define RUBY_RELEASE_YEAR 2022
#define RUBY_RELEASE_MONTH 3

View file

@ -584,6 +584,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 &&
@ -698,7 +699,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;
}