Permalink
Browse files

Cleanup old profiler cruft and fix json output

  • Loading branch information...
Evan Phoenix
Evan Phoenix committed Apr 2, 2011
1 parent e8d726b commit 4aa76a471aa4ac9a5b2a70d7e7a40713ee9ac77b
Showing with 12 additions and 157 deletions.
  1. +12 −157 lib/tooling/profiler/profiler.rb
@@ -207,7 +207,11 @@ def thread_flat(out, t_id, info)
def json(path)
File.open path, "w" do |f|
t_final = @info.size - 1
t_idx = 0
f.puts "["
@info.each do |t_id, info|
f.puts "{"
f.puts " \"thread_id\": #{t_id},"
@@ -249,7 +253,14 @@ def json(path)
end
f.puts " }"
f.puts "}"
if t_idx == t_final
f.puts "}"
else
f.puts "},"
end
t_idx += 1
end
f.puts "]"
end
@@ -405,161 +416,5 @@ def sort_order
Array(@options[:sort]).map { |header| HEADER_INDEX[header].to_i }
end
end
##
# Interface to VM's sampling profiler.
#
# @todo needs to be implemented in the VM.
class Sampler
def initialize(freq=nil)
@frequency = freq
@frequency ||= ENV['PROFILE_FREQ'].to_i
@frequency = 100 if @frequency == 0
@call_graph = ENV['PROFILE_FULL']
end
def activate(hz)
Ruby.primitive :sampler_activate
raise PrimitiveFailure, "primitive failed"
end
def terminate
Ruby.primitive :sampler_stop
raise PrimitiveFailure, "primitive failed"
end
def start
@start_clock = activate(@frequency)
nil
end
def stop
@results, @last_clock, @gc_cycles = terminate()
nil
end
##
# Records call information.
class Call
attr_accessor :slices
attr_accessor :descendants_slices
attr_accessor :name
attr_accessor :parents
attr_accessor :children
def initialize(name)
@name = name
@slices = 0
@descendants_slices = 0
@parents = Hash.new { |h,k| h[k] = 0 }
@children = Hash.new { |h,k| h[k] = 0 }
end
def total_slices
@slices + @descendants_slices
end
def count_parent(call)
if call
@parents[call] += 1
call.children[self] += 1
end
end
end
def display(out=$stdout)
@total_slices = 0
@calls = Hash.new { |h,k| h[k] = Call.new(k) }
@results.each do |ent|
next unless ent
@total_slices += 1
call = find_call(ent)
call.slices += 1
# skip context unwinding for a primitive
next if ent.kind_of? Fixnum
if @call_graph
# count parents and children
call.count_parent(find_call(ent.sender))
# calc descendants
seen_calls = { call => 1 }
while true
ent = ent.sender
break unless ent
c = find_call(ent)
# unwind to the root, but count each call only once
unless seen_calls[c]
seen_calls[c] = 1
c.descendants_slices += 1
end
end
end
end
@calls["VM.garbage_collection"].slices = @gc_cycles
out << "Total slices: #{@total_slices}, #{@last_clock - @start_clock} clocks\n\n"
out << "=== FLAT PROFILE ===\n\n"
out << " % time slices name\n"
@calls.sort { |a, b| b[1].slices <=> a[1].slices }.each do |name, call|
out.printf " %6.2f %8d %s\n", percent(call.slices), call.slices, name
end
if @call_graph
out << "\n=== CALL GRAPH ===\n\n"
out << " % time slices % self slices name\n"
@calls.sort { |a, b| b[1].total_slices <=> a[1].total_slices }.each do |name, call|
print_relatives(out, call.parents.sort { |a,b| a[1] <=> b[1] })
out.printf " %6.2f %8d %6.2f %8d %s\n",
percent(call.total_slices), call.total_slices,
percent(call.slices), call.slices,
name
print_relatives(out, call.children.sort { |a,b| b[1] <=> a[1] })
out << "----------------------------------------------------------------------\n"
end
end
nil
end
def context_name(entry)
# a Fixnum means that a primitive was running
if entry.kind_of? Fixnum
"VM.primitive => #{Primitives[entry]}"
else
entry.normalized_name
end
end
def find_call(entry)
@calls[context_name(entry)]
end
def percent(slices)
100.0 * slices / @total_slices
end
def print_relatives(out, rels)
rels[0,5].each do |rel|
out << " #{rel[0].name} (#{rel[1]})\n"
end
end
end
end
end

0 comments on commit 4aa76a4

Please sign in to comment.