aboutsummaryrefslogtreecommitdiffstats
path: root/yjit.rb
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2021-06-10 13:16:58 -0700
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:36 -0400
commit46d5e10279b6f1cea46682b5a5da3a09c5ce0c07 (patch)
tree36d54adb88de3fb5a6c81bb64c16c49b6a97cf7e /yjit.rb
parentf54e6e131099b5502f7d9be57f29bab11c70d841 (diff)
downloadruby-46d5e10279b6f1cea46682b5a5da3a09c5ce0c07.tar.gz
Add graphviz output
This adds a method to blocks to get outgoing ids, then uses the outgoing ids to generate a graphviz graph. Two methods were added to the Block object. One method returns an id for the block, which is just the address of the underlying block. The other method returns a list of outgoing block ids. We can use Block#id in conjunction with Block#outgoing_ids to construct a graph of blocks
Diffstat (limited to 'yjit.rb')
-rw-r--r--yjit.rb37
1 files changed, 37 insertions, 0 deletions
diff --git a/yjit.rb b/yjit.rb
index 6f7fdb41b3..442f9ef1b6 100644
--- a/yjit.rb
+++ b/yjit.rb
@@ -55,6 +55,43 @@ module YJIT
def self.comments_for(start_address, end_address)
Primitive.comments_for(start_address, end_address)
end
+
+ def self.graphviz_for(iseq)
+ iseq = RubyVM::InstructionSequence.of(iseq)
+ buff = ''
+ blocks = blocks_for(iseq)
+ buff << "digraph g {"
+ buff << " node [shape=record];"
+ blocks.each do |block|
+ buff << "b#{block.id} [label=\"#{disasm_block(block).gsub(/\n/, "\\l\n")}\"];"
+ block.outgoing_ids.each do |id|
+ buff << "b#{block.id} -> b#{id};"
+ end
+ end
+ buff << "}"
+ buff
+ end
+
+ def self.disasm_block(block)
+ cs = YJIT::Disasm.new
+ comments = comments_for(block.address, block.address + block.code.length)
+ comment_idx = 0
+ str = ''
+ cs.disasm(block.code, block.address).each do |i|
+ while (comment = comments[comment_idx]) && comment.address <= i.address
+ str << " ; #{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
+ str
+ end
end
# Return a hash for statistics generated for the --yjit-stats command line option.