summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-01-04 00:12:16 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 22:11:20 -0800
commit1f69ba1d8413abe20e95f74761ba267f0e35c649 (patch)
tree5565b8f3eedbb1502360d27b5b15a5e2bffad413
parentee80b2be20ae8a5102ac478f2b0fc0cf8786eaa3 (diff)
Use the actual sp_offset
-rw-r--r--lib/ruby_vm/mjit/assembler.rb9
-rw-r--r--lib/ruby_vm/mjit/exit_compiler.rb4
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb2
-rw-r--r--mjit.c9
4 files changed, 16 insertions, 8 deletions
diff --git a/lib/ruby_vm/mjit/assembler.rb b/lib/ruby_vm/mjit/assembler.rb
index bc42ad1a6a..f23696244d 100644
--- a/lib/ruby_vm/mjit/assembler.rb
+++ b/lib/ruby_vm/mjit/assembler.rb
@@ -215,6 +215,15 @@ module RubyVM::MJIT
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
disp: src_disp,
)
+ # MOV r32, imm32 (Mod 11: reg)
+ in Integer => src_imm if r32?(dst_reg) && imm32?(src_imm)
+ # B8+ rd id
+ # OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
+ insn(
+ opcode: 0xb8,
+ rd: dst_reg,
+ imm: imm32(src_imm),
+ )
# MOV r/m64, imm32 (Mod 11: reg)
in Integer => src_imm if r64?(dst_reg) && imm32?(src_imm)
# REX.W + C7 /0 id
diff --git a/lib/ruby_vm/mjit/exit_compiler.rb b/lib/ruby_vm/mjit/exit_compiler.rb
index d92f8a1588..a1eca9fe23 100644
--- a/lib/ruby_vm/mjit/exit_compiler.rb
+++ b/lib/ruby_vm/mjit/exit_compiler.rb
@@ -45,9 +45,10 @@ module RubyVM::MJIT
end
# @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
# @param stub [RubyVM::MJIT::BlockStub]
- def compile_jump_stub(jit, asm, stub)
+ def compile_jump_stub(jit, ctx, asm, stub)
case stub
when BlockStub
asm.comment("block stub hit: #{stub.iseq.body.location.label}@#{C.rb_iseq_path(stub.iseq)}:#{stub.iseq.body.location.first_lineno}")
@@ -57,6 +58,7 @@ module RubyVM::MJIT
# Call rb_mjit_stub_hit
asm.mov(:rdi, to_value(stub))
+ asm.mov(:esi, ctx.sp_offset)
asm.call(C.rb_mjit_stub_hit)
# Jump to the address returned by rb_mjit_stub_hit
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index c17167a4ac..3468be9598 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -375,7 +375,7 @@ module RubyVM::MJIT
)
stub_hit = Assembler.new.then do |ocb_asm|
- @exit_compiler.compile_jump_stub(jit, ocb_asm, block_stub)
+ @exit_compiler.compile_jump_stub(jit, ctx, ocb_asm, block_stub)
@ocb.write(ocb_asm)
end
diff --git a/mjit.c b/mjit.c
index dcf29feb84..c143bf3fa6 100644
--- a/mjit.c
+++ b/mjit.c
@@ -345,7 +345,7 @@ rb_mjit_compile(const rb_iseq_t *iseq)
}
void *
-rb_mjit_stub_hit(VALUE branch_stub)
+rb_mjit_stub_hit(VALUE branch_stub, int sp_offset)
{
VALUE result;
@@ -356,15 +356,12 @@ rb_mjit_stub_hit(VALUE branch_stub)
mjit_stats_p = false; // Avoid impacting JIT stats by itself
rb_control_frame_t *cfp = GET_EC()->cfp;
- // Given JIT's SP offset, temporarily update SP to preserve stack values.
- // It's reset afterwards for consistency with the code without this stub.
- unsigned int stack_max = cfp->iseq->body->stack_max;
- cfp->sp += stack_max;
+ cfp->sp += sp_offset; // preserve stack values, also using the actual sp_offset to make jit.peek_at_stack work
VALUE cfp_ptr = rb_funcall(rb_cMJITCfpPtr, rb_intern("new"), 1, SIZET2NUM((size_t)cfp));
result = rb_funcall(rb_MJITCompiler, rb_intern("stub_hit"), 2, branch_stub, cfp_ptr);
- cfp->sp -= stack_max;
+ cfp->sp -= sp_offset; // reset for consistency with the code without the stub
mjit_stats_p = mjit_opts.stats;
mjit_call_p = original_call_p;