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

ruby-changes:64230

From: Koichi <ko1@a...>
Date: Thu, 17 Dec 2020 16:54:01 +0900 (JST)
Subject: [ruby-changes:64230] 9213771817 (master): encourage inlining for vm_sendish()

https://git.ruby-lang.org/ruby.git/commit/?id=9213771817

From 92137718170118030a1f56303764d08201bf5c33 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Thu, 17 Dec 2020 15:46:36 +0900
Subject: encourage inlining for vm_sendish()

Some tunings.
* add `inline` for vm_sendish()
* pass enum instead of func ptr to vm_sendish()
* reorder initial order of `calling` struct.
* add ALWAYS_INLINE for vm_search_method_fastpath()
* call vm_search_method_fastpath() from vm_sendish()

diff --git a/insns.def b/insns.def
index c62e2f7..5bfcf99 100644
--- a/insns.def
+++ b/insns.def
@@ -767,7 +767,7 @@ send https://github.com/ruby/ruby/blob/trunk/insns.def#L767
 // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
 {
     VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false);
-    val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_method_wrap);
+    val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
 
     if (val == Qundef) {
         RESTORE_REGS();
@@ -786,7 +786,7 @@ opt_send_without_block https://github.com/ruby/ruby/blob/trunk/insns.def#L786
 // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
 {
     VALUE bh = VM_BLOCK_HANDLER_NONE;
-    val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_method_wrap);
+    val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method);
 
     if (val == Qundef) {
         RESTORE_REGS();
@@ -873,7 +873,7 @@ invokesuper https://github.com/ruby/ruby/blob/trunk/insns.def#L873
 // attr rb_snum_t comptime_sp_inc = sp_inc_of_sendish(ci);
 {
     VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true);
-    val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_super_method);
+    val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super);
 
     if (val == Qundef) {
         RESTORE_REGS();
@@ -892,7 +892,7 @@ invokeblock https://github.com/ruby/ruby/blob/trunk/insns.def#L892
 // attr rb_snum_t comptime_sp_inc = sp_inc_of_invokeblock(ci);
 {
     VALUE bh = VM_BLOCK_HANDLER_NONE;
-    val = vm_sendish(ec, GET_CFP(), cd, bh, vm_search_invokeblock);
+    val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock);
 
     if (val == Qundef) {
         RESTORE_REGS();
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 57f85b9..20e2672 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1795,7 +1795,9 @@ vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1795
     return cc;
 }
 
-static const struct rb_callcache *
+ALWAYS_INLINE(static const struct rb_callcache *vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass));
+
+static inline const struct rb_callcache *
 vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
 {
     const struct rb_callcache *cc = cd->cc;
@@ -4409,14 +4411,6 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L4411
     }
 }
 
-static const struct rb_callcache *
-vm_search_method_wrap(const struct rb_control_frame_struct *reg_cfp,
-                      struct rb_call_data *cd,
-                      VALUE recv)
-{
-    return vm_search_method((VALUE)reg_cfp->iseq, cd, recv);
-}
-
 static VALUE
 vm_invokeblock_i(struct rb_execution_context_struct *ec,
                  struct rb_control_frame_struct *reg_cfp,
@@ -4433,47 +4427,47 @@ vm_invokeblock_i(struct rb_execution_context_struct *ec, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L4427
     }
 }
 
-static const struct rb_callcache *
-vm_search_invokeblock(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
-{
-    static const struct rb_callcache cc = {
-        .flags = T_IMEMO | (imemo_callcache << FL_USHIFT) | VM_CALLCACHE_UNMARKABLE,
-        .klass = 0,
-        .cme_  = 0,
-        .call_ = vm_invokeblock_i,
-        .aux_  = {0},
-    };
-
-    return &cc;
-}
+enum method_explorer_type {
+    mexp_search_method,
+    mexp_search_invokeblock,
+    mexp_search_super,
+};
 
-static VALUE
+static inline VALUE
 vm_sendish(
     struct rb_execution_context_struct *ec,
     struct rb_control_frame_struct *reg_cfp,
     struct rb_call_data *cd,
     VALUE block_handler,
-    const struct rb_callcache *(*method_explorer)(
-        const struct rb_control_frame_struct *cfp,
-        struct rb_call_data *cd,
-        VALUE recv))
+    enum method_explorer_type method_explorer)
 {
     VALUE val;
-    int argc = vm_ci_argc(cd->ci);
+    const struct rb_callinfo *ci = cd->ci;
+    const struct rb_callcache *cc;
+    int argc = vm_ci_argc(ci);
     VALUE recv = TOPN(argc);
-    const struct rb_callcache *cc = method_explorer(GET_CFP(), cd, recv);
-    const struct rb_callinfo *ci = cd->ci; // TODO: vm_search_super_method can update ci!!
-
     struct rb_calling_info calling = {
-        .ci = cd->ci,
-        .cc = cc,
         .block_handler = block_handler,
         .kw_splat = IS_ARGS_KW_SPLAT(ci) > 0,
         .recv = recv,
         .argc = argc,
+        .ci = ci,
     };
 
-    val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
+    switch (method_explorer) {
+      case mexp_search_method:
+        calling.cc = cc = vm_search_method_fastpath((VALUE)reg_cfp->iseq, cd, CLASS_OF(recv));
+        val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
+        break;
+      case mexp_search_super:
+        calling.cc = cc = vm_search_super_method(reg_cfp, cd, recv);
+        calling.ci = cd->ci;  // TODO: does it safe?
+        val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
+        break;
+      case mexp_search_invokeblock:
+        val = vm_invokeblock_i(ec, GET_CFP(), &calling);
+        break;
+    }
 
     if (val != Qundef) {
         return val;             /* CFUNC normal return */
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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