ruby-changes:64137
From: Koichi <ko1@a...>
Date: Mon, 14 Dec 2020 15:44:43 +0900 (JST)
Subject: [ruby-changes:64137] 53edb27bac (master): use method cache on Object#respond_to?
https://git.ruby-lang.org/ruby.git/commit/?id=53edb27bac From 53edb27baccaffe919c2885a9c86312cc51ea9fb Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> 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. diff --git a/vm_eval.c b/vm_eval.c index b26c88f..9cf1bfc 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -389,8 +389,8 @@ check_funcall_failed(VALUE v, VALUE e) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L389 struct rescue_funcall_args *args = (void *)v; int ret = args->respond; if (!ret) { - switch (rb_method_boundp(args->defined_class, args->mid, - BOUND_PRIVATE|BOUND_RESPONDS)) { + switch (method_boundp(args->defined_class, args->mid, + BOUND_PRIVATE|BOUND_RESPONDS)) { case 2: ret = TRUE; break; diff --git a/vm_method.c b/vm_method.c index 122c435..87827db 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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1182 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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1390 #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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1416 } } - 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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1425 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, https://github.com/ruby/ruby/blob/trunk/vm_method.c#L2406 { 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 v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/