summaryrefslogtreecommitdiff
path: root/lib/ruby_vm/mjit/insn_compiler.rb
diff options
context:
space:
mode:
authorTakashi Kokubun <[email protected]>2022-12-31 13:41:32 -0800
committerTakashi Kokubun <[email protected]>2023-03-05 22:11:20 -0800
commitc3d99d0f12e2b494e16a5c61134ca312a3a6e3a5 (patch)
treead7af15b229a98e599e87668e54bc033f53394a6 /lib/ruby_vm/mjit/insn_compiler.rb
parent2b8d1c93ea4d44fba5997901fc4a50b9436bc8b5 (diff)
Implement defer_compilation
Diffstat (limited to 'lib/ruby_vm/mjit/insn_compiler.rb')
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb42
1 files changed, 37 insertions, 5 deletions
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index 96bab0a225..0d40cb6f50 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -1,7 +1,7 @@
module RubyVM::MJIT
# scratch regs: rax
#
- # 4/101
+ # 5/101
class InsnCompiler
# @param ocb [CodeBlock]
def initialize(ocb)
@@ -33,7 +33,7 @@ module RubyVM::MJIT
# @param asm [RubyVM::MJIT::Assembler]
def putnil(jit, ctx, asm)
asm.mov([SP, C.VALUE.size * ctx.stack_size], Qnil)
- ctx.stack_size += 1
+ ctx.stack_push(1)
KeepCompiling
end
@@ -55,7 +55,7 @@ module RubyVM::MJIT
asm.mov([SP, C.VALUE.size * ctx.stack_size], :rax)
end
- ctx.stack_size += 1
+ ctx.stack_push(1)
KeepCompiling
end
@@ -141,7 +141,18 @@ module RubyVM::MJIT
# opt_mod
# opt_eq
# opt_neq
- # opt_lt
+
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
+ # @param asm [RubyVM::MJIT::Assembler]
+ def opt_lt(jit, ctx, asm)
+ unless jit.at_current_insn?
+ defer_compilation(jit, ctx, asm)
+ return EndBlock
+ end
+ CantCompile
+ end
+
# opt_le
# opt_gt
# opt_ge
@@ -178,7 +189,7 @@ module RubyVM::MJIT
# Push it to the stack
asm.mov([SP, C.VALUE.size * ctx.stack_size], :rax)
- ctx.stack_size += 1
+ ctx.stack_push(1)
KeepCompiling
end
@@ -198,6 +209,27 @@ module RubyVM::MJIT
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
+ # @param asm [RubyVM::MJIT::Assembler]
+ def defer_compilation(jit, ctx, asm)
+ # Make a stub to compile the current insn
+ block_stub = BlockStub.new(
+ iseq: jit.iseq,
+ pc: jit.pc,
+ ctx: ctx.dup,
+ )
+
+ stub_hit = Assembler.new.then do |ocb_asm|
+ @exit_compiler.compile_jump_stub(jit, ocb_asm, block_stub)
+ @ocb.write(ocb_asm)
+ end
+
+ asm.comment('defer_compilation: block stub')
+ asm.stub(block_stub)
+ asm.jmp(stub_hit)
+ end
+
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
def compile_side_exit(jit, ctx)
asm = Assembler.new
@exit_compiler.compile_exit(jit, ctx, asm)