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

ruby-changes:68650

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:11:42 +0900 (JST)
Subject: [ruby-changes:68650] ff73762bda (master): Refactor ujit, define named register constants, code cleanup

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

From ff73762bda4f2c5c7aa2a04b39282c3755d69841 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Tue, 20 Oct 2020 11:11:47 -0400
Subject: Refactor ujit, define named register constants, code cleanup

---
 ujit_compile.c | 75 ++++++++++++++++++++++++++++------------------------------
 1 file changed, 36 insertions(+), 39 deletions(-)

diff --git a/ujit_compile.c b/ujit_compile.c
index 2ca17d228f..411d2c8ed6 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -53,6 +53,17 @@ static codeblock_t* cb = NULL; https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L53
 static codeblock_t outline_block;
 static codeblock_t* ocb = NULL;
 
+// Register MicroJIT receives the CFP and EC into
+#define REG_CFP RDI
+#define REG_EC RSI
+
+// Register MicroJIT loads the SP into
+#define REG_SP RDX
+
+// Scratch registers used by MicroJIT
+#define REG0 RCX
+#define REG1 R8
+
 // Keep track of mapping from instructions to generated code
 // See comment for rb_encoded_insn_data in iseq.c
 static void
@@ -101,7 +112,7 @@ Get an operand for the adjusted stack pointer address https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L112
 x86opnd_t ctx_sp_opnd(ctx_t* ctx, size_t n)
 {
     int32_t offset = (ctx->stack_diff) * 8;
-    return mem_opnd(64, R9, offset);
+    return mem_opnd(64, REG_SP, offset);
 }
 
 /*
@@ -114,7 +125,7 @@ x86opnd_t ctx_stack_push(ctx_t* ctx, size_t n) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L125
 
     // SP points just above the topmost value
     int32_t offset = (ctx->stack_diff - 1) * 8;
-    return mem_opnd(64, R9, offset);
+    return mem_opnd(64, REG_SP, offset);
 }
 
 /*
@@ -125,7 +136,7 @@ x86opnd_t ctx_stack_pop(ctx_t* ctx, size_t n) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L136
 {
     // SP points just above the topmost value
     int32_t offset = (ctx->stack_diff - 1) * 8;
-    x86opnd_t top = mem_opnd(64, R9, offset);
+    x86opnd_t top = mem_opnd(64, REG_SP, offset);
 
     ctx->stack_diff -= n;
 
@@ -136,7 +147,7 @@ x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L147
 {
     // SP points just above the topmost value
     int32_t offset = (ctx->stack_diff - 1 - idx) * 8;
-    x86opnd_t opnd = mem_opnd(64, R9, offset);
+    x86opnd_t opnd = mem_opnd(64, REG_SP, offset);
 
     return opnd;
 }
@@ -159,15 +170,13 @@ ujit_gen_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L170
     if (ctx->stack_diff != 0)
     {
         x86opnd_t stack_pointer = ctx_sp_opnd(ctx, 1);
-        lea(cb, R9, stack_pointer);
-        mov(cb, mem_opnd(64, RDI, 8), R9);
+        lea(cb, REG_SP, stack_pointer);
+        mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG_SP);
     }
 
     // Directly return the next PC, which is a constant
     mov(cb, RAX, const_ptr_opnd(exit_pc));
-
-    // Write PC back into the CFP
-    mov(cb, mem_opnd(64, RDI, 0), RAX);
+    mov(cb, member_opnd(REG_CFP, rb_control_frame_t, pc), RAX);
 
     // Write the post call bytes
     for (size_t i = 0; i < sizeof(ujit_post_call_with_ec_bytes); ++i)
@@ -201,21 +210,12 @@ ujit_side_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L210
 /*
 Generate a chunk of machine code for one individual bytecode instruction
 Eventually, this will handle multiple instructions in a sequence
-
-MicroJIT code gets a pointer to the cfp as the first argument in RDI
-See rb_ujit_empty_func(rb_control_frame_t *cfp) in iseq.c
-
-Throughout the generated code, we store the current stack pointer in R9
-
-System V ABI reference:
-https://wiki.osdev.org/System_V_ABI#x86-64
 */
 uint8_t *
 ujit_compile_insn(const rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_ujit_idx)
 {
-    if (!cb) {
-        return NULL;
-    }
+    assert (cb != NULL);
+
     VALUE *encoded = iseq->body->iseq_encoded;
 
     // NOTE: if we are ever deployed in production, we
@@ -270,8 +270,8 @@ ujit_compile_insn(const rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* ne https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L270
         {
             ujit_gen_entry(cb);
 
-            // Load the current SP from the CFP into R9
-            mov(cb, R9, mem_opnd(64, RDI, 8));
+            // Load the current SP from the CFP into REG_SP
+            mov(cb, REG_SP, member_opnd(REG_CFP, rb_control_frame_t, sp));
         }
 
         // Call the code generation function
@@ -371,7 +371,7 @@ bool https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L371
 gen_putself(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
 {
     // Load self from CFP
-    mov(cb, RAX, mem_opnd(64, RDI, 24));
+    mov(cb, RAX, member_opnd(REG_CFP, rb_control_frame_t, self));
 
     // Write it on the stack
     x86opnd_t stack_top = ctx_stack_push(ctx, 1);
@@ -384,18 +384,18 @@ bool https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L384
 gen_getlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
 {
     // Load environment pointer EP from CFP
-    mov(cb, RDX, member_opnd(RDI, rb_control_frame_t, ep));
+    mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
 
     // Compute the offset from BP to the local
     int32_t local_idx = (int32_t)ctx_get_arg(ctx, 0);
     const int32_t offs = -8 * local_idx;
 
     // Load the local from the block
-    mov(cb, RCX, mem_opnd(64, RDX, offs));
+    mov(cb, REG0, mem_opnd(64, REG0, offs));
 
     // Write the local at SP
     x86opnd_t stack_top = ctx_stack_push(ctx, 1);
-    mov(cb, stack_top, RCX);
+    mov(cb, stack_top, REG0);
 
     return true;
 }
@@ -417,10 +417,10 @@ gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L417
     */
 
     // Load environment pointer EP from CFP
-    mov(cb, RDX, member_opnd(RDI, rb_control_frame_t, ep));
+    mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
 
     // flags & VM_ENV_FLAG_WB_REQUIRED
-    x86opnd_t flags_opnd = mem_opnd(64, RDX, 8 * VM_ENV_DATA_INDEX_FLAGS);
+    x86opnd_t flags_opnd = mem_opnd(64, REG0, 8 * VM_ENV_DATA_INDEX_FLAGS);
     test(cb, flags_opnd, imm_opnd(VM_ENV_FLAG_WB_REQUIRED));
 
     // Create a size-exit to fall back to the interpreter
@@ -431,12 +431,12 @@ gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L431
 
     // Pop the value to write from the stack
     x86opnd_t stack_top = ctx_stack_pop(ctx, 1);
-    mov(cb, RCX, stack_top);
+    mov(cb, REG1, stack_top);
 
     // Write the value at the environment pointer
     int32_t local_idx = (int32_t)ctx_get_arg(ctx, 0);
     const int32_t offs = -8 * local_idx;
-    mov(cb, mem_opnd(64, RDX, offs), RCX);
+    mov(cb, mem_opnd(64, REG0, offs), REG1);
 
     return true;
 }
@@ -604,11 +604,6 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L604
 
 
 
-    // FIXME: for now, we hardcode ec
-    // TODO: hardcode EC
-    //mov(cb, RDI, const_ptr_opnd(rb_current_execution_context()));
-
-
     // Allocate a new CFP
     //ec->cfp--;
 
@@ -658,8 +653,9 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L653
 
 
     // Save the MicroJIT registers
-    push(cb, RDI);
-    push(cb, R9);
+    push(cb, REG_CFP);
+    push(cb, REG_EC);
+    push(cb, REG_SP);
 
 
 
@@ -671,8 +667,9 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L667
 
 
     // Restore MicroJIT registers
-    pop(cb, R9);
-    pop(cb, RDI);
+    pop(cb, REG_SP);
+    pop(cb, REG_EC);
+    pop(cb, REG_CFP);
 
 
 
-- 
cgit v1.2.1


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

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