diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2021-04-07 15:27:05 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:33 -0400 |
commit | 515fb988fe3c3ad28fdcaea4f043ea6a445c5213 (patch) | |
tree | 85168fefe3b4222796a3f21c8dc456dcbc8dddfc /yjit.rb | |
parent | 543bdde6c21f071e673aa8090086e1045ee4f2d9 (diff) |
YJIT: add comments to disassembly
Introduce a new macro `ADD_COMMENT(cb, comment)` that records a comment
for the current write position in the code block.
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Aaron Patterson <aaron.patterson@shopify.com>
Diffstat (limited to 'yjit.rb')
-rw-r--r-- | yjit.rb | 77 |
1 files changed, 49 insertions, 28 deletions
@@ -1,40 +1,61 @@ module YJIT - def self.disasm(iseq) - iseq = RubyVM::InstructionSequence.of(iseq) + if defined?(Disasm) + def self.disasm(iseq, tty: $stdout && $stdout.tty?) + iseq = RubyVM::InstructionSequence.of(iseq) - blocks = YJIT.blocks_for(iseq) - return if blocks.empty? + blocks = YJIT.blocks_for(iseq) + return if blocks.empty? - str = "" - - cs = YJIT::Disasm.new + str = "" + str << iseq.disasm + str << "\n" - str << iseq.disasm - str << "\n" + # Sort the blocks by increasing addresses + sorted_blocks = blocks.sort_by(&:address) + + highlight = ->(str) { + if tty + "\x1b[1m#{str}\x1b[0m" + else + str + end + } + + cs = YJIT::Disasm.new + sorted_blocks.each_with_index do |block, i| + str << "== BLOCK #{i+1}/#{blocks.length}: #{block.code.length} BYTES, ISEQ RANGE [#{block.iseq_start_index},#{block.iseq_end_index}) ".ljust(80, "=") + str << "\n" + + comments = comments_for(block.address, block.address + block.code.length) + comment_idx = 0 + cs.disasm(block.code, block.address).each do |i| + while (comment = comments[comment_idx]) && comment.address <= i.address + str << " ;#{highlight.call(comment.comment)}\n" + comment_idx += 1 + end + + str << sprintf( + " %<address>08x: %<instruction>s\t%<details>s\n", + address: i.address, + instruction: i.mnemonic, + details: i.op_str + ) + end + end - # Sort the blocks by increasing addresses - blocks.sort_by(&:address).each_with_index do |block, i| - str << "== BLOCK #{i+1}/#{blocks.length}: #{block.code.length} BYTES, ISEQ RANGE [#{block.iseq_start_index},#{block.iseq_end_index}) ".ljust(80, "=") + block_sizes = blocks.map { |block| block.code.length } + total_bytes = block_sizes.sum + str << "\n" + str << "Total code size: #{total_bytes} bytes" str << "\n" - cs.disasm(block.code, block.address).each do |i| - str << sprintf( - " %<address>08x: %<instruction>s\t%<details>s\n", - address: i.address, - instruction: i.mnemonic, - details: i.op_str - ) - end + str end - block_sizes = blocks.map { |block| block.code.length } - total_bytes = block_sizes.reduce(0, :+) - str << "\n" - str << "Total code size: #{total_bytes} bytes" - str << "\n" - - str - end if defined?(Disasm) + def self.comments_for(start_address, end_address) + Primitive.comments_for(start_address, end_address) + end + end # Return a hash for statistics generated for the --yjit-stats command line option. # Return nil when option is not passed or unavailable. |