Split responsibilities differently

This commit is contained in:
Takashi Kokubun 2022-12-17 22:00:16 -08:00
parent d9c2eb6f42
commit 2700d35b7b
4 changed files with 38 additions and 38 deletions

View file

@ -1,11 +1,11 @@
module RubyVM::MJIT module RubyVM::MJIT
class InsnCompiler class InsnCompiler
def compile_putnil(_asm) def on_putnil(_asm)
# TODO # TODO
KeepCompiling KeepCompiling
end end
def compile_leave(asm) def on_leave(asm)
# pop the current frame (ec->cfp++) # pop the current frame (ec->cfp++)
asm.add(:rsi, C.rb_control_frame_t.size) asm.add(:rsi, C.rb_control_frame_t.size)
asm.mov([:rdi, C.rb_execution_context_t.offsetof(:cfp)], :rsi) asm.mov([:rdi, C.rb_execution_context_t.offsetof(:cfp)], :rsi)

View file

@ -6,12 +6,15 @@ module RubyVM::MJIT
@bytes = [] @bytes = []
end end
def compile(compiler) = with_dump_disasm(compiler) do def compile(addr)
C.mjit_mark_writable writer = ByteWriter.new(addr)
write_bytes(compiler.write_addr, @bytes) # If you pack bytes containing \x00, Ruby fails to recognize bytes after \x00.
C.mjit_mark_executable # So writing byte by byte to avoid hitting that situation.
@bytes.each_with_index do |byte, index|
compiler.write_pos += @bytes.size writer[index] = byte
end
@bytes.size
ensure
@bytes.clear @bytes.clear
end end
@ -36,27 +39,5 @@ module RubyVM::MJIT
# [C3] # [C3]
@bytes.push(0xc3) @bytes.push(0xc3)
end end
private
def with_dump_disasm(compiler)
from = compiler.write_addr
yield
to = compiler.write_addr
if C.mjit_opts.dump_disasm && from < to
C.dump_disasm(from, to).each do |address, mnemonic, op_str|
puts " 0x#{"%p" % address}: #{mnemonic} #{op_str}"
end
end
end
def write_bytes(addr, bytes)
writer = ByteWriter.new(addr)
# If you pack bytes containing \x00, Ruby fails to recognize bytes after \x00.
# So writing byte by byte to avoid hitting that situation.
bytes.each_with_index do |byte, index|
writer[index] = byte
end
end
end end
end end

View file

@ -22,9 +22,9 @@ module RubyVM::MJIT
end end
# @param iseq [RubyVM::MJIT::CPointer::Struct] # @param iseq [RubyVM::MJIT::CPointer::Struct]
def compile(iseq) def call(iseq)
return if iseq.body.location.label == '<main>' return if iseq.body.location.label == '<main>'
iseq.body.jit_func = compile_iseq(iseq) iseq.body.jit_func = compile_block(iseq)
rescue Exception => e rescue Exception => e
# TODO: check --mjit-verbose # TODO: check --mjit-verbose
$stderr.puts e.full_message $stderr.puts e.full_message
@ -37,7 +37,7 @@ module RubyVM::MJIT
private private
# ec -> RDI, cfp -> RSI # ec -> RDI, cfp -> RSI
def compile_iseq(iseq) def compile_block(iseq)
addr = write_addr addr = write_addr
asm = X86Assembler.new asm = X86Assembler.new
@ -51,20 +51,39 @@ module RubyVM::MJIT
index += insn.len index += insn.len
end end
asm.compile(self) compile(asm)
addr
end end
def compile_insn(asm, insn) def compile_insn(asm, insn)
case insn.name case insn.name
when :putnil then @insn_compiler.compile_putnil(asm) when :putnil then @insn_compiler.on_putnil(asm)
when :leave then @insn_compiler.compile_leave(asm) when :leave then @insn_compiler.on_leave(asm)
else raise NotImplementedError, "insn '#{insn.name}' is not supported yet" else raise NotImplementedError, "insn '#{insn.name}' is not supported yet"
end end
end end
def compile(asm)
start_addr = write_addr
C.mjit_mark_writable
@write_pos += asm.compile(start_addr)
C.mjit_mark_executable
end_addr = write_addr
if C.mjit_opts.dump_disasm && start_addr < end_addr
dump_disasm(start_addr, end_addr)
end
start_addr
end
def decode_insn(encoded) def decode_insn(encoded)
INSNS.fetch(C.rb_vm_insn_decode(encoded)) INSNS.fetch(C.rb_vm_insn_decode(encoded))
end end
def dump_disasm(from, to)
C.dump_disasm(from, to).each do |address, mnemonic, op_str|
puts " 0x#{"%p" % address}: #{mnemonic} #{op_str}"
end
end
end end
end end

2
mjit.c
View file

@ -384,7 +384,7 @@ rb_mjit_compile(const rb_iseq_t *iseq)
mjit_call_p = false; // Avoid impacting JIT metrics by itself mjit_call_p = false; // Avoid impacting JIT metrics by itself
VALUE iseq_ptr = rb_funcall(rb_cMJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq)); VALUE iseq_ptr = rb_funcall(rb_cMJITIseqPtr, rb_intern("new"), 1, SIZET2NUM((size_t)iseq));
rb_funcall(rb_MJITCompiler, rb_intern("compile"), 1, iseq_ptr); rb_funcall(rb_MJITCompiler, rb_intern("call"), 1, iseq_ptr);
mjit_call_p = original_call_p; mjit_call_p = original_call_p;
} }