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

ruby-changes:68755

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:13:26 +0900 (JST)
Subject: [ruby-changes:68755] 8357e8e514 (master): Fixed two bugs in JIT-to-JIT calls (thanks Alan!)

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

From 8357e8e5142b97c452929aade0c24f59c7a34833 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Fri, 5 Feb 2021 12:18:55 -0500
Subject: Fixed two bugs in JIT-to-JIT calls (thanks Alan!)

---
 bootstraptest/test_ujit.rb | 48 +++++++++++++++++++++++++++++++++++++++++++-
 ujit_codegen.c             | 50 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/bootstraptest/test_ujit.rb b/bootstraptest/test_ujit.rb
index 9d26aec347..dda9e89559 100644
--- a/bootstraptest/test_ujit.rb
+++ b/bootstraptest/test_ujit.rb
@@ -27,4 +27,50 @@ assert_equal '1', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ujit.rb#L27
     end
 
     retval
-}
\ No newline at end of file
+}
+
+# foo leaves a temp on the stack before the call
+assert_equal '6', %q{
+    def bar
+        return 5
+    end
+
+    def foo
+        return 1 + bar
+    end
+
+    foo()
+    retval = foo()
+}
+
+# Ruby-to-Ruby call and C call
+assert_normal_exit %q{
+  def bar
+    puts('hi!')
+  end
+
+  def foo
+    bar
+  end
+
+  foo()
+  foo()
+}
+
+# Test for GC safety. Don't invalidate dead iseqs.
+assert_normal_exit %q{
+  Class.new do
+    def foo
+      itself
+    end
+
+    new.foo
+    UJIT.install_entry(RubyVM::InstructionSequence.of(instance_method(:foo)))
+    new.foo
+  end
+
+  4.times { GC.start }
+  def itself
+    self
+  end
+}
diff --git a/ujit_codegen.c b/ujit_codegen.c
index 30d38b5d77..bb5c336d6d 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -62,6 +62,9 @@ ujit_gen_exit(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb, VALUE* exit_pc) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L62
         mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG_SP);
     }
 
+    // Update the CFP on the EC
+    mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
+
     // Directly return the next PC, which is a constant
     mov(cb, RAX, const_ptr_opnd(exit_pc));
     mov(cb, member_opnd(REG_CFP, rb_control_frame_t, pc), RAX);
@@ -1250,7 +1253,7 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1253
     mov(cb, REG0, const_ptr_opnd(jit->pc + insn_len(BIN(opt_send_without_block))));
     mov(cb, mem_opnd(64, REG_CFP, offsetof(rb_control_frame_t, pc)), REG0);
 
-    // Store the updated SP on the CFP (pop arguments and self)
+    // Store the updated SP on the CFP (pop arguments and receiver)
     lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * -(argc + 1)));
     mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0);
 
@@ -1285,11 +1288,8 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1288
     mov(cb, mem_opnd(64, REG0, 8 * -1), imm_opnd(frame_type));
 
     // Allocate a new CFP (ec->cfp--)
-    sub(
-        cb,
-        member_opnd(REG_EC, rb_execution_context_t, cfp),
-        imm_opnd(sizeof(rb_control_frame_t))
-    );
+    sub(cb, REG_CFP, imm_opnd(sizeof(rb_control_frame_t)));
+    mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
 
     // Setup the new frame
     // *cfp = (const struct rb_control_frame_struct) {
@@ -1315,10 +1315,31 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1315
     mov(cb, member_opnd(REG1, rb_control_frame_t, pc), REG0);
 
     //print_str(cb, "calling Ruby func:");
-    //print_str(cb, rb_id2name(mid));
+    //print_str(cb, rb_id2name(vm_ci_mid(cd->ci)));
+
+    // Load the updated SP
+    mov(cb, REG_SP, member_opnd(REG_CFP, rb_control_frame_t, sp));
+   
+    // Directly jump to the entry point of the callee
+    gen_direct_jump(
+        &DEFAULT_CTX,
+        (blockid_t){ iseq, 0 }
+    );
+    
+
+
+    // TODO: create stub for call continuation
+
+    // TODO: need to pop args in the caller ctx
+
+    // TODO: stub so we can return to JITted code
+    //blockid_t cont_block = { jit->iseq, jit_next_insn_idx(jit) };
+
+
+
+
+
 
-    // Write the post call bytes, exit to the interpreter
-    cb_write_post_call_bytes(cb);
 
     return true;
 }
@@ -1387,11 +1408,9 @@ gen_leave(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1408
     // Load environment pointer EP from CFP
     mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
 
-    // flags & VM_FRAME_FLAG_FINISH
+    // if (flags & VM_FRAME_FLAG_FINISH) != 0
     x86opnd_t flags_opnd = mem_opnd(64, REG0, sizeof(VALUE) * VM_ENV_DATA_INDEX_FLAGS);
     test(cb, flags_opnd, imm_opnd(VM_FRAME_FLAG_FINISH));
-
-    // if (flags & VM_FRAME_FLAG_FINISH) != 0
     jnz_ptr(cb, side_exit);
 
     // TODO:
@@ -1400,15 +1419,16 @@ gen_leave(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L1419
     // Load the return value
     mov(cb, REG0, ctx_stack_pop(ctx, 1));
 
-    // Pop the current CFP (ec->cfp++)
+    // Pop the current frame (ec->cfp++)
     // Note: the return PC is already in the previous CFP
     add(cb, REG_CFP, imm_opnd(sizeof(rb_control_frame_t)));
     mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
 
     // Push the return value on the caller frame
-    mov(cb, REG1, member_opnd(REG_CFP, rb_control_frame_t, sp));
-    mov(cb, mem_opnd(64, REG1, 0), REG0);
+    // The SP points one above the topmost value
     add(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), imm_opnd(SIZEOF_VALUE));
+    mov(cb, REG_SP, member_opnd(REG_CFP, rb_control_frame_t, sp));
+    mov(cb, mem_opnd(64, REG_SP, -SIZEOF_VALUE), REG0);
 
     // Write the post call bytes
     cb_write_post_call_bytes(cb);
-- 
cgit v1.2.1


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

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