Implement asm comments
This commit is contained in:
parent
652d63789f
commit
4fe5efbf7f
@ -19,14 +19,14 @@ module RubyVM::MJIT
|
|||||||
def leave(jit, ctx, asm)
|
def leave(jit, ctx, asm)
|
||||||
assert_eq!(ctx.stack_size, 1)
|
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.mov(:eax, [EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
|
||||||
asm.test(:eax, :eax)
|
asm.test(:eax, :eax)
|
||||||
asm.jz(not_interrupted = asm.new_label(:not_interrupted))
|
asm.jz(not_interrupted = asm.new_label(:not_interrupted))
|
||||||
Compiler.compile_exit(jit, ctx, asm) # TODO: use ocb
|
Compiler.compile_exit(jit, ctx, asm) # TODO: use ocb
|
||||||
asm.write_label(not_interrupted)
|
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.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
|
asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], CFP) # ec->cfp = cfp
|
||||||
|
|
||||||
|
@ -10,10 +10,13 @@ module RubyVM::MJIT
|
|||||||
# REX = 0100WR0B
|
# REX = 0100WR0B
|
||||||
REX_W = 0b01001000
|
REX_W = 0b01001000
|
||||||
|
|
||||||
|
attr_reader :comments
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@bytes = []
|
@bytes = []
|
||||||
@label_id = 0
|
|
||||||
@labels = {}
|
@labels = {}
|
||||||
|
@label_id = 0
|
||||||
|
@comments = Hash.new { |h, k| h[k] = [] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile(addr)
|
def compile(addr)
|
||||||
@ -173,6 +176,10 @@ module RubyVM::MJIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def comment(message)
|
||||||
|
@comments[@bytes.size] << message
|
||||||
|
end
|
||||||
|
|
||||||
def new_label(name)
|
def new_label(name)
|
||||||
Label.new(id: @label_id += 1, name:)
|
Label.new(id: @label_id += 1, name:)
|
||||||
end
|
end
|
||||||
|
@ -26,11 +26,13 @@ module RubyVM::MJIT
|
|||||||
# @param ctx [RubyVM::MJIT::Context]
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
# @param asm [RubyVM::MJIT::X86Assembler]
|
# @param asm [RubyVM::MJIT::X86Assembler]
|
||||||
def self.compile_exit(jit, ctx, asm)
|
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(:rax, jit.pc) # rax = jit.pc
|
||||||
asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax) # cfp->pc = rax
|
asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax) # cfp->pc = rax
|
||||||
|
|
||||||
# update sp
|
# Update sp
|
||||||
if ctx.stack_size > 0
|
if ctx.stack_size > 0
|
||||||
asm.add(SP, C.VALUE.size * ctx.stack_size) # rbx += stack_size
|
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
|
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
|
# @param mem_block [Integer] JIT buffer address
|
||||||
def initialize(mem_block)
|
def initialize(mem_block)
|
||||||
|
@comments = Hash.new { |h, k| h[k] = [] }
|
||||||
@mem_block = mem_block
|
@mem_block = mem_block
|
||||||
@write_pos = 0
|
@write_pos = 0
|
||||||
@insn_compiler = InsnCompiler.new
|
@insn_compiler = InsnCompiler.new
|
||||||
@ -56,6 +59,7 @@ module RubyVM::MJIT
|
|||||||
return if iseq.body.param.flags.has_opt
|
return if iseq.body.param.flags.has_opt
|
||||||
|
|
||||||
asm = X86Assembler.new
|
asm = X86Assembler.new
|
||||||
|
asm.comment("Block: #{iseq.body.location.label}@#{iseq.body.location.pathobj}:#{iseq.body.location.first_lineno}")
|
||||||
compile_prologue(asm)
|
compile_prologue(asm)
|
||||||
compile_block(asm, iseq)
|
compile_block(asm, iseq)
|
||||||
iseq.body.jit_func = compile(asm)
|
iseq.body.jit_func = compile(asm)
|
||||||
@ -73,11 +77,20 @@ module RubyVM::MJIT
|
|||||||
def compile(asm)
|
def compile(asm)
|
||||||
start_addr = write_addr
|
start_addr = write_addr
|
||||||
|
|
||||||
|
# Write machine code
|
||||||
C.mjit_mark_writable
|
C.mjit_mark_writable
|
||||||
@write_pos += asm.compile(start_addr)
|
@write_pos += asm.compile(start_addr)
|
||||||
C.mjit_mark_executable
|
C.mjit_mark_executable
|
||||||
|
|
||||||
end_addr = write_addr
|
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
|
if C.mjit_opts.dump_disasm && start_addr < end_addr
|
||||||
dump_disasm(start_addr, end_addr)
|
dump_disasm(start_addr, end_addr)
|
||||||
end
|
end
|
||||||
@ -92,6 +105,8 @@ module RubyVM::MJIT
|
|||||||
#
|
#
|
||||||
# @param asm [RubyVM::MJIT::X86Assembler]
|
# @param asm [RubyVM::MJIT::X86Assembler]
|
||||||
def compile_prologue(asm)
|
def compile_prologue(asm)
|
||||||
|
asm.comment("MJIT entry")
|
||||||
|
|
||||||
# Save callee-saved registers used by JITed code
|
# Save callee-saved registers used by JITed code
|
||||||
asm.push(SP)
|
asm.push(SP)
|
||||||
|
|
||||||
@ -124,6 +139,7 @@ module RubyVM::MJIT
|
|||||||
# @param ctx [RubyVM::MJIT::Context]
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
# @param asm [RubyVM::MJIT::X86Assembler]
|
# @param asm [RubyVM::MJIT::X86Assembler]
|
||||||
def compile_insn(jit, ctx, asm, insn)
|
def compile_insn(jit, ctx, asm, insn)
|
||||||
|
asm.comment("Insn: #{insn.name}")
|
||||||
case insn.name
|
case insn.name
|
||||||
when :putnil then @insn_compiler.putnil(jit, ctx, asm)
|
when :putnil then @insn_compiler.putnil(jit, ctx, asm)
|
||||||
when :leave then @insn_compiler.leave(jit, ctx, asm)
|
when :leave then @insn_compiler.leave(jit, ctx, asm)
|
||||||
@ -137,9 +153,16 @@ module RubyVM::MJIT
|
|||||||
|
|
||||||
def dump_disasm(from, to)
|
def dump_disasm(from, to)
|
||||||
C.dump_disasm(from, to).each do |address, mnemonic, op_str|
|
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}"
|
puts " 0x#{"%x" % address}: #{mnemonic} #{op_str}"
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bold(text)
|
||||||
|
"\e[1m#{text}\e[0m"
|
||||||
|
end
|
||||||
end
|
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],
|
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],
|
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],
|
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)")],
|
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)")],
|
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: {
|
ruby_fields: {
|
||||||
rb_iseq_location_struct: %w[
|
rb_iseq_location_struct: %w[
|
||||||
base_label
|
base_label
|
||||||
first_lineno
|
|
||||||
label
|
label
|
||||||
pathobj
|
pathobj
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user