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

ruby-changes:68823

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:14:05 +0900 (JST)
Subject: [ruby-changes:68823] 824fea684f (master): Thread EC through jit state. Add codegen status enum.

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

From 824fea684f8346386db0391fb8575ced07ae01d6 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Mon, 1 Mar 2021 20:43:58 -0500
Subject: Thread EC through jit state. Add codegen status enum.

---
 mjit.h         |   2 +-
 ujit.h         |   2 +-
 ujit_codegen.c | 301 ++++++++++++++++++++++++++-------------------------------
 ujit_codegen.h |  28 +++---
 ujit_core.c    |  20 ++--
 ujit_core.h    |   4 +-
 ujit_iface.c   |  15 +--
 7 files changed, 169 insertions(+), 203 deletions(-)

diff --git a/mjit.h b/mjit.h
index 83f5cb919a..48596980b4 100644
--- a/mjit.h
+++ b/mjit.h
@@ -151,7 +151,7 @@ mjit_exec(rb_execution_context_t *ec) https://github.com/ruby/ruby/blob/trunk/mjit.h#L151
 
 #ifndef MJIT_HEADER
     if (rb_ujit_enabled_p() && !mjit_call_p && body->total_calls == rb_ujit_call_threshold())  {
-        rb_ujit_compile_iseq(iseq);
+        rb_ujit_compile_iseq(iseq, ec);
         return Qundef;
     }
 #endif
diff --git a/ujit.h b/ujit.h
index f3c2bffae6..e7ff96e64d 100644
--- a/ujit.h
+++ b/ujit.h
@@ -49,7 +49,7 @@ RUBY_SYMBOL_EXPORT_END https://github.com/ruby/ruby/blob/trunk/ujit.h#L49
 
 void rb_ujit_collect_vm_usage_insn(int insn);
 void rb_ujit_method_lookup_change(VALUE cme_or_cc);
-void rb_ujit_compile_iseq(const rb_iseq_t *iseq);
+void rb_ujit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec);
 void rb_ujit_init(struct rb_ujit_options *options);
 void rb_ujit_bop_redefined(VALUE klass, const rb_method_entry_t *me, enum ruby_basic_operators bop);
 void rb_ujit_constant_state_changed(void);
diff --git a/ujit_codegen.c b/ujit_codegen.c
index 78806e0f5a..e67d15c96b 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -205,7 +205,7 @@ ujit_check_ints(codeblock_t* cb, uint8_t* side_exit) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L205
 Compile a sequence of bytecode instructions for a given basic block version
 */
 void
-ujit_gen_block(ctx_t* ctx, block_t* block)
+ujit_gen_block(ctx_t* ctx, block_t* block, rb_execution_context_t* ec)
 {
     RUBY_ASSERT(cb != NULL);
     RUBY_ASSERT(block != NULL);
@@ -229,18 +229,17 @@ ujit_gen_block(ctx_t* ctx, block_t* block) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L229
         block,
         block->blockid.iseq,
         0,
-        0
+        0,
+        ec
     };
 
-    // Last operation that was successfully compiled
-    opdesc_t* p_last_op = NULL;
-
     // Mark the start position of the block
     block->start_pos = cb->write_pos;
 
     // For each instruction to compile
     for (;;) {
         // Set the current instruction
+        RUBY_ASSERT(insn_idx < iseq->body->iseq_size);
         jit.insn_idx = insn_idx;
         jit.pc = &encoded[insn_idx];
 
@@ -248,8 +247,11 @@ ujit_gen_block(ctx_t* ctx, block_t* block) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L247
         int opcode = jit_get_opcode(&jit);
 
         // Lookup the codegen function for this instruction
-        st_data_t st_op_desc;
-        if (!rb_st_lookup(gen_fns, opcode, &st_op_desc)) {
+        codegen_fn gen_fn;
+        if (!rb_st_lookup(gen_fns, opcode, (st_data_t*)&gen_fn)) {
+            // If we reach an unknown instruction,
+            // exit to the interpreter and stop compiling
+            ujit_gen_exit(&jit, ctx, cb, &encoded[insn_idx]);
             break;
         }
 
@@ -266,30 +268,24 @@ ujit_gen_block(ctx_t* ctx, block_t* block) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L268
         //print_str(cb, insn_name(opcode));
 
         // Call the code generation function
-        opdesc_t* p_desc = (opdesc_t*)st_op_desc;
-        bool success = p_desc->gen_fn(&jit, ctx);
+        codegen_status_t status = gen_fn(&jit, ctx);
 
-        // If we can't compile this instruction, stop
-        if (!success) {
+        // If we can't compile this instruction
+        // exit to the interpreter and stop compiling
+        if (status == UJIT_CANT_COMPILE) {
+            ujit_gen_exit(&jit, ctx, cb, &encoded[insn_idx]);
             break;
         }
 
-    	// Move to the next instruction
-        p_last_op = p_desc;
+        // Move to the next instruction to compile
         insn_idx += insn_len(opcode);
 
-        // If this instruction terminates this block
-        if (p_desc->is_branch) {
+        // If the instruction terminates this block
+        if (status == UJIT_END_BLOCK) {
             break;
         }
     }
 
-    // If the last instruction compiled did not terminate the block
-    // Generate code to exit to the interpreter
-    if (!p_last_op || !p_last_op->is_branch) {
-        ujit_gen_exit(&jit, ctx, cb, &encoded[insn_idx]);
-    }
-
     // Mark the end position of the block
     block->end_pos = cb->write_pos;
 
@@ -309,7 +305,7 @@ ujit_gen_block(ctx_t* ctx, block_t* block) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L305
     }
 }
 
-static bool
+static codegen_status_t
 gen_dup(jitstate_t* jit, ctx_t* ctx)
 {
     // Get the top value and its type
@@ -321,34 +317,34 @@ gen_dup(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L317
     mov(cb, REG0, dup_val);
     mov(cb, loc0, REG0);
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_nop(jitstate_t* jit, ctx_t* ctx)
 {
     // Do nothing
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_pop(jitstate_t* jit, ctx_t* ctx)
 {
     // Decrement SP
     ctx_stack_pop(ctx, 1);
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_putnil(jitstate_t* jit, ctx_t* ctx)
 {
     // Write constant at SP
     x86opnd_t stack_top = ctx_stack_push(ctx, T_NIL);
     mov(cb, stack_top, imm_opnd(Qnil));
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_putobject(jitstate_t* jit, ctx_t* ctx)
 {
     VALUE arg = jit_get_arg(jit, 0);
@@ -389,10 +385,10 @@ gen_putobject(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L385
         mov(cb, stack_top, RAX);
     }
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_putobject_int2fix(jitstate_t* jit, ctx_t* ctx)
 {
     int opcode = jit_get_opcode(jit);
@@ -402,10 +398,10 @@ gen_putobject_int2fix(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L398
     x86opnd_t stack_top = ctx_stack_push(ctx, T_FIXNUM);
     mov(cb, stack_top, imm_opnd(INT2FIX(cst_val)));
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_putself(jitstate_t* jit, ctx_t* ctx)
 {
     // Load self from CFP
@@ -415,10 +411,10 @@ gen_putself(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L411
     x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_top, RAX);
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx)
 {
     // Load environment pointer EP from CFP
@@ -435,10 +431,10 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L431
     x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_top, REG0);
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx)
 {
     //fprintf(stderr, "gen_getlocal_wc1\n");
@@ -462,10 +458,10 @@ gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L458
     x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_top, REG0);
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
-static bool
+static codegen_status_t
 gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
 {
     /*
@@ -503,7 +499,7 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L499
     const int32_t offs = -8 * local_idx;
     mov(cb, mem_opnd(64, REG0, offs), REG1);
 
-    return true;
+    return UJIT_KEEP_COMPILING;
 }
 
 // Check that `self` is a pointer to an object on the GC heap
@@ -522,24 +518,22 @@ guard_self_is_object(codeblock_t *cb, x86opnd_t self_opnd, uint8_t *side_exit, c https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L518
     }
 }
 
-static bool
+static codegen_status_t
 gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx)
 {
     IVC ic = (IVC)jit_get_arg(jit, 1);
 
     // Check that the inline cache has been set, slot index is known
-    if (!ic->entry)
-    {
-        return false;
+    if (!ic->entry) {
+        return UJIT_CANT_COMPILE;
     }
 
     // If the class uses the default allocator, instances should all be T_OBJECT
     // NOTE: This assumes nobody changes the allocator of the class after allocation.
     //       Eventually, we can encode whether an object is T_OBJECT or not
     //       inside object shapes.
-    if (rb_get_alloc_func(ic->entry->class_value) != rb_class_allocate_instance)
-    {
-        return false;
+    if (rb_get_alloc_func(ic->entry->class_value) != rb_class_allocate_instance) {
+        return UJIT_CANT_COMPILE;
     }
 
     uint32_t ivar_index = ic->entry->index;
@@ -566,8 +560,7 @@ gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L560
     jnz_ptr(cb, side_exit);
 
     // check that the extended table is big enough
-    if (ivar_index >= ROBJECT_EMBED_LEN_MAX + 1)
-    {
+    if (ivar_index >= ROBJECT_EMBED_LEN_MAX + 1) {
         // Check that the slot is inside the extended table (num_slots > index)
         x86opnd_t num_slots = mem_opnd(32, REG0, offsetof(struct RObject, as.heap.numiv));
         cmp(cb, num_slots, imm_opnd(ivar_index));
@@ -590,27 +583,25 @@ gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen (... truncated)

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

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