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

ruby-changes:68670

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:17 +0900 (JST)
Subject: [ruby-changes:68670] bd7cc9ed98 (master): Thread insn_idx through context object

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

From bd7cc9ed98056d01dbdd592156e07ae6c6eff516 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Mon, 14 Dec 2020 15:57:55 -0500
Subject: Thread insn_idx through context object

---
 ujit_codegen.c | 36 ++++++++++++++----------------------
 ujit_codegen.h |  2 +-
 ujit_core.c    |  4 ++--
 ujit_core.h    | 15 ++++++++++-----
 4 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index ec55600bae..01785d5fc4 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -65,7 +65,7 @@ ujit_gen_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L65
 Generate an out-of-line exit to return to the interpreter
 */
 static uint8_t *
-ujit_side_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc)
+ujit_side_exit(codeblock_t* cb, ctx_t* ctx)
 {
     uint8_t* code_ptr = cb_get_ptr(cb, cb->write_pos);
 
@@ -84,6 +84,7 @@ ujit_side_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L84
     // 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);
     void* exit_instr = (void*)table[exit_opcode];
     mov(cb, RAX, const_ptr_opnd(exit_pc));
@@ -101,10 +102,9 @@ Compile a sequence of bytecode instructions starting at `insn_idx`. https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L102
 Returns `NULL` if compilation fails.
 */
 uint8_t *
-ujit_compile_block(const rb_iseq_t *iseq, unsigned int insn_idx, bool gen_entry)
+ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, bool gen_entry)
 {
     assert (cb != NULL);
-    unsigned first_insn_idx = insn_idx;
     VALUE *encoded = iseq->body->iseq_encoded;
 
     // NOTE: if we are ever deployed in production, we
@@ -136,7 +136,8 @@ ujit_compile_block(const rb_iseq_t *iseq, unsigned int insn_idx, bool gen_entry) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L136
     // For each instruction to compile
     unsigned num_instrs = 0;
     for (;;) {
-        // Set the current PC
+        // Set the current instruction
+        ctx.insn_idx = insn_idx;
         ctx.pc = &encoded[insn_idx];
 
         // Get the current opcode
@@ -187,7 +188,7 @@ ujit_compile_block(const rb_iseq_t *iseq, unsigned int insn_idx, bool gen_entry) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L188
     if (UJIT_DUMP_MODE >= 2) {
         // Dump list of compiled instrutions
         fprintf(stderr, "Compiled the following for iseq=%p:\n", (void *)iseq);
-        VALUE *pc = &encoded[first_insn_idx];
+        VALUE *pc = &encoded[ctx.start_idx];
         VALUE *end_pc = &encoded[insn_idx];
         while (pc < end_pc) {
             int opcode = opcode_at_pc(iseq, pc);
@@ -199,15 +200,6 @@ ujit_compile_block(const rb_iseq_t *iseq, unsigned int insn_idx, bool gen_entry) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L200
     return code_ptr;
 }
 
-
-
-
-
-
-
-
-
-
 static bool
 gen_dup(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
 {
@@ -248,7 +240,7 @@ static bool https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L240
 gen_putobject(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
 {
     // Load the argument from the bytecode sequence.
-    // We need to do this as the argument can chanage due to GC compaction.
+    // We need to do this as the argument can change due to GC compaction.
     x86opnd_t pc_imm = const_ptr_opnd((void*)ctx->pc);
     mov(cb, RAX, pc_imm);
     mov(cb, RAX, mem_opnd(64, RAX, 8)); // One after the opcode
@@ -330,7 +322,7 @@ gen_setlocal_wc0(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L322
     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, ctx->pc);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
     jnz_ptr(cb, side_exit);
@@ -386,7 +378,7 @@ gen_getinstancevariable(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L378
     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);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // Load self from CFP
     mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, self));
@@ -448,7 +440,7 @@ gen_setinstancevariable(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L440
     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);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // Load self from CFP
     mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, self));
@@ -501,7 +493,7 @@ gen_opt_lt(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L493
 {
     // Create a size-exit to fall back to the interpreter
     // Note: we generate the side-exit before popping operands from the stack
-    uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // TODO: make a helper function for guarding on op-not-redefined
     // Make sure that minus isn't redefined for integers
@@ -542,7 +534,7 @@ gen_opt_minus(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L534
 {
     // Create a size-exit to fall back to the interpreter
     // Note: we generate the side-exit before popping operands from the stack
-    uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // TODO: make a helper function for guarding on op-not-redefined
     // Make sure that minus isn't redefined for integers
@@ -582,7 +574,7 @@ gen_opt_plus(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L574
 {
     // Create a size-exit to fall back to the interpreter
     // Note: we generate the side-exit before popping operands from the stack
-    uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // TODO: make a helper function for guarding on op-not-redefined
     // Make sure that plus isn't redefined for integers
@@ -711,7 +703,7 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L703
     }
 
     // Create a size-exit to fall back to the interpreter
-    uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc);
+    uint8_t* side_exit = ujit_side_exit(ocb, ctx);
 
     // Check for interrupts
     // RUBY_VM_CHECK_INTS(ec)
diff --git a/ujit_codegen.h b/ujit_codegen.h
index 5216dbb1be..3dc3d1bf47 100644
--- a/ujit_codegen.h
+++ b/ujit_codegen.h
@@ -3,7 +3,7 @@ https://github.com/ruby/ruby/blob/trunk/ujit_codegen.h#L3
 
 #include "stddef.h"
 
-uint8_t *ujit_compile_block(const rb_iseq_t *iseq, unsigned int insn_idx, bool gen_entry);
+uint8_t *ujit_compile_block(const rb_iseq_t *iseq, uint32_t insn_idx, bool gen_entry);
 
 void ujit_init_codegen(void);
 
diff --git a/ujit_core.c b/ujit_core.c
index c981ef0e30..1119e3df91 100644
--- a/ujit_core.c
+++ b/ujit_core.c
@@ -18,7 +18,7 @@ st_index_t blockid_hash(st_data_t arg) https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L18
 {
     const blockid_t *blockid = (const blockid_t*)arg;
     st_index_t hash0 = st_numhash((st_data_t)blockid->iseq);
-    st_index_t hash1 = st_numhash((st_data_t)blockid->idx);
+    st_index_t hash1 = st_numhash((st_data_t)(uint64_t)blockid->idx);
 
     // Use XOR to combine the hashes
     return hash0 ^ hash1;
@@ -31,7 +31,7 @@ static const struct st_hash_type hashtype_blockid = { https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L31
 
 // Retrieve a basic block version for an (iseq, idx) tuple
 // TODO: we need to add a versioning context here
-uint8_t* get_block_version(const rb_iseq_t *iseq, unsigned int idx /*, ctx_t* ctx */)
+uint8_t* get_block_version(const rb_iseq_t *iseq, uint32_t idx)
 {
     blockid_t blockid = { iseq, idx };
 
diff --git a/ujit_core.h b/ujit_core.h
index f42ff84ace..5bcbd89f3c 100644
--- a/ujit_core.h
+++ b/ujit_core.h
@@ -27,7 +27,7 @@ typedef struct BlockId https://github.com/ruby/ruby/blob/trunk/ujit_core.h#L27
     const rb_iseq_t *iseq;
 
     // Instruction index
-    const unsigned int idx;
+    const uint32_t idx;
 
 } blockid_t;
 
@@ -39,26 +39,31 @@ typedef struct ctx_struct https://github.com/ruby/ruby/blob/trunk/ujit_core.h#L39
     // Some of the information here is only needed during
     // code generation, eg: current pc
 
+    // The start of the generated code
+    uint8_t *code_ptr;
+
     // Instruction sequence this is associated with
     const rb_iseq_t *iseq;
 
     // Index in the iseq of the opcode we are replacing
-    size_t start_idx;
+    uint32_t start_idx;
 
-    // The start of the generated code
-    uint8_t *code_ptr;
+    // Index of the current instruction being compiled
+    uint32_t insn_idx;
 
     // Current PC
     VALUE *pc;
 
     // Number of values pushed on the temporary stack
-    int32_t stack_size;
+    uint32_t stack_size;
 
     // Whether we know self is a heap object
     bool self_is_object;
 
 } ctx_t;
 
+uint8_t* get_block_version(const rb_iseq_t *iseq, uint32_t idx);
+
 // Context object methods
 int ctx_get_opcode(ctx_t *ctx);
 VALUE ctx_get_arg(ctx_t* ctx, size_t arg_idx);
-- 
cgit v1.2.1


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

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