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

fix bug on method cache invalidation.

To invalidate cached method entry, existing method entry (ment)
is marked as invalidated and replace with copied ment. However,
complemented method entry (method entries in Module) should not
be set to Module's m_tbl.
[Bug #16669]
This commit is contained in:
Koichi Sasada 2020-03-11 02:45:49 +09:00
parent ec78b8b62a
commit 2943ff9d44
2 changed files with 59 additions and 8 deletions

View file

@ -61,4 +61,50 @@ class TestMethod < Test::Unit::TestCase
assert_equal :E, test[]
EOS
end
def test_module_methods_redefiniton
m0 = Module.new do
def foo
super
end
end
c1 = Class.new do
def foo
:C1
end
end
c2 = Class.new do
def foo
:C2
end
end
d1 = Class.new(c1) do
include m0
end
d2 = Class.new(c2) do
include m0
end
assert_equal :C1, d1.new.foo
m = Module.new do
def foo
super
end
end
d1.class_eval do
include m
end
d2.class_eval do
include m
end
assert_equal :C2, d2.new.foo
end
end

View file

@ -166,15 +166,20 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
// invalidate cme if found to invalidate the inline method cache.
if (METHOD_ENTRY_CACHED(cme)) {
// invalidate cc by invalidating cc->cme
VALUE owner = cme->owner;
rb_callable_method_entry_t *new_cme =
(rb_callable_method_entry_t *)rb_method_entry_clone((const rb_method_entry_t *)cme);
struct rb_id_table *mtbl = RCLASS_M_TBL(RCLASS_ORIGIN(owner));
rb_id_table_insert(mtbl, mid, (VALUE)new_cme);
RB_OBJ_WRITTEN(owner, cme, new_cme);
if (METHOD_ENTRY_COMPLEMENTED(cme)) {
// do nothing
}
else {
// invalidate cc by invalidating cc->cme
VALUE owner = cme->owner;
VM_ASSERT(BUILTIN_TYPE(owner) == T_CLASS);
rb_callable_method_entry_t *new_cme =
(rb_callable_method_entry_t *)rb_method_entry_clone((const rb_method_entry_t *)cme);
struct rb_id_table *mtbl = RCLASS_M_TBL(RCLASS_ORIGIN(owner));
rb_id_table_insert(mtbl, mid, (VALUE)new_cme);
RB_OBJ_WRITTEN(owner, cme, new_cme);
}
vm_me_invalidate_cache((rb_callable_method_entry_t *)cme);
RB_DEBUG_COUNTER_INC(cc_invalidate_tree_cme);
}