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

ruby-changes:68677

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:18 +0900 (JST)
Subject: [ruby-changes:68677] 16ddb422eb (master): Complete refactoring to codegen functions

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

From 16ddb422eb83cc8223a8e93297aef4d6ab273238 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 16 Sep 2020 10:33:34 -0400
Subject: Complete refactoring to codegen functions

---
 ujit_compile.c | 176 ++++++++++++++++++++++++++-------------------------------
 1 file changed, 81 insertions(+), 95 deletions(-)

diff --git a/ujit_compile.c b/ujit_compile.c
index 62a98481ba..2a99a85e45 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -14,6 +14,9 @@ https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L14
 // Code generation context
 typedef struct ctx_struct
 {
+    // Current PC
+    VALUE* pc;
+
     // TODO: virtual stack pointer handling
 
 } ctx_t;
@@ -65,11 +68,26 @@ addr2insn_bookkeeping(void *code_ptr, int insn) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L68
     }
 }
 
-// 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 RSI
-// See rb_ujit_empty_func(rb_control_frame_t *cfp) in iseq.c
+// Get the current instruction opcode from the context object
+int ctx_get_opcode(ctx_t* ctx)
+{
+    return (int)(*ctx->pc);
+}
+
+// Get an instruction argument from the context object
+VALUE ctx_get_arg(ctx_t* ctx, size_t arg_idx)
+{
+    assert (arg_idx + 1 < insn_len(ctx_get_opcode(ctx)));
+    return *(ctx->pc + arg_idx + 1);
+}
+
+/*
+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 RSI
+See rb_ujit_empty_func(rb_control_frame_t *cfp) in iseq.c
+*/
 uint8_t *
 ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
 {
@@ -84,9 +102,12 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L102
         rb_bug("out of executable memory");
     }
 
+    // Get a pointer to the current write position in the code block
+    uint8_t *code_ptr = &cb->mem_block[cb->write_pos];
+    //printf("write pos: %ld\n", cb->write_pos);
+
     int insn = (int)iseq->body->iseq_encoded[insn_idx];
 	int len = insn_len(insn);
-
     //const char* name = insn_name(insn);
     //printf("%s\n", name);
 
@@ -99,22 +120,20 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L120
 
     codegen_fn gen_fn = (codegen_fn)st_gen_fn;
 
-    // Compute the address of the next instruction
-    void *next_pc = &iseq->body->iseq_encoded[insn_idx + len];
-
-    // Get a pointer to the current write position in the code block
-    uint8_t *code_ptr = &cb->mem_block[cb->write_pos];
-    //printf("write pos: %ld\n", cb->write_pos);
-
     // Write the pre call bytes
     ujit_instr_entry(cb);
 
-    // TODO: create codegen context
+    // Create codegen context
+    ctx_t ctx;
+
+    // Set the current PC
+    ctx.pc = &iseq->body->iseq_encoded[insn_idx];
 
     // Call the code generation function
-    gen_fn(cb, NULL);
+    gen_fn(cb, &ctx);
 
     // Directly return the next PC, which is a constant
+    void *next_pc = &iseq->body->iseq_encoded[insn_idx + len];
     mov(cb, RAX, const_ptr_opnd(next_pc));
 
     // Write the post call bytes
@@ -123,102 +142,66 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L142
     addr2insn_bookkeeping(code_ptr, insn);
 
     return code_ptr;
+}
 
+void gen_nop(codeblock_t* cb, ctx_t* ctx)
+{
+}
 
+void gen_pop(codeblock_t* cb, ctx_t* ctx)
+{
+    // Decrement SP
+    sub(cb, mem_opnd(64, RDI, 8), imm_opnd(8));
+}
 
+void gen_putobject_int2fix(codeblock_t* cb, ctx_t* ctx)
+{
+    // Load current SP into RAX
+    mov(cb, RAX, mem_opnd(64, RDI, 8));
 
+    // Write constant at SP
+    int opcode = ctx_get_opcode(ctx);
+    int cst_val = (opcode == BIN(putobject_INT2FIX_0_))? 0:1;
+    mov(cb, mem_opnd(64, RAX, 0), imm_opnd(INT2FIX(cst_val)));
 
+    // Load incremented SP into RCX
+    lea(cb, RCX, mem_opnd(64, RAX, 8));
 
+    // Write back incremented SP
+    mov(cb, mem_opnd(64, RDI, 8), RCX);
+}
 
-    /*
-    if (insn == BIN(putobject_INT2FIX_0_) || insn == BIN(putobject_INT2FIX_1_))
-    {
-        // Load current SP into RAX
-        mov(cb, RAX, mem_opnd(64, RDI, 8));
-
-        // Write constant at SP
-        int cst_val = (insn == BIN(putobject_INT2FIX_0_))? 0:1;
-        mov(cb, mem_opnd(64, RAX, 0), imm_opnd(INT2FIX(cst_val)));
-
-        // Load incremented SP into RCX
-        lea(cb, RCX, mem_opnd(64, RAX, 8));
-
-        // Write back incremented SP
-        mov(cb, mem_opnd(64, RDI, 8), RCX);
-
-        // Directly return the next PC, which is a constant
-        mov(cb, RAX, const_ptr_opnd(next_pc));
-
-        // Write the post call bytes
-        ujit_instr_exit(cb);
-
-        addr2insn_bookkeeping(code_ptr, insn);
-
-        return code_ptr;
-    }
-    */
-
-    // TODO: implement putself
-    /*
-    if (insn == BIN(putself))
-    {
-    }
-    */
-
-    // TODO: implement putobject
-    /*
-    if (insn == BIN(putobject))
-    {
-    }
-    */
-
-    /*
-    if (insn == BIN(getlocal_WC_0))
-    {
-        //printf("compiling getlocal_WC_0\n");
-
-        // Load current SP from CFP
-        mov(cb, RAX, mem_opnd(64, RDI, 8));
-
-        // Load block pointer from CFP
-        mov(cb, RDX, mem_opnd(64, RDI, 32));
-
-        // TODO: we may want a macro or helper function to get insn operands
-        // Compute the offset from BP to the local
-        int32_t opnd0 = (int)iseq->body->iseq_encoded[insn_idx+1];
-        const int32_t offs = -8 * opnd0;
+// TODO: putnil
+// could we reuse code from putobject_int2fix here?
 
-        // Load the local from the block
-        mov(cb, RCX, mem_opnd(64, RDX, offs));
+// TODO: implement putself
 
-        // Write the local at SP
-        mov(cb, mem_opnd(64, RAX, 0), RCX);
+// TODO: implement putobject
 
-        // Compute address of incremented SP
-        lea(cb, RCX, mem_opnd(64, RAX, 8));
+void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx)
+{
+    // Load current SP from CFP
+    mov(cb, RAX, mem_opnd(64, RDI, 8));
 
-        // Write back incremented SP
-        mov(cb, mem_opnd(64, RDI, 8), RCX);
+    // Load block pointer from CFP
+    mov(cb, RDX, mem_opnd(64, RDI, 32));
 
-        // Directly return the next PC, which is a constant
-        mov(cb, RAX, const_ptr_opnd(next_pc));
+    // TODO: we may want a macro or helper function to get insn operands
+    // 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;
 
-        // Write the post call bytes
-        ujit_instr_exit(cb);
+    // Load the local from the block
+    mov(cb, RCX, mem_opnd(64, RDX, offs));
 
-        addr2insn_bookkeeping(code_ptr, insn);
-    }
-    */
-}
+    // Write the local at SP
+    mov(cb, mem_opnd(64, RAX, 0), RCX);
 
-void gen_nop(codeblock_t* cb, ctx_t* ctx)
-{
-}
+    // Compute address of incremented SP
+    lea(cb, RCX, mem_opnd(64, RAX, 8));
 
-void gen_pop(codeblock_t* cb, ctx_t* ctx)
-{
-    // Decrement SP
-    sub(cb, mem_opnd(64, RDI, 8), imm_opnd(8));
+    // Write back incremented SP
+    mov(cb, mem_opnd(64, RDI, 8), RCX);
 }
 
 static void ujit_init()
@@ -233,4 +216,7 @@ static void ujit_init() https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L216
     // Map YARV opcodes to the corresponding codegen functions
     st_insert(gen_fns, (st_data_t)BIN(nop), (st_data_t)&gen_nop);
     st_insert(gen_fns, (st_data_t)BIN(pop), (st_data_t)&gen_pop);
+    st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_0_), (st_data_t)&gen_putobject_int2fix);
+    st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_1_), (st_data_t)&gen_putobject_int2fix);
+    st_insert(gen_fns, (st_data_t)BIN(getlocal_WC_0), (st_data_t)&gen_getlocal_wc0);
 }
-- 
cgit v1.2.1


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

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