This commit is contained in:
Takashi Kokubun 2022-12-30 21:27:12 -08:00
Родитель 7a19aad8c3
Коммит 28290d5198
3 изменённых файлов: 43 добавлений и 32 удалений

Просмотреть файл

@ -1,4 +1,5 @@
require 'ruby_vm/mjit/context'
require 'ruby_vm/mjit/exit_compiler'
require 'ruby_vm/mjit/insn_compiler'
require 'ruby_vm/mjit/instruction'
require 'ruby_vm/mjit/jit_state'
@ -22,35 +23,6 @@ module RubyVM::MJIT
class Compiler
attr_accessor :write_pos
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::X86Assembler]
def self.compile_exit(jit, ctx, asm)
if C.mjit_opts.stats
insn = decode_insn(C.VALUE.new(jit.pc).*)
asm.comment("increment insn exit: #{insn.name}")
asm.mov(:rax, (C.mjit_insn_exits + insn.bin).to_i)
asm.add([:rax], 1) # TODO: lock
end
asm.comment("exit to interpreter")
# Update pc
asm.mov(:rax, jit.pc) # rax = jit.pc
asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax) # cfp->pc = rax
# Update sp
if ctx.stack_size > 0
asm.add(SP, C.VALUE.size * ctx.stack_size) # rbx += stack_size
asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP) # cfp->sp = rbx
end
# Restore callee-saved registers
asm.pop(SP)
asm.mov(:rax, Qundef)
asm.ret
end
def self.decode_insn(encoded)
INSNS.fetch(C.rb_vm_insn_decode(encoded))
end
@ -60,6 +32,7 @@ module RubyVM::MJIT
@comments = Hash.new { |h, k| h[k] = [] }
@mem_block = mem_block
@write_pos = 0
@exit_compiler = ExitCompiler.new
@insn_compiler = InsnCompiler.new
end
@ -138,7 +111,7 @@ module RubyVM::MJIT
when EndBlock
break
when CantCompile
self.class.compile_exit(jit, ctx, asm)
@exit_compiler.compile_exit(jit, ctx, asm)
break
end
index += insn.len
@ -213,7 +186,7 @@ module RubyVM::MJIT
# opt_newarray_min
# invokesuper
# invokeblock
when :leave then @insn_compiler.leave(jit, ctx, asm)
when :leave then @insn_compiler.leave(jit, ctx, asm)
# throw
# jump
# branchif

Просмотреть файл

@ -0,0 +1,34 @@
module RubyVM::MJIT
class ExitCompiler
def initialize = freeze
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::X86Assembler]
def compile_exit(jit, ctx, asm)
if C.mjit_opts.stats
insn = decode_insn(C.VALUE.new(jit.pc).*)
asm.comment("increment insn exit: #{insn.name}")
asm.mov(:rax, (C.mjit_insn_exits + insn.bin).to_i)
asm.add([:rax], 1) # TODO: lock
end
asm.comment("exit to interpreter")
# Update pc
asm.mov(:rax, jit.pc) # rax = jit.pc
asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax) # cfp->pc = rax
# Update sp
if ctx.stack_size > 0
asm.add(SP, C.VALUE.size * ctx.stack_size) # rbx += stack_size
asm.mov([CFP, C.rb_control_frame_t.offsetof(:sp)], SP) # cfp->sp = rbx
end
# Restore callee-saved registers
asm.pop(SP)
asm.mov(:rax, Qundef)
asm.ret
end
end
end

Просмотреть файл

@ -5,6 +5,10 @@ module RubyVM::MJIT
# scratch regs: rax
class InsnCompiler
# 4/101
def initialize
@exit_compiler = ExitCompiler.new
freeze
end
# nop
# getlocal
@ -106,7 +110,7 @@ module RubyVM::MJIT
asm.mov(:eax, [EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
asm.test(:eax, :eax)
asm.jz(not_interrupted = asm.new_label(:not_interrupted))
Compiler.compile_exit(jit, ctx, asm) # TODO: use ocb
@exit_compiler.compile_exit(jit, ctx, asm) # TODO: use ocb
asm.write_label(not_interrupted)
asm.comment('pop stack frame')