Skip to content

Commit

Permalink
Implement asm comments
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Mar 6, 2023
1 parent 652d637 commit 4fe5efb
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 7 deletions.
4 changes: 2 additions & 2 deletions lib/mjit/insn_compiler.rb
Expand Up @@ -19,14 +19,14 @@ def putnil(jit, ctx, asm)
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

Expand Down
9 changes: 8 additions & 1 deletion lib/mjit/x86_assembler.rb
Expand Up @@ -10,10 +10,13 @@ class Label < Data.define(:id, :name); end
# 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)
Expand Down Expand Up @@ -173,6 +176,10 @@ def test(left, right)
end
end

def comment(message)
@comments[@bytes.size] << message
end

def new_label(name)
Label.new(id: @label_id += 1, name:)
end
Expand Down
27 changes: 25 additions & 2 deletions lib/ruby_vm/mjit/compiler.rb
Expand Up @@ -26,11 +26,13 @@ class Compiler
# @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
Expand All @@ -45,6 +47,7 @@ def self.compile_exit(jit, ctx, asm)

# @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
Expand All @@ -56,6 +59,7 @@ def call(iseq)
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)
Expand All @@ -73,11 +77,20 @@ def write_addr
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
Expand All @@ -92,6 +105,8 @@ def compile(asm)
#
# @param asm [RubyVM::MJIT::X86Assembler]
def compile_prologue(asm)
asm.comment("MJIT entry")

# Save callee-saved registers used by JITed code
asm.push(SP)

Expand Down Expand Up @@ -124,6 +139,7 @@ def compile_block(asm, iseq)
# @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)
Expand All @@ -137,9 +153,16 @@ def decode_insn(encoded)

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
2 changes: 1 addition & 1 deletion mjit_c.rb
Expand Up @@ -578,7 +578,7 @@ def C.rb_iseq_location_t
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)")],
)
Expand Down
1 change: 0 additions & 1 deletion tool/mjit/bindgen.rb
Expand Up @@ -423,7 +423,6 @@ def push_target(target)
ruby_fields: {
rb_iseq_location_struct: %w[
base_label
first_lineno
label
pathobj
]
Expand Down

0 comments on commit 4fe5efb

Please sign in to comment.