summaryrefslogtreecommitdiff
path: root/lib/ruby_vm/mjit/insn_compiler.rb
diff options
context:
space:
mode:
authorTakashi Kokubun <[email protected]>2023-01-02 22:53:14 -0800
committerTakashi Kokubun <[email protected]>2023-03-05 22:11:20 -0800
commita8dec34961d7734ad975e44efa8aae361a1c4f5a (patch)
tree5849c716f37c959d9276ddb8c598fe1142a7f6fa /lib/ruby_vm/mjit/insn_compiler.rb
parent21696ad81ec40cf9cd146836dc8c945f1e485774 (diff)
Implement initial opt_lt
Diffstat (limited to 'lib/ruby_vm/mjit/insn_compiler.rb')
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb54
1 files changed, 45 insertions, 9 deletions
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index 262d33387a..2950536e8e 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -1,7 +1,4 @@
module RubyVM::MJIT
- # scratch regs: rax
- #
- # 5/101
class InsnCompiler
# @param ocb [CodeBlock]
# @param exit_compiler [RubyVM::MJIT::ExitCompiler]
@@ -20,6 +17,7 @@ module RubyVM::MJIT
asm.incr_counter(:mjit_insns_count)
asm.comment("Insn: #{insn.name}")
+ # 5/101
case insn.name
# nop
# getlocal
@@ -149,6 +147,7 @@ module RubyVM::MJIT
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
def putnil(jit, ctx, asm)
+ raise 'sp_offset != stack_size' if ctx.sp_offset != ctx.stack_size # TODO: handle this
asm.mov([SP, C.VALUE.size * ctx.stack_size], Qnil)
ctx.stack_push(1)
KeepCompiling
@@ -165,6 +164,7 @@ module RubyVM::MJIT
# Push it to the stack
# TODO: GC offsets
+ raise 'sp_offset != stack_size' if ctx.sp_offset != ctx.stack_size # TODO: handle this
if asm.imm32?(val)
asm.mov([SP, C.VALUE.size * ctx.stack_size], val)
else # 64-bit immediates can't be directly written to memory
@@ -226,7 +226,7 @@ module RubyVM::MJIT
asm.comment('RUBY_VM_CHECK_INTS(ec)')
asm.mov(:eax, [EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
asm.test(:eax, :eax)
- asm.jnz(compile_side_exit(jit, ctx))
+ asm.jnz(side_exit(jit, ctx))
asm.comment('pop stack frame')
asm.add(CFP, C.rb_control_frame_t.size) # cfp = cfp + 1
@@ -268,10 +268,38 @@ module RubyVM::MJIT
return EndBlock
end
- unless @invariants.assume_bop_not_redefined(jit, C.INTEGER_REDEFINED_OP_FLAG, C.BOP_LT)
- return CantCompile
+ comptime_recv = jit.peek_at_stack(1)
+ comptime_obj = jit.peek_at_stack(0)
+
+ if fixnum?(comptime_recv) && fixnum?(comptime_obj)
+ unless @invariants.assume_bop_not_redefined(jit, C.INTEGER_REDEFINED_OP_FLAG, C.BOP_LT)
+ return CantCompile
+ end
+
+ raise 'sp_offset != stack_size' if ctx.sp_offset != ctx.stack_size # TODO: handle this
+ recv_index = ctx.stack_size - 2
+ obj_index = ctx.stack_size - 1
+
+ asm.comment('guard recv is fixnum');
+ asm.test([SP, C.VALUE.size * recv_index], C.RUBY_FIXNUM_FLAG)
+ asm.je(side_exit(jit, ctx))
+
+ asm.comment('guard obj is fixnum');
+ asm.test([SP, C.VALUE.size * obj_index], C.RUBY_FIXNUM_FLAG)
+ asm.je(side_exit(jit, ctx))
+
+ asm.mov(:rax, [SP, C.VALUE.size * obj_index])
+ asm.cmp([SP, C.VALUE.size * recv_index], :rax)
+ asm.mov(:rax, Qfalse)
+ asm.mov(:rcx, Qtrue)
+ asm.cmovl(:rax, :rcx)
+ asm.mov([SP, C.VALUE.size * recv_index], :rax)
+
+ ctx.stack_pop(1)
+ KeepCompiling
+ else
+ CantCompile # TODO: delegate to send
end
- CantCompile
end
# opt_le
@@ -330,6 +358,11 @@ module RubyVM::MJIT
end
end
+ def fixnum?(obj)
+ flag = C.RUBY_FIXNUM_FLAG
+ (C.to_value(obj) & flag) == flag
+ end
+
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
@@ -354,10 +387,13 @@ module RubyVM::MJIT
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
- def compile_side_exit(jit, ctx)
+ def side_exit(jit, ctx)
+ if side_exit = jit.side_exits[jit.pc]
+ return side_exit
+ end
asm = Assembler.new
@exit_compiler.compile_side_exit(jit, ctx, asm)
- @ocb.write(asm)
+ jit.side_exits[jit.pc] = @ocb.write(asm)
end
end
end