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

ruby-changes:61286

From: Takashi <ko1@a...>
Date: Mon, 18 May 2020 15:38:48 +0900 (JST)
Subject: [ruby-changes:61286] b16a2aa938 (master): Reduce code size for rb_class_of

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

From b16a2aa938d091c387a7437d94dac7f7bb829ba2 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Sun, 17 May 2020 22:47:20 -0700
Subject: Reduce code size for rb_class_of

by inlining only hot path.

=== mame/optcarrot ===

$ benchmark-driver -v --rbenv 'before --jit;after --jit' benchmark.yml --repeat-count=24 --output=all
before --jit: ruby 2.8.0dev (2020-05-18T05:21:31Z master 0e5a58b6bf) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-05-18T06:12:04Z master 0e3d71a8d1) +JIT [x86_64-linux]
last_commit=Reduce code size for rb_class_of
Calculating -------------------------------------
                                 before --jit           after --jit
Optcarrot Lan_Master.nes    71.62880463568773     70.95730063273503 fps
                            71.73973684273152     71.98447841929851
                            75.03923801841310     75.54262519509039
                            75.16300287174957     77.64029272984344
                            75.16834828625935     78.67861469580785
                            75.17670723726911     78.81879353707393
                            75.67637908020630     79.18188850392886
                            76.19843953215396     79.66484891814478
                            77.28166716118808     79.80278072861037
                            77.38509903325165     80.05859292679696
                            78.12693418455953     80.34624804808006
                            78.73654441746730     80.66326571254345
                            79.25387513454415     80.69760605740196
                            79.44137881689524     81.32053489212245
                            79.50497657368358     81.50250852553751
                            79.62401328582868     82.27544931834611
                            79.79178811723664     82.67455264522741
                            81.20275352937418     82.93857260493297
                            81.57027048640776     83.15019118788184
                            81.63373188649095     83.20728816044721
                            81.93420437766426     83.25027576772972
                            82.05716136357167     83.27072145898173
                            82.21070805525066     83.36008265822194
                            82.56924063784872     83.36112268888493

=== benchmark-driver/sinatra ===

[rps]
before: 13143.49 rps
after: 13505.70 rps

[inlined rb_class_of size]
before: 11.5K
after: 3.8K

(calculated by `dwarftree --die inlined_subroutine --flat --merge --show-size`)

diff --git a/mjit_compile.c b/mjit_compile.c
index fe75b45..589ac50 100644
--- a/mjit_compile.c
+++ b/mjit_compile.c
@@ -114,6 +114,23 @@ fastpath_applied_iseq_p(const CALL_INFO ci, const CALL_CACHE cc, const rb_iseq_t https://github.com/ruby/ruby/blob/trunk/mjit_compile.c#L114
         && vm_call_iseq_optimizable_p(ci, cc); // CC_SET_FASTPATH condition
 }
 
+// Return true if an object of the klass may be a special const. See: rb_class_of
+static bool
+maybe_special_const_class_p(const VALUE klass)
+{
+    if (klass == rb_cFalseClass
+        || klass == rb_cNilClass
+        || klass == rb_cTrueClass
+        || klass == rb_cInteger
+        || klass == rb_cSymbol
+        || klass == rb_cFloat) {
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
 static int
 compile_case_dispatch_each(VALUE key, VALUE value, VALUE arg)
 {
diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb
index d1f4692..8c1c1c0 100644
--- a/tool/ruby_vm/views/_mjit_compile_send.erb
+++ b/tool/ruby_vm/views/_mjit_compile_send.erb
@@ -34,9 +34,11 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_send.erb#L34
         fprintf(f, "{\n");
 
 % # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things.
+        bool opt_class_of = !maybe_special_const_class_p(captured_cc->klass); // If true, use RBASIC_CLASS instead of CLASS_OF to reduce code size
         fprintf(f, "    const struct rb_callcache *cc = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)captured_cc);
         fprintf(f, "    const rb_callable_method_entry_t *cc_cme = (const rb_callable_method_entry_t *)0x%"PRIxVALUE";\n", (VALUE)vm_cc_cme(captured_cc));
-        fprintf(f, "    if (UNLIKELY(!vm_cc_valid_p(cc, cc_cme, CLASS_OF(stack[%d])))) {\n", b->stack_size + sp_inc - 1);
+        fprintf(f, "    const VALUE recv = stack[%d];\n", b->stack_size + sp_inc - 1);
+        fprintf(f, "    if (UNLIKELY(%s || !vm_cc_valid_p(cc, cc_cme, %s(recv)))) {\n", opt_class_of ? "RB_SPECIAL_CONST_P(recv)" : "false", opt_class_of ? "RBASIC_CLASS" : "CLASS_OF");
         fprintf(f, "        reg_cfp->pc = original_body_iseq + %d;\n", pos);
         fprintf(f, "        reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size);
         fprintf(f, "        goto send_cancel;\n");
-- 
cgit v0.10.2


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

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