mirror of
https://github.com/ruby/ruby.git
synced 2025-08-26 06:25:31 +02:00
Split responsibilities differently
This commit is contained in:
parent
d9c2eb6f42
commit
2700d35b7b
4 changed files with 38 additions and 38 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
2
mjit.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue