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

ruby-changes:68694

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:26 +0900 (JST)
Subject: [ruby-changes:68694] df16bf97ec (master): Split out context object into jitstate_t and ctx_t

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

From df16bf97ece9c3f943750954c19d1caace089215 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Fri, 18 Dec 2020 15:02:43 -0500
Subject: Split out context object into jitstate_t and ctx_t

---
 ujit_codegen.c | 144 ++++++++++++++++++++++++++++++++++-----------------------
 ujit_codegen.h |  19 +++++++-
 ujit_core.c    |  22 ---------
 ujit_core.h    |  32 -------------
 ujit_iface.c   |   8 +++-
 5 files changed, 111 insertions(+), 114 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 09b61a9bea..a1fcb8b7c0 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -26,7 +26,31 @@ codeblock_t* cb = NULL; https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L26
 static codeblock_t outline_block;
 codeblock_t* ocb = NULL;
 
-// Ruby instruction entry
+// Get the current instruction's opcode
+static int
+jit_get_opcode(jitstate_t* jit)
+{
+    return opcode_at_pc(jit->iseq, jit->pc);
+}
+
+// Get the index of the next instruction
+static uint32_t
+jit_next_idx(jitstate_t* jit)
+{
+    return jit->insn_idx + insn_len(jit_get_opcode(jit));
+}
+
+// Get an instruction argument by index
+static VALUE
+jit_get_arg(jitstate_t* jit, size_t arg_idx)
+{
+    assert (arg_idx + 1 < insn_len(jit_get_opcode(jit)));
+    return *(jit->pc + arg_idx + 1);
+}
+
+/**
+Generate code to enter from the Ruby interpreter into ujit code
+*/
 static void
 ujit_gen_entry(codeblock_t* cb)
 {
@@ -40,7 +64,7 @@ ujit_gen_entry(codeblock_t* cb) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L64
 Generate an inline exit to return to the interpreter
 */
 static void
-ujit_gen_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc)
+ujit_gen_exit(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb, VALUE* exit_pc)
 {
     // Write the adjusted SP back into the CFP
     if (ctx->stack_size != 0)
@@ -62,9 +86,9 @@ ujit_gen_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L86
 Generate an out-of-line exit to return to the interpreter
 */
 static uint8_t *
-ujit_side_exit(codeblock_t* cb, ctx_t* ctx)
+ujit_side_exit(jitstate_t* jit, ctx_t* ctx)
 {
-    uint8_t* code_ptr = cb_get_ptr(cb, cb->write_pos);
+    uint8_t* code_ptr = cb_get_ptr(ocb, cb->write_pos);
 
     // Table mapping opcodes to interpreter handlers
     const void * const *table = rb_vm_get_insns_address_table();
@@ -72,15 +96,15 @@ ujit_side_exit(codeblock_t* cb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L96
     // Write back the old instruction at the exit PC
     // Otherwise the interpreter may jump right back to the
     // JITted code we're trying to exit
-    VALUE* exit_pc = &ctx->iseq->body->iseq_encoded[ctx->insn_idx];
-    int exit_opcode = opcode_at_pc(ctx->iseq, exit_pc);
+    VALUE* exit_pc = &jit->iseq->body->iseq_encoded[jit->insn_idx];
+    int exit_opcode = opcode_at_pc(jit->iseq, exit_pc);
     void* exit_instr = (void*)table[exit_opcode];
-    mov(cb, RAX, const_ptr_opnd(exit_pc));
-    mov(cb, RCX, const_ptr_opnd(exit_instr));
-    mov(cb, mem_opnd(64, RAX, 0), RCX);
+    mov(ocb, RAX, const_ptr_opnd(exit_pc));
+    mov(ocb, RCX, const_ptr_opnd(exit_instr));
+    mov(ocb, mem_opnd(64, RAX, 0), RCX);
 
     // Generate the code to exit to the interpreters
-    ujit_gen_exit(cb, ctx, exit_pc);
+    ujit_gen_exit(jit, ctx, ocb, exit_pc);
 
     return code_ptr;
 }
@@ -146,20 +170,24 @@ ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, uint32_t* num_instr https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L170
     // Get a pointer to the current write position in the code block
     uint8_t *code_ptr = cb_get_ptr(cb, cb->write_pos);
 
+    // Initialize JIT state object
+    jitstate_t jit = { 0 };
+    jit.iseq = iseq;
+    jit.start_idx = insn_idx;
+
     // Create codegen context
     ctx_t ctx = { 0 };
-    ctx.iseq = iseq;
-    ctx.code_ptr = code_ptr;
-    ctx.start_idx = insn_idx;
 
     // For each instruction to compile
     for (;;) {
         // Set the current instruction
-        ctx.insn_idx = insn_idx;
-        ctx.pc = &encoded[insn_idx];
+        jit.insn_idx = insn_idx;
+        jit.pc = &encoded[insn_idx];
 
         // Get the current opcode
-        int opcode = ctx_get_opcode(&ctx);
+        int opcode = jit_get_opcode(&jit);
+
+        //fprintf(stderr, "compiling %s\n", insn_name(opcode));
 
         // Lookup the codegen function for this instruction
         st_data_t st_gen_fn;
@@ -169,12 +197,11 @@ ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, uint32_t* num_instr https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L197
             break;
         }
 
-        //fprintf(stderr, "compiling %s\n", insn_name(opcode));
         //print_str(cb, insn_name(opcode));
 
         // Call the code generation function
         codegen_fn gen_fn = (codegen_fn)st_gen_fn;
-        if (!gen_fn(cb, ocb, &ctx)) {
+        if (!gen_fn(&jit, &ctx)) {
             break;
         }
 
@@ -195,12 +222,12 @@ ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, uint32_t* num_instr https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L222
     // FIXME: we only need to generate an exit if an instruction fails to compile
     //
     // Generate code to exit to the interpreter
-    ujit_gen_exit(cb, &ctx, &encoded[insn_idx]);
+    ujit_gen_exit(&jit, &ctx, cb, &encoded[insn_idx]);
 
     if (UJIT_DUMP_MODE >= 2) {
         // Dump list of compiled instrutions
         fprintf(stderr, "Compiled the following for iseq=%p:\n", (void *)iseq);
-        VALUE *pc = &encoded[ctx.start_idx];
+        VALUE *pc = &encoded[jit.start_idx];
         VALUE *end_pc = &encoded[insn_idx];
         while (pc < end_pc) {
             int opcode = opcode_at_pc(iseq, pc);
@@ -213,7 +240,7 @@ ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, uint32_t* num_instr https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L240
 }
 
 static bool
-gen_dup(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_dup(jitstate_t* jit, ctx_t* ctx)
 {
     x86opnd_t dup_val = ctx_stack_pop(ctx, 1);
     x86opnd_t loc0 = ctx_stack_push(ctx, 1);
@@ -225,14 +252,14 @@ gen_dup(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L252
 }
 
 static bool
-gen_nop(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_nop(jitstate_t* jit, ctx_t* ctx)
 {
     // Do nothing
     return true;
 }
 
 static bool
-gen_pop(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_pop(jitstate_t* jit, ctx_t* ctx)
 {
     // Decrement SP
     ctx_stack_pop(ctx, 1);
@@ -240,7 +267,7 @@ gen_pop(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L267
 }
 
 static bool
-gen_putnil(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_putnil(jitstate_t* jit, ctx_t* ctx)
 {
     // Write constant at SP
     x86opnd_t stack_top = ctx_stack_push(ctx, 1);
@@ -249,11 +276,11 @@ gen_putnil(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L276
 }
 
 static bool
-gen_putobject(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_putobject(jitstate_t* jit, ctx_t* ctx)
 {
     // Load the argument from the bytecode sequence.
     // We need to do this as the argument can change due to GC compaction.
-    x86opnd_t pc_imm = const_ptr_opnd((void*)ctx->pc);
+    x86opnd_t pc_imm = const_ptr_opnd((void*)jit->pc);
     mov(cb, RAX, pc_imm);
     mov(cb, RAX, mem_opnd(64, RAX, 8)); // One after the opcode
 
@@ -265,9 +292,9 @@ gen_putobject(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L292
 }
 
 static bool
-gen_putobject_int2fix(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_putobject_int2fix(jitstate_t* jit, ctx_t* ctx)
 {
-    int opcode = ctx_get_opcode(ctx);
+    int opcode = jit_get_opcode(jit);
     int cst_val = (opcode == BIN(putobject_INT2FIX_0_))? 0:1;
 
     // Write constant at SP
@@ -278,7 +305,7 @@ gen_putobject_int2fix(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L305
 }
 
 static bool
-gen_putself(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_putself(jitstate_t* jit, ctx_t* ctx)
 {
     // Load self from CFP
     mov(cb, RAX, member_opnd(REG_CFP, rb_control_frame_t, self));
@@ -291,13 +318,13 @@ gen_putself(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L318
 }
 
 static bool
-gen_getlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx)
 {
     // Load environment pointer EP from CFP
     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);
+    int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
     const int32_t offs = -8 * local_idx;
 
     // Load the local from the block
@@ -311,7 +338,7 @@ gen_getlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L338
 }
 
 static bool
-gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
+gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
 {
     /*
     vm_env_write(const VALUE *ep, int index, VALUE v)
@@ -334,7 +361,7 @@ gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L361
     test(cb, flags_opnd, imm_opnd(VM_ENV_FLAG_WB_REQUIRED));
 
     // Create a size-exit to fall back to the interpreter
-    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
+    uint8_t* side_exit = ujit_side_exit(jit, ctx);
 
     // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
     jnz_ptr(cb, side_exit);
@@ -344,7 +371,7 @@ gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L371
     mov(cb, REG1, stack_top);
 
     // Write the value at the enviro (... truncated)

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

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