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

ruby-changes:60366

From: Takashi <ko1@a...>
Date: Wed, 11 Mar 2020 17:01:13 +0900 (JST)
Subject: [ruby-changes:60366] da4b97a0e3 (master): Pin and inline cme in JIT-ed method calls

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

From da4b97a0e3914f0dbb9983229b266bb4761a28d3 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Wed, 11 Mar 2020 00:54:18 -0700
Subject: Pin and inline cme in JIT-ed method calls

```
$ benchmark-driver benchmark.yml -v --rbenv 'before --jit;after --jit' --repeat-count=12 --output=all
before --jit: ruby 2.8.0dev (2020-03-11T07:43:12Z master e89ebdcb87) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-03-11T07:54:18Z master 143776a0da) +JIT [x86_64-linux]
Calculating -------------------------------------
                                 before --jit           after --jit
Optcarrot Lan_Master.nes    73.86976729561439     77.20184819316513 fps
                            74.46997176460742     78.43493030231805
                            77.59686308754307     78.55714131655935
                            78.53693921126656     79.08984255596820
                            80.10158944910573     79.17751731838183
                            80.12254974411167     79.60853122429181
                            80.28678655204945     79.74674066871896
                            80.38690681095379     79.90624544440300
                            80.79223498756919     80.57881084206193
                            80.82857188422419     80.70677614429169
                            81.06447745878245     81.03868541295149
                            81.21620802278490     82.16354660940607
```

diff --git a/iseq.c b/iseq.c
index b6d4635..d32a092 100644
--- a/iseq.c
+++ b/iseq.c
@@ -364,8 +364,9 @@ rb_iseq_mark(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L364
             for (unsigned int i=0; i<body->ci_size; i++) {
                 const struct rb_callcache *cc = cc_entries[i];
                 if (cc != NULL) {
-                    // Pin cc against GC.compact as the the address may be written in JIT-ed code.
+                    // Pin `cc` and `cc->cme` against GC.compact as their addresses may be written in JIT-ed code.
                     rb_gc_mark((VALUE)cc);
+                    rb_gc_mark((VALUE)vm_cc_cme(cc));
                 }
             }
         }
diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb
index 9642e46..6935292 100644
--- a/tool/ruby_vm/views/_mjit_compile_send.erb
+++ b/tool/ruby_vm/views/_mjit_compile_send.erb
@@ -39,7 +39,8 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_send.erb#L39
 
 % # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things.
             fprintf(f, "    const struct rb_callcache *cc = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)captured_cc);
-            fprintf(f, "    if (UNLIKELY(!vm_cc_valid_p(cc, CLASS_OF(stack[%d])))) {\n", b->stack_size - 1 - argc);
+            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 - 1 - argc);
             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");
@@ -72,7 +73,7 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_send.erb#L73
 % # JIT: Special CALL_METHOD. Bypass captured_cc->call and inline vm_call_iseq_setup_normal for vm_call_iseq_setup_func FASTPATH.
                 fprintf(f, "        {\n");
                 fprintf(f, "            VALUE v;\n");
-                fprintf(f, "            vm_call_iseq_setup_normal(ec, reg_cfp, &calling, vm_cc_cme(cc), 0, %d, %d);\n",
+                fprintf(f, "            vm_call_iseq_setup_normal(ec, reg_cfp, &calling, cc_cme, 0, %d, %d);\n",
                            param_size, iseq->body->local_table_size); // fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
                 if (iseq->body->catch_except_p) {
                     fprintf(f, "            VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n");
diff --git a/vm_callinfo.h b/vm_callinfo.h
index 0f90d10..30c4f70 100644
--- a/vm_callinfo.h
+++ b/vm_callinfo.h
@@ -316,11 +316,12 @@ vm_cc_markable(const struct rb_callcache *cc) https://github.com/ruby/ruby/blob/trunk/vm_callinfo.h#L316
     return FL_TEST_RAW(cc, VM_CALLCACHE_UNMARKABLE) == 0;
 }
 
+// For MJIT. cc_cme is supposed to have inlined `vm_cc_cme(cc)`.
 static inline bool
-vm_cc_valid_p(const struct rb_callcache *cc, VALUE klass)
+vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *cc_cme, VALUE klass)
 {
     VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
-    if (cc->klass == klass && !METHOD_ENTRY_INVALIDATED(vm_cc_cme(cc))) {
+    if (cc->klass == klass && !METHOD_ENTRY_INVALIDATED(cc_cme)) {
         return 1;
     }
     else {
-- 
cgit v0.10.2


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

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