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

ruby-changes:68701

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:29 +0900 (JST)
Subject: [ruby-changes:68701] e17053c720 (master): Basic implementation of getivar for MicroJIT

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

From e17053c72090dd8d732742386303f9964b6326ce Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Tue, 10 Nov 2020 15:35:55 -0500
Subject: Basic implementation of getivar for MicroJIT

---
 ujit_compile.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/ujit_compile.c b/ujit_compile.c
index 064e93152d..79a5f05bc4 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -6,6 +6,7 @@ https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L6
 #include "vm_callinfo.h"
 #include "builtin.h"
 #include "internal/compile.h"
+#include "internal/class.h"
 #include "insns_info.inc"
 #include "ujit_compile.h"
 #include "ujit_asm.h"
@@ -623,6 +624,71 @@ gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L624
     return true;
 }
 
+static bool
+gen_getinstancevariable(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+{
+    IVC ic = (IVC)ctx_get_arg(ctx, 1);
+
+    // Check that the inline cache has been set, slot index is known
+    if (!ic->entry)
+    {
+        return false;
+    }
+
+    uint32_t ivar_index = ic->entry->index;
+
+    // Create a size-exit to fall back to the interpreter
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc);
+
+    // Load self from CFP
+    mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, self));
+
+    // Check that the receiver is 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 receiver class is different from compiled time call cache class
+    x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass));
+    mov(cb, REG1, klass_opnd);
+    x86opnd_t serial_opnd = mem_opnd(64, REG1, offsetof(struct RClass, class_serial));
+    cmp(cb, serial_opnd, imm_opnd(ic->entry->class_serial));
+    jne_ptr(cb, side_exit);
+
+    // Bail if the ivars are not on the extended table
+    // See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
+    x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
+    test(cb, flags_opnd, imm_opnd(ROBJECT_EMBED));
+    jnz_ptr(cb, side_exit);
+
+    // Check that this is a Ruby object (not a string, etc)
+    mov(cb, REG1, flags_opnd);
+    and(cb, REG1, imm_opnd(RUBY_T_MASK));
+    cmp(cb, REG1, imm_opnd(T_OBJECT));
+    jne_ptr(cb, side_exit);
+
+    // Get a pointer to the extended table
+    x86opnd_t tbl_opnd = mem_opnd(64, REG0, offsetof(struct RObject, as.heap.ivptr));
+    mov(cb, REG0, tbl_opnd);
+
+    // Read the ivar from the extended table
+    x86opnd_t ivar_opnd = mem_opnd(64, REG0, sizeof(VALUE) * ivar_index);
+    mov(cb, REG0, ivar_opnd);
+
+    // Check that the ivar is not Qundef
+    cmp(cb, REG0, imm_opnd(Qundef));
+    je_ptr(cb, side_exit);
+
+    // Push the ivar on the stack
+    x86opnd_t out_opnd = ctx_stack_push(ctx, 1);
+    mov(cb, out_opnd, REG0);
+
+    return true;
+}
+
 static bool
 gen_opt_minus(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
 {
@@ -1034,6 +1100,7 @@ rb_ujit_init(void) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L1100
     st_insert(gen_fns, (st_data_t)BIN(putself), (st_data_t)&gen_putself);
     st_insert(gen_fns, (st_data_t)BIN(getlocal_WC_0), (st_data_t)&gen_getlocal_wc0);
     st_insert(gen_fns, (st_data_t)BIN(setlocal_WC_0), (st_data_t)&gen_setlocal_wc0);
+    st_insert(gen_fns, (st_data_t)BIN(getinstancevariable), (st_data_t)&gen_getinstancevariable);
     st_insert(gen_fns, (st_data_t)BIN(opt_minus), (st_data_t)&gen_opt_minus);
     st_insert(gen_fns, (st_data_t)BIN(opt_send_without_block), (st_data_t)&gen_opt_send_without_block);
 
-- 
cgit v1.2.1


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

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