Class: RubyProf::CallInfo
- Inherits:
-
Object
- Object
- RubyProf::CallInfo
- Defined in:
- ext/ruby_prof/rp_call_info.c,
lib/ruby-prof/call_info.rb,
ext/ruby_prof/rp_call_info.c
Overview
RubyProf::CallInfo is a helper class used by RubyProf::MethodInfo to keep track of which child methods were called and how long they took to execute.
Instance Attribute Summary collapse
-
#recursive ⇒ Object
readonly
part of this class is defined in C code.
Class Method Summary collapse
Instance Method Summary collapse
-
#add_self_time(call_info) ⇒ nil
adds self time from call_info to self.
-
#add_total_time(call_info) ⇒ nil
adds total time time from call_info to self.
-
#add_wait_time(call_info) ⇒ nil
adds wait time from call_info to self.
- #call_sequence ⇒ Object
-
#called ⇒ Integer
Returns the total amount of times this method was called.
-
#called= ⇒ Object
Sets the call count to n.
-
#children ⇒ Hash
Returns an array of call info objects of methods that this method called (ie, children).
- #children_time ⇒ Object
-
#depth ⇒ Integer
returns the depth of this call info in the call graph.
- #descendent_of(other) ⇒ Object
- #detect_recursion(visited_methods = Hash.new(0)) ⇒ Object
-
#eliminate! ⇒ Object
eliminate call info from the call tree.
-
#find_call(other) ⇒ Object
find a specific call in list of children.
- #inspect ⇒ Object
-
#line_no ⇒ Integer
returns the line number of the method.
-
#merge_call_tree(other) ⇒ Object
merge two call trees.
-
#parent ⇒ Object
Returns the call_infos parent call_info object (the method that called this method).
-
#parent= ⇒ Object
Changes the parent of self to new_parent and returns it.
- #root? ⇒ Boolean
-
#self_time ⇒ Float
Returns the total amount of time spent in this method.
- #stack ⇒ Object
-
#called ⇒ MethodInfo
Returns the target method.
- #to_s ⇒ Object
-
#total_time ⇒ Float
Returns the total amount of time spent in this method and its children.
-
#wait_time ⇒ Float
Returns the total amount of time this method waited for other threads.
Instance Attribute Details
#recursive ⇒ Object (readonly)
part of this class is defined in C code. it provides the following attributes pertaining to tree structure: depth: tree level (0 == root) parent: parent call info (can be nil) children: array of call info children (can be empty) target: method info (containing an array of call infos)
12 13 14 |
# File 'lib/ruby-prof/call_info.rb', line 12 def recursive @recursive end |
Class Method Details
.roots_of(call_infos) ⇒ Object
60 61 62 63 64 65 66 67 |
# File 'lib/ruby-prof/call_info.rb', line 60 def self.roots_of(call_infos) roots = [] sorted = call_infos.sort_by(&:depth).reverse while call_info = sorted.shift roots << call_info unless sorted.any?{|p| call_info.descendent_of(p)} end roots end |
Instance Method Details
#add_self_time(call_info) ⇒ nil
adds self time from call_info to self.
228 229 230 231 232 233 234 235 236 |
# File 'ext/ruby_prof/rp_call_info.c', line 228 static VALUE prof_call_info_add_self_time(VALUE self, VALUE other) { prof_call_info_t *result = prof_get_call_info(self); prof_call_info_t *other_info = prof_get_call_info(other); result->self_time += other_info->self_time; return Qnil; } |
#add_total_time(call_info) ⇒ nil
adds total time time from call_info to self.
202 203 204 205 206 207 208 209 210 |
# File 'ext/ruby_prof/rp_call_info.c', line 202 static VALUE prof_call_info_add_total_time(VALUE self, VALUE other) { prof_call_info_t *result = prof_get_call_info(self); prof_call_info_t *other_info = prof_get_call_info(other); result->total_time += other_info->total_time; return Qnil; } |
#add_wait_time(call_info) ⇒ nil
adds wait time from call_info to self.
255 256 257 258 259 260 261 262 263 |
# File 'ext/ruby_prof/rp_call_info.c', line 255 static VALUE prof_call_info_add_wait_time(VALUE self, VALUE other) { prof_call_info_t *result = prof_get_call_info(self); prof_call_info_t *other_info = prof_get_call_info(other); result->wait_time += other_info->wait_time; return Qnil; } |
#call_sequence ⇒ Object
42 43 44 45 46 |
# File 'lib/ruby-prof/call_info.rb', line 42 def call_sequence @call_sequence ||= begin stack.map {|method| method.full_name}.join('->') end end |
#called ⇒ Integer
Returns the total amount of times this method was called.
146 147 148 149 150 151 |
# File 'ext/ruby_prof/rp_call_info.c', line 146 static VALUE prof_call_info_called(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); return INT2NUM(result->called); } |
#called= ⇒ Object
Sets the call count to n.
157 158 159 160 161 162 163 |
# File 'ext/ruby_prof/rp_call_info.c', line 157 static VALUE prof_call_info_set_called(VALUE self, VALUE called) { prof_call_info_t *result = prof_get_call_info(self); result->called = NUM2INT(called); return called; } |
#children ⇒ Hash
Returns an array of call info objects of methods that this method called (ie, children).
308 309 310 311 312 313 314 315 316 317 318 |
# File 'ext/ruby_prof/rp_call_info.c', line 308 static VALUE prof_call_info_children(VALUE self) { prof_call_info_t *call_info = prof_get_call_info(self); if (call_info->children == Qnil) { call_info->children = rb_ary_new(); st_foreach(call_info->call_infos, prof_call_info_collect_children, call_info->children); } return call_info->children; } |
#children_time ⇒ Object
23 24 25 26 27 |
# File 'lib/ruby-prof/call_info.rb', line 23 def children_time children.inject(0) do |sum, call_info| sum += call_info.total_time end end |
#depth ⇒ Integer
returns the depth of this call info in the call graph
169 170 171 172 173 174 |
# File 'ext/ruby_prof/rp_call_info.c', line 169 static VALUE prof_call_info_depth(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); return rb_int_new(result->depth); } |
#descendent_of(other) ⇒ Object
52 53 54 55 56 57 58 |
# File 'lib/ruby-prof/call_info.rb', line 52 def descendent_of(other) p = self.parent while p && p != other && p.depth > other.depth p = p.parent end p == other end |
#detect_recursion(visited_methods = Hash.new(0)) ⇒ Object
14 15 16 17 18 19 20 21 |
# File 'lib/ruby-prof/call_info.rb', line 14 def detect_recursion(visited_methods = Hash.new(0)) @recursive = (visited_methods[target] += 1) > 1 children.each do |child| child.detect_recursion(visited_methods) end visited_methods.delete(target) if (visited_methods[target] -= 1) == 0 return @recursive end |
#eliminate! ⇒ Object
eliminate call info from the call tree. adds self and wait time to parent and attaches called methods to parent. merges call trees for methods called from both praent end self.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/ruby-prof/call_info.rb', line 80 def eliminate! # puts "eliminating #{self}" return unless parent parent.add_self_time(self) parent.add_wait_time(self) children.each do |kid| if call = parent.find_call(kid) call.merge_call_tree(kid) else parent.children << kid # $stderr.puts "setting parent of #{kid}\nto #{parent}" kid.parent = parent end end parent.children.delete(self) end |
#find_call(other) ⇒ Object
find a specific call in list of children. returns nil if not found. note: there can’t be more than one child with a given target method. in other words: x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
100 101 102 103 104 |
# File 'lib/ruby-prof/call_info.rb', line 100 def find_call(other) matching = children.select { |kid| kid.target == other.target } raise "inconsistent call tree" unless matching.size <= 1 matching.first end |
#inspect ⇒ Object
73 74 75 |
# File 'lib/ruby-prof/call_info.rb', line 73 def inspect super + "(#{target.full_name}, d: #{depth}, c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})" end |
#line_no ⇒ Integer
returns the line number of the method
180 181 182 183 184 185 |
# File 'ext/ruby_prof/rp_call_info.c', line 180 static VALUE prof_call_info_line(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); return rb_int_new(result->line); } |
#merge_call_tree(other) ⇒ Object
merge two call trees. adds self, wait, and total time of other to self and merges children of other into children of self.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/ruby-prof/call_info.rb', line 107 def merge_call_tree(other) # $stderr.puts "merging #{self}\nand #{other}" self.called += other.called add_self_time(other) add_wait_time(other) add_total_time(other) other.children.each do |other_kid| if kid = find_call(other_kid) # $stderr.puts "merging kids" kid.merge_call_tree(other_kid) else other_kid.parent = self children << other_kid end end other.children.clear other.target.call_infos.delete(other) end |
#parent ⇒ Object
Returns the call_infos parent call_info object (the method that called this method).
269 270 271 272 273 274 275 276 277 |
# File 'ext/ruby_prof/rp_call_info.c', line 269 static VALUE prof_call_info_parent(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); if (result->parent) return prof_call_info_wrap(result->parent); else return Qnil; } |
#parent= ⇒ Object
Changes the parent of self to new_parent and returns it.
283 284 285 286 287 288 289 290 291 292 |
# File 'ext/ruby_prof/rp_call_info.c', line 283 static VALUE prof_call_info_set_parent(VALUE self, VALUE new_parent) { prof_call_info_t *result = prof_get_call_info(self); if (new_parent == Qnil) result->parent = NULL; else result->parent = prof_get_call_info(new_parent); return prof_call_info_parent(self); } |
#root? ⇒ Boolean
48 49 50 |
# File 'lib/ruby-prof/call_info.rb', line 48 def root? self.parent.nil? end |
#self_time ⇒ Float
Returns the total amount of time spent in this method.
216 217 218 219 220 221 222 |
# File 'ext/ruby_prof/rp_call_info.c', line 216 static VALUE prof_call_info_self_time(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); return rb_float_new(result->self_time); } |
#stack ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/ruby-prof/call_info.rb', line 29 def stack @stack ||= begin methods = Array.new call_info = self while call_info methods << call_info.target call_info = call_info.parent end methods.reverse end end |
#called ⇒ MethodInfo
Returns the target method.
131 132 133 134 135 136 137 138 139 140 |
# File 'ext/ruby_prof/rp_call_info.c', line 131 static VALUE prof_call_info_target(VALUE self) { /* Target is a pointer to a method_info - so we have to be careful about the GC. We will wrap the method_info but provide no free method so the underlying object is not freed twice! */ prof_call_info_t *result = prof_get_call_info(self); return prof_method_wrap(result->target); } |
#to_s ⇒ Object
69 70 71 |
# File 'lib/ruby-prof/call_info.rb', line 69 def to_s "#{target.full_name} (c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})" end |
#total_time ⇒ Float
Returns the total amount of time spent in this method and its children.
191 192 193 194 195 196 |
# File 'ext/ruby_prof/rp_call_info.c', line 191 static VALUE prof_call_info_total_time(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); return rb_float_new(result->total_time); } |
#wait_time ⇒ Float
Returns the total amount of time this method waited for other threads.
242 243 244 245 246 247 248 |
# File 'ext/ruby_prof/rp_call_info.c', line 242 static VALUE prof_call_info_wait_time(VALUE self) { prof_call_info_t *result = prof_get_call_info(self); return rb_float_new(result->wait_time); } |