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

ruby-changes:68702

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:29 +0900 (JST)
Subject: [ruby-changes:68702] 4a57107696 (master): Sketch code to invalidate basic blocks. Rename version_t to block_t.

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

From 4a5710769609c35a32a071cc4cd3bcebdc3ec908 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 14 Jan 2021 13:33:19 -0500
Subject: Sketch code to invalidate basic blocks. Rename version_t to block_t.

---
 ujit_codegen.c |  22 +++----
 ujit_codegen.h |   6 +-
 ujit_core.c    | 180 ++++++++++++++++++++++++++++++++++++++-------------------
 ujit_core.h    |  11 ++--
 4 files changed, 142 insertions(+), 77 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 722f799e64..17a9447812 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -102,7 +102,7 @@ Compile an interpreter entry block to be inserted into an iseq https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L102
 Returns `NULL` if compilation fails.
 */
 uint8_t*
-ujit_gen_entry(version_t* version)
+ujit_gen_entry(block_t* block)
 {
     assert (cb != NULL);
 
@@ -122,7 +122,7 @@ ujit_gen_entry(version_t* version) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L122
     mov(cb, REG_SP, member_opnd(REG_CFP, rb_control_frame_t, sp));
 
     // Compile the block starting at this instruction
-    uint32_t num_instrs = ujit_gen_code(version);
+    uint32_t num_instrs = ujit_gen_code(block);
 
     // If no instructions were compiled
     if (num_instrs == 0) {
@@ -133,19 +133,19 @@ ujit_gen_entry(version_t* version) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L133
 }
 
 /*
-Compile a sequence of bytecode instructions
+Compile a sequence of bytecode instructions for a given basic block version
 */
 uint32_t
-ujit_gen_code(version_t* version)
+ujit_gen_code(block_t* block)
 {
     assert (cb != NULL);
 
-    // Copy the version's context to avoid mutating it
-    ctx_t ctx_copy = version->ctx;
+    // Copy the block's context to avoid mutating it
+    ctx_t ctx_copy = block->ctx;
     ctx_t* ctx = &ctx_copy;
 
-    const rb_iseq_t *iseq = version->blockid.iseq;
-    uint32_t insn_idx = version->blockid.idx;
+    const rb_iseq_t *iseq = block->blockid.iseq;
+    uint32_t insn_idx = block->blockid.idx;
     VALUE *encoded = iseq->body->iseq_encoded;
 
     // NOTE: if we are ever deployed in production, we
@@ -163,7 +163,7 @@ ujit_gen_code(version_t* version) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L163
 
     // Initialize JIT state object
     jitstate_t jit = {
-        version,
+        block,
         iseq
     };
 
@@ -216,7 +216,7 @@ ujit_gen_code(version_t* version) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L216
     if (UJIT_DUMP_MODE >= 2) {
         // Dump list of compiled instrutions
         fprintf(stderr, "Compiled the following for iseq=%p:\n", (void *)iseq);
-        VALUE *pc = &encoded[version->blockid.idx];
+        VALUE *pc = &encoded[block->blockid.idx];
         VALUE *end_pc = &encoded[insn_idx];
         while (pc < end_pc) {
             int opcode = opcode_at_pc(iseq, pc);
@@ -961,6 +961,7 @@ gen_branchunless(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L961
 
     // Generate the branch instructions
     gen_branch(
+        jit->block,
         ctx,
         jump_block,
         ctx,
@@ -1004,6 +1005,7 @@ gen_jump(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1005
 
     // Generate the jump instruction
     gen_branch(
+        jit->block,
         ctx,
         jump_block,
         ctx,
diff --git a/ujit_codegen.h b/ujit_codegen.h
index 0564c594d3..192cf29d61 100644
--- a/ujit_codegen.h
+++ b/ujit_codegen.h
@@ -12,7 +12,7 @@ codeblock_t* ocb; https://github.com/ruby/ruby/blob/trunk/ujit_codegen.h#L12
 typedef struct JITState
 {
     // Block version being compiled
-    version_t* version;
+    block_t* block;
 
     // Instruction sequence this is associated with
     const rb_iseq_t *iseq;
@@ -40,9 +40,9 @@ typedef struct OpDesc https://github.com/ruby/ruby/blob/trunk/ujit_codegen.h#L40
 
 } opdesc_t;
 
-uint8_t* ujit_gen_entry(version_t* version);
+uint8_t* ujit_gen_entry(block_t* block);
 
-uint32_t ujit_gen_code(version_t* version);
+uint32_t ujit_gen_code(block_t* block);
 
 void ujit_init_codegen(void);
 
diff --git a/ujit_core.c b/ujit_core.c
index 2cb1c252de..77c329970b 100644
--- a/ujit_core.c
+++ b/ujit_core.c
@@ -70,12 +70,12 @@ ctx_stack_opnd(ctx_t* ctx, int32_t idx) https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L70
 }
 
 // Retrieve a basic block version for an (iseq, idx) tuple
-version_t* find_block_version(blockid_t block, const ctx_t* ctx)
+block_t* find_block_version(blockid_t blockid, const ctx_t* ctx)
 {
     // If there exists a version for this block id
     st_data_t st_version;
-    if (rb_st_lookup(version_tbl, (st_data_t)&block, &st_version)) {
-        return (version_t*)st_version;
+    if (rb_st_lookup(version_tbl, (st_data_t)&blockid, &st_version)) {
+        return (block_t*)st_version;
     }
 
     //
@@ -85,68 +85,79 @@ version_t* find_block_version(blockid_t block, const ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L85
     return NULL;
 }
 // Compile a new block version immediately
-version_t* gen_block_version(blockid_t blockid, const ctx_t* ctx)
+block_t* gen_block_version(blockid_t blockid, const ctx_t* ctx)
 {
     // Allocate a version object
-    version_t* p_version = malloc(sizeof(version_t));
-    memcpy(&p_version->blockid, &blockid, sizeof(blockid_t));
-    memcpy(&p_version->ctx, ctx, sizeof(ctx_t));
-    p_version->incoming = NULL;
-    p_version->num_incoming = 0;
+    block_t* p_block = malloc(sizeof(block_t));
+    memcpy(&p_block->blockid, &blockid, sizeof(blockid_t));
+    memcpy(&p_block->ctx, ctx, sizeof(ctx_t));
+    p_block->incoming = NULL;
+    p_block->num_incoming = 0;
+    p_block->end_pos = 0;
+
+    // The block starts at the current position
+    p_block->start_pos = cb->write_pos;
 
     // Compile the block version
-    p_version->start_pos = cb->write_pos;
-    ujit_gen_code(p_version);
-    p_version->end_pos = cb->write_pos;
+    ujit_gen_code(p_block);
+
+    // The block may have been terminated in gen_branch
+    if (p_block->end_pos == 0)
+        p_block->end_pos = cb->write_pos;
 
     // Keep track of the new block version
-    st_insert(version_tbl, (st_data_t)&p_version->blockid, (st_data_t)p_version);
+    st_insert(version_tbl, (st_data_t)&p_block->blockid, (st_data_t)p_block);
 
-    return p_version;
+    return p_block;
 }
 
 // Generate a block version that is an entry point inserted into an iseq
 uint8_t* gen_entry_point(const rb_iseq_t *iseq, uint32_t insn_idx)
 {
     // Allocate a version object
-    version_t* p_version = malloc(sizeof(version_t));
+    block_t* p_block = malloc(sizeof(block_t));
     blockid_t blockid = { iseq, insn_idx };
-    memcpy(&p_version->blockid, &blockid, sizeof(blockid_t));
-    p_version->incoming = NULL;
-    p_version->num_incoming = 0;
+    memcpy(&p_block->blockid, &blockid, sizeof(blockid_t));
+    p_block->incoming = NULL;
+    p_block->num_incoming = 0;
+    p_block->end_pos = 0;
 
     // The entry context makes no assumptions about types
     ctx_t ctx = { 0 };
-    memcpy(&p_version->ctx, &ctx, sizeof(ctx_t));
+    memcpy(&p_block->ctx, &ctx, sizeof(ctx_t));
+
+    // The block starts at the current position
+    p_block->start_pos = cb->write_pos;
 
     // Compile the block version
-    p_version->start_pos = cb->write_pos;
-    uint8_t* code_ptr = ujit_gen_entry(p_version);
-    p_version->end_pos = cb->write_pos;
+    uint8_t* code_ptr = ujit_gen_entry(p_block);
+
+    // The block may have been terminated in gen_branch
+    if (p_block->end_pos == 0)
+        p_block->end_pos = cb->write_pos;
 
     // If we couldn't generate any code
     if (!code_ptr)
     {
-        free(p_version);
+        free(p_block);
         return NULL;
     }
 
     // Keep track of the new block version
-    st_insert(version_tbl, (st_data_t)&p_version->blockid, (st_data_t)p_version);
+    st_insert(version_tbl, (st_data_t)&p_block->blockid, (st_data_t)p_block);
 
     return code_ptr;
 }
 
 // Add an incoming branch for a given block version
-static void add_incoming(version_t* p_version, uint32_t branch_idx)
+static void add_incoming(block_t* p_block, uint32_t branch_idx)
 {
     // Add this branch to the list of incoming branches for the target
-    uint32_t* new_list = malloc(sizeof(uint32_t) * p_version->num_incoming + 1);
-    memcpy(new_list, p_version->incoming, p_version->num_incoming);
-    new_list[p_version->num_incoming] = branch_idx;
-    p_version->incoming = new_list;
-    p_version->num_incoming += 1;
-    //fprintf(stderr, "num_incoming: %d\n", p_version->num_incoming);
+    uint32_t* new_list = malloc(sizeof(uint32_t) * p_block->num_incoming + 1);
+    memcpy(new_list, p_block->incoming, p_block->num_incoming);
+    new_list[p_block->num_incoming] = branch_idx;
+    p_block->incoming = new_list;
+    p_block->num_incoming += 1;
 }
 
 // Called by the generated code when a branch stub is executed
@@ -176,19 +187,19 @@ uint8_t* branch_stub_hit(uint32_t branch_idx, uint32_t target_idx) https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L187
     }
 
     // Try to find a compiled version of this block
-    version_t* p_version = find_block_version(target, target_ctx);
+    block_t* p_block = find_block_version(target, target_ctx);
 
     // If this block hasn't yet been compiled
-    if (!p_version)
+    if (!p_block)
     {
-        p_version = gen_block_version(target, target_ctx);
+        p_block = gen_block_version(target, target_ctx);
     }
 
     // Add this branch to the list of incoming branches for the target
-    add_incoming(p_version, branch_idx);
+    add_incoming(p_block, branch_idx);
 
     // Update the branch target address
-    uint8_t* dst_addr = cb_get_ptr(cb, p_version->start_pos);
+    uint8_t* dst_addr = cb_get_ptr(cb, p_block->start_pos);
     branch->dst_addrs[target_idx] = dst_addr;
 
     // Rewrite the branch with the new jump target address
@@ -198,6 +209 (... truncated)

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

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