Last active
July 9, 2016 18:02
-
-
Save nurse/1c42f2d7436f86c042c7286231348ff7 to your computer and use it in GitHub Desktop.
Profile perf(3)'s report into YARV instructions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'pp' | |
files = {'vm.inc' => [], 'insns.def' => []} | |
current_insn = nil | |
current_filename = 'vm.inc' | |
lineno_offset = 0 | |
IO.foreach('vm.inc') do |line| | |
case line | |
when /^INSN_ENTRY\((\w+)\)/ | |
files[current_filename] << $. - lineno_offset | |
current_insn = $1 | |
files[current_filename] << current_insn | |
when /#line (\d+) "([^"]+)"/ | |
current_filename = $2 | |
lineno_offset = $. - $1.to_i | |
files[current_filename] << $. - lineno_offset | |
files[current_filename] << current_insn | |
end | |
end | |
def find_insn(files, fn, lineno) | |
ary = files[fn] | |
return nil unless ary | |
current = nil | |
ary.each_slice(2) do |n, insn| | |
return current || insn if lineno < n | |
current = insn | |
end | |
end | |
addrs = {} | |
s = `perf annotate -svm_exec_core --stdio --no-source` | |
s.scan(/^ *(?=[.0]*[1-9])([ .0-9]*) :\s*(\h+)/) do |pct, addr| | |
h = (addrs[addr.hex] ||= {}) | |
h[:pct] = pct.to_f | |
end | |
/\A0*(\h+)[ .a-z]*\t0*(\h+)/i =~ `objdump -t miniruby|grep vm_exec_core` | |
#puts"0x#{$1}..#{"%#x"%[$1.hex+$2.hex]}" | |
from = $1.hex | |
to = from + $2.hex | |
`readelf --debug-dump=decodedline miniruby`. | |
scan(/^([a-z_.]+)\s+(\d+)\s+0x(\h+)/) do |fn, no, a| | |
addr = a.hex | |
next if addr < from | |
break if addr > to | |
lineno = no.to_i | |
h = (addrs[addr] ||= {}) | |
h[:filename] = fn | |
h[:lineno] = lineno | |
insn = find_insn(files, fn, lineno) | |
h[:insn] = insn if insn | |
end | |
pcts = {} | |
current = "" | |
addrs.each_pair do |addr, h| | |
insn = h[:insn] | |
current = insn if insn | |
next unless pct = h[:pct] | |
pcts[current] ||= 0.0 | |
pcts[current] += pct | |
end | |
pcts.sort_by(&:last).reverse_each do |key, pct| | |
puts "%20s: %5.2f" % [key, pct] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment