summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-12-14 14:51:39 +0900
committerKoichi Sasada <ko1@atdot.net>2020-12-14 15:28:09 +0900
commit53edb27baccaffe919c2885a9c86312cc51ea9fb (patch)
treee559108379bd763767e2ffd333a76781fc94c3d5 /vm_method.c
parent0362b4c689e319e233691ee052cd703bf8d2baa1 (diff)
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.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3899
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c46
1 files changed, 34 insertions, 12 deletions
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: