ruby-changes:71389
From: nagachika <ko1@a...>
Date: Sun, 13 Mar 2022 12:12:22 +0900 (JST)
Subject: [ruby-changes:71389] 6175823bab (ruby_3_0): merge revision(s) 7ff1bf317887c0d7b21e91ad548d07b9f05c540c,e89d80702bd98a8276243a7fcaa2a158b3bfb659: [Backport #18516]
https://git.ruby-lang.org/ruby.git/commit/?id=6175823bab From 6175823bab28b5d12f66371d67d006df37751fbc Mon Sep 17 00:00:00 2001 From: nagachika <nagachika@r...> Date: Sun, 13 Mar 2022 11:52:53 +0900 Subject: 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(-) --- method.h | 1 + test/ruby/test_alias.rb | 29 +++++++++++++++++++++++++++++ version.h | 2 +- vm_method.c | 9 ++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/method.h b/method.h index 5b6fe2d800..16a48ccf88 100644 --- a/method.h +++ b/method.h @@ -173,6 +173,7 @@ struct rb_method_definition_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L173 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; diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb index 271d552bf5..99f2223b49 100644 --- a/test/ruby/test_alias.rb +++ b/test/ruby/test_alias.rb @@ -253,4 +253,33 @@ class TestAlias < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_alias.rb#L253 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 diff --git a/version.h b/version.h index 9ada821db3..35084ce3b9 100644 --- a/version.h +++ b/version.h @@ -12,7 +12,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L12 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 4 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 192 +#define RUBY_PATCHLEVEL 193 #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 3 diff --git a/vm_method.c b/vm_method.c index 7fc3f8db97..8ef69b6401 100644 --- a/vm_method.c +++ b/vm_method.c @@ -810,6 +810,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil https://github.com/ruby/ruby/blob/trunk/vm_method.c#L810 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 && @@ -923,7 +924,13 @@ method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, https://github.com/ruby/ruby/blob/trunk/vm_method.c#L924 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; } -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/