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

ruby-changes:70531

From: nagachika <ko1@a...>
Date: Fri, 24 Dec 2021 18:05:02 +0900 (JST)
Subject: [ruby-changes:70531] 545d682071 (ruby_3_0): merge revision(s) fb4cf204a662a8cd9dafef6f31f2bd0db9129abe,fa0279d947c3962c3f8c32852278d3ebb964cb19: [Backport #17725]

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

From 545d6820715a48a17d6182128c0db4198dfa76c1 Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Fri, 24 Dec 2021 17:47:44 +0900
Subject: merge revision(s)
 fb4cf204a662a8cd9dafef6f31f2bd0db9129abe,fa0279d947c3962c3f8c32852278d3ebb964cb19:
 [Backport #17725]

	use me->def instead of me for opt_table

	`vm_opt_method_table` is me=>bop table to manage the optimized
	methods (by specialized instruction). However, `me` can be invalidated
	to invalidate the method cache entry.
	[Bug #17725]

	To solve the issue, use `me-def` instead of `me` which simply copied
	at invalidation timing.

	A test by @jeremyevans https://github.com/ruby/ruby/pull/4376
	---
	 test/ruby/test_method.rb | 15 +++++++++++++++
	 vm.c                     | 11 +++++------
	 2 files changed, 20 insertions(+), 6 deletions(-)

	should not share same `def` for specialized method

	Because the key of redefine table is `def`, `def` should be
	unique for each optimized method (`alias` is not allowed).
	---
	 array.c | 2 +-
	 1 file changed, 1 insertion(+), 1 deletion(-)
---
 array.c                  |  2 +-
 test/ruby/test_method.rb | 15 +++++++++++++++
 version.h                |  2 +-
 vm.c                     | 11 +++++------
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/array.c b/array.c
index 69937968545..b48a6431e7c 100644
--- a/array.c
+++ b/array.c
@@ -8122,7 +8122,7 @@ Init_Array(void) https://github.com/ruby/ruby/blob/trunk/array.c#L8122
     rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
     rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
     rb_define_method(rb_cArray, "length", rb_ary_length, 0);
-    rb_define_alias(rb_cArray,  "size", "length");
+    rb_define_method(rb_cArray, "size", rb_ary_length, 0);
     rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
     rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
     rb_define_method(rb_cArray, "index", rb_ary_index, -1);
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 240821c9e26..0bd5dc63ddd 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -1303,6 +1303,21 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L1303
     end;
   end
 
+  def test_override_optimized_method_on_class_using_prepend
+    assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
+      # Bug #17725 [ruby-core:102884]
+      $VERBOSE = nil
+      String.prepend(Module.new)
+      class String
+        def + other
+          'blah blah'
+        end
+      end
+
+      assert_equal('blah blah', 'a' + 'b')
+    end;
+  end
+
   def test_eqq
     assert_operator(0.method(:<), :===, 5)
     assert_not_operator(0.method(:<), :===, -5)
diff --git a/version.h b/version.h
index bc580942d0e..3223f4b72f9 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 163
+#define RUBY_PATCHLEVEL 164
 
 #define RUBY_RELEASE_YEAR 2021
 #define RUBY_RELEASE_MONTH 12
diff --git a/vm.c b/vm.c
index c807c8afb24..2503ca9a9f3 100644
--- a/vm.c
+++ b/vm.c
@@ -1796,7 +1796,7 @@ rb_iter_break_value(VALUE val) https://github.com/ruby/ruby/blob/trunk/vm.c#L1796
 
 /* optimization: redefine management */
 
-static st_table *vm_opt_method_table = 0;
+static st_table *vm_opt_method_def_table = 0;
 static st_table *vm_opt_mid_table = 0;
 
 static int
@@ -1850,9 +1850,8 @@ rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass) https://github.com/ruby/ruby/blob/trunk/vm.c#L1850
        klass = RBASIC_CLASS(klass);
     }
     if (vm_redefinition_check_method_type(me->def)) {
-	if (st_lookup(vm_opt_method_table, (st_data_t)me, &bop)) {
-	    int flag = vm_redefinition_check_flag(klass);
-
+        if (st_lookup(vm_opt_method_def_table, (st_data_t)me->def, &bop)) {
+            int flag = vm_redefinition_check_flag(klass);
 	    ruby_vm_redefined_flag[bop] |= flag;
 	}
     }
@@ -1883,7 +1882,7 @@ add_opt_method(VALUE klass, ID mid, VALUE bop) https://github.com/ruby/ruby/blob/trunk/vm.c#L1882
     const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
 
     if (me && vm_redefinition_check_method_type(me->def)) {
-	st_insert(vm_opt_method_table, (st_data_t)me, (st_data_t)bop);
+	st_insert(vm_opt_method_def_table, (st_data_t)me->def, (st_data_t)bop);
 	st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
     }
     else {
@@ -1897,7 +1896,7 @@ vm_init_redefined_flag(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L1896
     ID mid;
     VALUE bop;
 
-    vm_opt_method_table = st_init_numtable();
+    vm_opt_method_def_table = st_init_numtable();
     vm_opt_mid_table = st_init_numtable();
 
 #define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0)
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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