[前][次][番号順一覧][スレッド一覧]

ruby-changes:71031

From: Nobuyoshi <ko1@a...>
Date: Thu, 27 Jan 2022 15:46:37 +0900 (JST)
Subject: [ruby-changes:71031] e89d80702b (master): Fix memory leak at the same named alias [Bug #18516]

https://git.ruby-lang.org/ruby.git/commit/?id=e89d80702b

From e89d80702bd98a8276243a7fcaa2a158b3bfb659 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 27 Jan 2022 00:28:39 +0900
Subject: 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(-)

diff --git a/method.h b/method.h
index 815fd9da470..2f4504bfec9 100644
--- a/method.h
+++ b/method.h
@@ -181,6 +181,7 @@ struct rb_method_definition_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L181
     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;
diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb
index c6fad25cc24..99f2223b49d 100644
--- a/test/ruby/test_alias.rb
+++ b/test/ruby/test_alias.rb
@@ -264,4 +264,22 @@ class TestAlias < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_alias.rb#L264
       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/vm_method.c b/vm_method.c
index 6867b5cf8c5..b926654bdcc 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -856,6 +856,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#L856
 	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, https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1087
 		 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/

[前][次][番号順一覧][スレッド一覧]