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

ruby-changes:68745

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:13:15 +0900 (JST)
Subject: [ruby-changes:68745] 0f53c216d2 (master): Pop stack operands in opt_aref

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

From 0f53c216d2e46049d30eb82b66c9ab4c946911ed Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 4 Feb 2021 16:37:14 -0500
Subject: Pop stack operands in opt_aref

---
 ujit_codegen.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 50bc4f77b1..30d38b5d77 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -636,6 +636,78 @@ gen_opt_ge(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L636
     return gen_fixnum_cmp(jit, ctx, cmovge);
 }
 
+static bool
+gen_opt_aref(jitstate_t* jit, ctx_t* ctx)
+{
+    struct rb_call_data * cd = (struct rb_call_data *)jit_get_arg(jit, 0);
+    int32_t argc = (int32_t)vm_ci_argc(cd->ci);
+
+    // Only JIT one arg calls like `ary[6]`
+    if (argc != 1) {
+        return false;
+    }
+
+    const rb_callable_method_entry_t *cme = vm_cc_cme(cd->cc);
+
+    // Bail if the inline cache has been filled.  Currently, certain types
+    // (including arrays) don't use the inline cache, so if the inline cache
+    // has an entry, then this must be used by some other type.
+    if (cme) {
+        return false;
+    }
+
+    // Create a size-exit to fall back to the interpreter
+    uint8_t* side_exit = ujit_side_exit(jit, ctx);
+
+    x86opnd_t recv = ctx_stack_pop(ctx, 1);
+    mov(cb, REG0, recv);
+
+    // if (SPECIAL_CONST_P(recv)) {
+    // Bail if it's not a heap object
+    test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK));
+    jnz_ptr(cb, side_exit);
+    cmp(cb, REG0, imm_opnd(Qfalse));
+    je_ptr(cb, side_exit);
+    cmp(cb, REG0, imm_opnd(Qnil));
+    je_ptr(cb, side_exit);
+
+    // Bail if recv is *not* an array
+    x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass));
+    mov(cb, REG0, klass_opnd);
+    mov(cb, REG1, const_ptr_opnd((void *)rb_cArray));
+    cmp(cb, REG0, REG1);
+    jne_ptr(cb, side_exit);
+
+    // Bail if arg0 is *not* an FIXNUM
+    x86opnd_t operand = ctx_stack_pop(ctx, 1);
+    mov(cb, REG1, operand);
+    test(cb, REG1, imm_opnd(RUBY_FIXNUM_FLAG));
+    jz_ptr(cb, side_exit);
+
+    // Save MicroJIT registers
+    push(cb, REG_CFP);
+    push(cb, REG_EC);
+    push(cb, REG_SP);
+    // Maintain 16-byte RSP alignment
+    sub(cb, RSP, imm_opnd(8));
+
+    mov(cb, RDI, recv);
+    sar(cb, REG1, imm_opnd(1)); // Convert fixnum to int
+    mov(cb, RSI, REG1);
+    call_ptr(cb, REG0, (void *)rb_ary_entry_internal);
+
+    // Restore registers
+    add(cb, RSP, imm_opnd(8));
+    pop(cb, REG_SP);
+    pop(cb, REG_EC);
+    pop(cb, REG_CFP);
+
+    x86opnd_t stack_ret = ctx_stack_push(ctx, T_NONE);
+    mov(cb, stack_ret, RAX);
+
+    return true;
+}
+
 static bool
 gen_opt_and(jitstate_t* jit, ctx_t* ctx)
 {
@@ -1192,7 +1264,7 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1264
     lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * (3 + num_locals)));
 
     // Initialize local variables to Qnil
-    for (int i=0; i < num_locals; i++) {
+    for (int i = 0; i < num_locals; i++) {
         mov(cb, mem_opnd(64, REG0, sizeof(VALUE) * (i - num_locals - 3)), imm_opnd(Qnil));
     }
 
@@ -1390,6 +1462,7 @@ ujit_init_codegen(void) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1462
     ujit_reg_op(BIN(opt_lt), gen_opt_lt, false);
     ujit_reg_op(BIN(opt_le), gen_opt_le, false);
     ujit_reg_op(BIN(opt_ge), gen_opt_ge, false);
+    ujit_reg_op(BIN(opt_aref), gen_opt_aref, false);
     ujit_reg_op(BIN(opt_and), gen_opt_and, false);
     ujit_reg_op(BIN(opt_minus), gen_opt_minus, false);
     ujit_reg_op(BIN(opt_plus), gen_opt_plus, false);
-- 
cgit v1.2.1


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

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