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

ruby-changes:68807

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:13:38 +0900 (JST)
Subject: [ruby-changes:68807] 8a9ee00a31 (master): uJIT: add guards for protected opt_send_without_block calls

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

From 8a9ee00a318d25145b3262277864c5599271bb6a Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Wed, 3 Mar 2021 16:29:54 -0500
Subject: uJIT: add guards for protected opt_send_without_block calls

These account for about 12% of the time when we were bailing from calls
in railsbench. `ratio_in_ujit` went up 0.1% with this change.
---
 ujit_codegen.c | 35 ++++++++++++++++++++++++++++-------
 ujit_iface.h   |  2 +-
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 8249c1b1d5..4b28fa1dbd 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -1120,7 +1120,23 @@ gen_jump(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1120
     return UJIT_END_BLOCK;
 }
 
-static codegen_status_t
+static void
+jit_protected_guard(jitstate_t *jit, codeblock_t *cb, const rb_callable_method_entry_t *cme, uint8_t *side_exit)
+{
+    // Callee is protected. Generate ancestry guard.
+    // See vm_call_method().
+    ujit_save_regs(cb);
+    mov(cb, C_ARG_REGS[0], member_opnd(REG_CFP, rb_control_frame_t, self));
+    jit_mov_gc_ptr(jit, cb, C_ARG_REGS[1], cme->defined_class);
+    // Note: PC isn't written to current control frame as rb_is_kind_of() shouldn't raise.
+    // VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass);
+    call_ptr(cb, REG0, (void *)&rb_obj_is_kind_of);
+    ujit_load_regs(cb);
+    cmp(cb, RAX, imm_opnd(0));
+    jz_ptr(cb, COUNTED_EXIT(side_exit, oswb_se_protected_check_failed));
+}
+
+static bool
 gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_callable_method_entry_t *cme, int32_t argc)
 {
     const rb_method_cfunc_t *cfunc = UNALIGNED_MEMBER_PTR(cme->def, body.cfunc);
@@ -1190,6 +1206,11 @@ gen_oswb_cfunc(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_c https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1206
     mov(cb, REG0, const_ptr_opnd(jit->pc + insn_len(BIN(opt_send_without_block))));
     mov(cb, mem_opnd(64, REG_CFP, offsetof(rb_control_frame_t, pc)), REG0);
 
+    if (METHOD_ENTRY_VISI(cme) == METHOD_VISI_PROTECTED) {
+        // Generate ancestry guard for protected callee.
+        jit_protected_guard(jit, cb, cme, side_exit);
+    }
+
     // If this function needs a Ruby stack frame
     if (cfunc_needs_frame(cfunc))
     {
@@ -1416,6 +1437,12 @@ gen_oswb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb_ca https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1437
     cmp(cb, klass_opnd, REG1);
     jne_ptr(cb, COUNTED_EXIT(side_exit, oswb_se_cc_klass_differ));
 
+
+    if (METHOD_ENTRY_VISI(cme) == METHOD_VISI_PROTECTED) {
+        // Generate ancestry guard for protected callee.
+        jit_protected_guard(jit, cb, cme, side_exit);
+    }
+
     // Store the updated SP on the current frame (pop arguments and receiver)
     lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * -(argc + 1)));
     mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0);
@@ -1563,12 +1590,6 @@ gen_opt_send_without_block(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1590
         return false;
     }
 
-    // We don't generate code to check protected method calls
-    if (METHOD_ENTRY_VISI(cme) == METHOD_VISI_PROTECTED) {
-        GEN_COUNTER_INC(cb, oswb_protected);
-        return false;
-    }
-
     switch (cme->def->type) {
     case VM_METHOD_TYPE_ISEQ:
         return gen_oswb_iseq(jit, ctx, cd, cme, argc);
diff --git a/ujit_iface.h b/ujit_iface.h
index 2542e21590..e0addb3574 100644
--- a/ujit_iface.h
+++ b/ujit_iface.h
@@ -33,7 +33,6 @@ UJIT_DECLARE_COUNTERS( https://github.com/ruby/ruby/blob/trunk/ujit_iface.h#L33
     oswb_kw_splat,
     oswb_ic_empty,
     oswb_invalid_cme,
-    oswb_protected,
     oswb_ivar_set_method,
     oswb_ivar_get_method,
     oswb_zsuper_method,
@@ -54,6 +53,7 @@ UJIT_DECLARE_COUNTERS( https://github.com/ruby/ruby/blob/trunk/ujit_iface.h#L53
     oswb_se_receiver_not_heap,
     oswb_se_cf_overflow,
     oswb_se_cc_klass_differ,
+    oswb_se_protected_check_failed,
 
     // Member with known name for iterating over counters
     last_member
-- 
cgit v1.2.1


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

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