зеркало из https://github.com/github/ruby.git
Try carving out ExitCompiler
This commit is contained in:
Родитель
7a19aad8c3
Коммит
28290d5198
|
@ -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')
|
||||
|
|
Загрузка…
Ссылка в новой задаче