From 53edb27baccaffe919c2885a9c86312cc51ea9fb Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Mon, 14 Dec 2020 14:51:39 +0900 Subject: use method cache on Object#respond_to? rb_method_boundp (method_boundp) searches method_entry, but this search did not use pCMC, so change to use it. --- vm_method.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'vm_method.c') diff --git a/vm_method.c b/vm_method.c index 122c43556f..87827db5aa 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1182,20 +1182,33 @@ rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr) return method_entry_resolve_refinement(klass, id, TRUE, defined_class_ptr); } -MJIT_FUNC_EXPORTED const rb_callable_method_entry_t * -rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr) +static const rb_callable_method_entry_t * +callable_method_entry_refeinements(VALUE klass, ID id, VALUE *defined_class_ptr, bool with_refinements) { const rb_callable_method_entry_t *cme = callable_method_entry(klass, id, defined_class_ptr); + if (cme == NULL || cme->def->type != VM_METHOD_TYPE_REFINED) { return cme; } else { VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class; - const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, TRUE, dcp); + const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, with_refinements, dcp); return prepare_callable_method_entry(*dcp, id, me, TRUE); } } +MJIT_FUNC_EXPORTED const rb_callable_method_entry_t * +rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr) +{ + return callable_method_entry_refeinements(klass, id, defined_class_ptr, true); +} + +static const rb_callable_method_entry_t * +callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr) +{ + return callable_method_entry_refeinements(klass, id, defined_class_ptr, false); +} + const rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr) { @@ -1377,21 +1390,23 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi) #define BOUND_PRIVATE 0x01 #define BOUND_RESPONDS 0x02 -int -rb_method_boundp(VALUE klass, ID id, int ex) +static int +method_boundp(VALUE klass, ID id, int ex) { - const rb_method_entry_t *me; + const rb_callable_method_entry_t *cme; + + VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS)); if (ex & BOUND_RESPONDS) { - me = method_entry_resolve_refinement(klass, id, TRUE, NULL); + cme = rb_callable_method_entry_with_refinements(klass, id, NULL); } else { - me = rb_method_entry_without_refinements(klass, id, NULL); + cme = callable_method_entry_without_refinements(klass, id, NULL); } - if (me != NULL) { + if (cme != NULL) { if (ex & ~BOUND_RESPONDS) { - switch (METHOD_ENTRY_VISI(me)) { + switch (METHOD_ENTRY_VISI(cme)) { case METHOD_VISI_PRIVATE: return 0; case METHOD_VISI_PROTECTED: @@ -1401,7 +1416,7 @@ rb_method_boundp(VALUE klass, ID id, int ex) } } - if (me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) { + if (cme->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) { if (ex & BOUND_RESPONDS) return 2; return 0; } @@ -1410,6 +1425,13 @@ rb_method_boundp(VALUE klass, ID id, int ex) return 0; } +// deprecated +int +rb_method_boundp(VALUE klass, ID id, int ex) +{ + return method_boundp(klass, id, ex); +} + static void vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func) { @@ -2384,7 +2406,7 @@ basic_obj_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE obj, ID id, { VALUE ret; - switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) { + switch (method_boundp(klass, id, pub|BOUND_RESPONDS)) { case 2: return FALSE; case 0: -- cgit v1.2.3