зеркало из https://github.com/github/ruby.git
Implement asm comments
This commit is contained in:
Родитель
652d63789f
Коммит
4fe5efbf7f
|
@ -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
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче