diff options
author | nagachika <[email protected]> | 2021-12-24 17:47:44 +0900 |
---|---|---|
committer | nagachika <[email protected]> | 2021-12-24 17:47:44 +0900 |
commit | 545d6820715a48a17d6182128c0db4198dfa76c1 (patch) | |
tree | 4eb0ca72b4e98923adfcf163a394a4d2997597b2 | |
parent | 1d29740c1b101db4bd8fc2d05f929a9e37471a0f (diff) |
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(-)
-rw-r--r-- | array.c | 2 | ||||
-rw-r--r-- | test/ruby/test_method.rb | 15 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vm.c | 11 |
4 files changed, 22 insertions, 8 deletions
@@ -8122,7 +8122,7 @@ Init_Array(void) 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 240821c9e2..0bd5dc63dd 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -1303,6 +1303,21 @@ class TestMethod < Test::Unit::TestCase 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) @@ -12,7 +12,7 @@ # 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 @@ -1796,7 +1796,7 @@ rb_iter_break_value(VALUE val) /* 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) 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) 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) 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) |