[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]