ZJIT: Add iongraph-generating Ruby script (#15466)

Run like so:

    $ ../tool/zjit_iongraph.rb ../build-dev/miniruby --zjit-call-threshold=2 tmp/ghbug.rb
    false
    false
    tmp/ghbug.rb:3:in 'Object#doit': this shouldnt ever be nil (RuntimeError)
            from tmp/ghbug.rb:10:in '<main>'
    W, [2025-12-09T11:00:32.070382 #67400]  WARN -- : Command failed with exit status 1
    zjit_iongraph_67405.html
    $

Then open zjit_iongraph_67405.html with your browser.
This commit is contained in:
Max Bernstein 2025-12-15 11:52:35 -05:00 committed by GitHub
parent 3038286a4b
commit 9581d6c898
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
Notes: git 2025-12-15 16:53:04 +00:00
Merged-By: tekknolagi <donotemailthisaddress@bernsteinbear.com>
2 changed files with 584 additions and 0 deletions

546
tool/zjit_iongraph.html Normal file

File diff suppressed because one or more lines are too long

38
tool/zjit_iongraph.rb Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env ruby
require 'json'
require 'logger'
LOGGER = Logger.new($stderr)
def run_ruby *cmd
# Find the first --zjit* option and add --zjit-dump-hir-iongraph after it
zjit_index = cmd.find_index { |arg| arg.start_with?("--zjit") }
raise "No --zjit option found in command" unless zjit_index
cmd.insert(zjit_index + 1, "--zjit-dump-hir-iongraph")
pid = Process.spawn(*cmd)
_, status = Process.wait2(pid)
if status.exitstatus != 0
LOGGER.warn("Command failed with exit status #{status.exitstatus}")
end
pid
end
usage = "Usage: zjit_iongraph.rb <path_to_ruby> <options>"
RUBY = ARGV[0] || raise(usage)
OPTIONS = ARGV[1..]
pid = run_ruby(RUBY, *OPTIONS)
functions = Dir["/tmp/zjit-iongraph-#{pid}/fun*.json"].map do |path|
JSON.parse(File.read(path))
end
if functions.empty?
LOGGER.warn("No iongraph functions found for PID #{pid}")
end
json = JSON.dump({version: 1, functions: functions})
# Get zjit_iongraph.html from the sibling file next to this script
html = File.read(File.join(File.dirname(__FILE__), "zjit_iongraph.html"))
html.sub!("{{ IONJSON }}", json)
output_path = "zjit_iongraph_#{pid}.html"
File.write(output_path, html)
puts "Wrote iongraph to #{output_path}"