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

Use inline cache for super calls

This commit is contained in:
John Hawthorn 2020-01-18 18:18:00 -08:00 committed by 卜部昌平
parent a91ce05046
commit ed7b46b66b
Notes: git 2020-02-13 00:15:34 +09:00
2 changed files with 30 additions and 1 deletions

View file

@ -583,4 +583,17 @@ class TestSuper < Test::Unit::TestCase
def test_super_with_modified_rest_parameter
assert_equal [13], TestFor_super_with_modified_rest_parameter.new.foo
end
def test_super_with_define_method
superklass = Class.new do
def foo; :foo; end
def bar; :bar; end
end
subklass = Class.new(superklass)
[:foo, :bar].each do |sym|
subklass.define_method(sym){ super() }
end
assert_equal :foo, subklass.new.foo
assert_equal :bar, subklass.new.bar
end
end

View file

@ -3154,9 +3154,25 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c
CC_SET_FASTPATH(cc, vm_call_method_missing, TRUE);
}
else {
/* TODO: use inline cache */
#if OPT_INLINE_METHOD_CACHE
/* Unlike normal method search, we only consider the first class
* serial. Since we're testing defined_class rather than receiver,
* there's only one valid "warm" value. */
if (LIKELY(RB_DEBUG_COUNTER_INC_UNLESS(mc_global_state_miss,
GET_GLOBAL_METHOD_STATE() == cc->method_state) &&
cc->class_serial[0] == RCLASS_SERIAL(klass)) &&
cc->me && ci->mid == cc->me->def->original_id) {
VM_ASSERT(cc->call != NULL);
RB_DEBUG_COUNTER_INC(mc_inline_hit);
return;
}
#endif
CC_SET_ME(cc, rb_callable_method_entry(klass, ci->mid));
CC_SET_FASTPATH(cc, vm_call_super_method, TRUE);
cc->method_state = GET_GLOBAL_METHOD_STATE();
cc->class_serial[0] = RCLASS_SERIAL(klass);
}
}