This commit is contained in:
Takashi Kokubun 2022-12-26 22:06:43 -08:00
Родитель 652d63789f
Коммит 4fe5efbf7f
5 изменённых файлов: 36 добавлений и 7 удалений

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

@ -19,14 +19,14 @@ module RubyVM::MJIT
def leave(jit, ctx, asm)
assert_eq!(ctx.stack_size, 1)
# Check interrupts
asm.comment("RUBY_VM_CHECK_INTS(ec)")
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
asm.write_label(not_interrupted)
# Pop the current frame (ec->cfp++)
asm.comment("pop stack frame")
asm.add(CFP, C.rb_control_frame_t.size) # cfp = cfp + 1
asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], CFP) # ec->cfp = cfp

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

@ -10,10 +10,13 @@ module RubyVM::MJIT
# REX = 0100WR0B
REX_W = 0b01001000
attr_reader :comments
def initialize
@bytes = []
@label_id = 0
@labels = {}
@label_id = 0
@comments = Hash.new { |h, k| h[k] = [] }
end
def compile(addr)
@ -173,6 +176,10 @@ module RubyVM::MJIT
end
end
def comment(message)
@comments[@bytes.size] << message
end
def new_label(name)
Label.new(id: @label_id += 1, name:)
end

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

@ -26,11 +26,13 @@ module RubyVM::MJIT
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::X86Assembler]
def self.compile_exit(jit, ctx, asm)
# update pc
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
# 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
@ -45,6 +47,7 @@ module RubyVM::MJIT
# @param mem_block [Integer] JIT buffer address
def initialize(mem_block)
@comments = Hash.new { |h, k| h[k] = [] }
@mem_block = mem_block
@write_pos = 0
@insn_compiler = InsnCompiler.new
@ -56,6 +59,7 @@ module RubyVM::MJIT
return if iseq.body.param.flags.has_opt
asm = X86Assembler.new
asm.comment("Block: #{iseq.body.location.label}@#{iseq.body.location.pathobj}:#{iseq.body.location.first_lineno}")
compile_prologue(asm)
compile_block(asm, iseq)
iseq.body.jit_func = compile(asm)
@ -73,11 +77,20 @@ module RubyVM::MJIT
def compile(asm)
start_addr = write_addr
# Write machine code
C.mjit_mark_writable
@write_pos += asm.compile(start_addr)
C.mjit_mark_executable
end_addr = write_addr
# Convert comment indexes to addresses
asm.comments.each do |index, comments|
@comments[start_addr + index] += comments
end
asm.comments.clear
# Dump disasm if --mjit-dump-disasm
if C.mjit_opts.dump_disasm && start_addr < end_addr
dump_disasm(start_addr, end_addr)
end
@ -92,6 +105,8 @@ module RubyVM::MJIT
#
# @param asm [RubyVM::MJIT::X86Assembler]
def compile_prologue(asm)
asm.comment("MJIT entry")
# Save callee-saved registers used by JITed code
asm.push(SP)
@ -124,6 +139,7 @@ module RubyVM::MJIT
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::X86Assembler]
def compile_insn(jit, ctx, asm, insn)
asm.comment("Insn: #{insn.name}")
case insn.name
when :putnil then @insn_compiler.putnil(jit, ctx, asm)
when :leave then @insn_compiler.leave(jit, ctx, asm)
@ -137,9 +153,16 @@ module RubyVM::MJIT
def dump_disasm(from, to)
C.dump_disasm(from, to).each do |address, mnemonic, op_str|
@comments.fetch(address, []).each do |comment|
puts bold(" # #{comment}")
end
puts " 0x#{"%x" % address}: #{mnemonic} #{op_str}"
end
puts
end
def bold(text)
"\e[1m#{text}\e[0m"
end
end
end

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

@ -578,7 +578,7 @@ module RubyVM::MJIT # :nodoc: all
pathobj: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), pathobj)"), true],
base_label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), base_label)"), true],
label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), label)"), true],
first_lineno: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), first_lineno)"), true],
first_lineno: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), first_lineno)")],
node_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), node_id)")],
code_location: [self.rb_code_location_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), code_location)")],
)

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

@ -423,7 +423,6 @@ generator = BindingGenerator.new(
ruby_fields: {
rb_iseq_location_struct: %w[
base_label
first_lineno
label
pathobj
]