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

ruby-changes:69034

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:36 +0900 (JST)
Subject: [ruby-changes:69034] 0d64f5e8a8 (master): Check for easy-to-handle cases of block param (#24)

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

From 0d64f5e8a89a0ca5caba5289249ba9ee34fa4303 Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Thu, 6 May 2021 12:24:50 -0400
Subject: Check for easy-to-handle cases of block param (#24)

In some cases, methods taking block parameters don't require extra
paramter setup. They are fairly popular in railsbench.
---
 bootstraptest/test_yjit.rb | 24 ++++++++++++++++++++++++
 yjit_codegen.c             | 21 +++++++++++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 0b469ff5fa..663977f0ca 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -869,3 +869,27 @@ end https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L869
 use([], 0)
 [use([2, 2], 38), use([14, 14, 14], 0)]
 }
+
+# test calling method taking block param
+assert_equal '[Proc, 1, 2, 3, Proc]', %q{
+  def three(a, b, c, &block)
+    [a, b, c, block.class]
+  end
+
+  def zero(&block)
+    block.class
+  end
+
+  def use_three
+    three(1, 2, 3) {}
+  end
+
+  def use_zero
+    zero {}
+  end
+
+  use_three
+  use_zero
+
+  [use_zero] + use_three
+}
diff --git a/yjit_codegen.c b/yjit_codegen.c
index ba332687b4..0b1c7745da 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -1892,7 +1892,22 @@ gen_return_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t s https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1892
     }
 }
 
-bool rb_simple_iseq_p(const rb_iseq_t *iseq);
+// Returns whether the iseq only needs positional (lead) argument setup.
+static bool
+iseq_lead_only_arg_setup_p(const rb_iseq_t *iseq)
+{
+    // When iseq->body->local_iseq == iseq, setup_parameters_complex()
+    // doesn't do anything to setup the block parameter.
+    bool takes_block = iseq->body->param.flags.has_block;
+    return (!takes_block || iseq->body->local_iseq == iseq) &&
+        iseq->body->param.flags.has_opt          == false &&
+        iseq->body->param.flags.has_rest         == false &&
+        iseq->body->param.flags.has_post         == false &&
+        iseq->body->param.flags.has_kw           == false &&
+        iseq->body->param.flags.has_kwrest       == false &&
+        iseq->body->param.flags.accepts_no_kwarg == false;
+}
+
 bool rb_iseq_only_optparam_p(const rb_iseq_t *iseq);
 bool rb_iseq_only_kwparam_p(const rb_iseq_t *iseq);
 
@@ -1910,7 +1925,9 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1925
     // Arity handling and optional parameter setup
     int num_params = iseq->body->param.size;
     uint32_t start_pc_offset = 0;
-    if (rb_simple_iseq_p(iseq)) {
+    if (iseq_lead_only_arg_setup_p(iseq)) {
+        num_params = iseq->body->param.lead_num;
+
         if (num_params != argc) {
             GEN_COUNTER_INC(cb, send_iseq_arity_error);
             return YJIT_CANT_COMPILE;
-- 
cgit v1.2.1


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

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