ruby-prof 0.8.1-x86-mingw32 → 0.11.0.rc1-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. data/CHANGES +89 -13
  2. data/LICENSE +4 -3
  3. data/{README → README.rdoc} +155 -162
  4. data/Rakefile +50 -123
  5. data/bin/ruby-prof +86 -47
  6. data/examples/empty.png +0 -0
  7. data/examples/graph.dot +106 -0
  8. data/examples/graph.png +0 -0
  9. data/examples/minus.png +0 -0
  10. data/examples/multi.flat.txt +23 -0
  11. data/examples/multi.graph.html +906 -0
  12. data/examples/multi.grind.dat +194 -0
  13. data/examples/multi.stack.html +573 -0
  14. data/examples/plus.png +0 -0
  15. data/examples/stack.html +573 -0
  16. data/ext/ruby_prof/extconf.rb +53 -0
  17. data/ext/ruby_prof/rp_call_info.c +369 -0
  18. data/ext/ruby_prof/rp_call_info.h +46 -0
  19. data/ext/ruby_prof/rp_measure.c +48 -0
  20. data/ext/ruby_prof/rp_measure.h +45 -0
  21. data/ext/ruby_prof/rp_measure_allocations.c +86 -0
  22. data/ext/ruby_prof/rp_measure_cpu_time.c +112 -0
  23. data/ext/ruby_prof/rp_measure_gc_runs.c +87 -0
  24. data/ext/ruby_prof/rp_measure_gc_time.c +73 -0
  25. data/ext/ruby_prof/rp_measure_memory.c +81 -0
  26. data/ext/ruby_prof/rp_measure_process_time.c +71 -0
  27. data/ext/ruby_prof/rp_measure_wall_time.c +42 -0
  28. data/ext/ruby_prof/rp_method.c +363 -0
  29. data/ext/ruby_prof/rp_method.h +55 -0
  30. data/ext/ruby_prof/rp_stack.c +61 -0
  31. data/ext/ruby_prof/rp_stack.h +40 -0
  32. data/ext/ruby_prof/rp_thread.c +113 -0
  33. data/ext/ruby_prof/rp_thread.h +20 -0
  34. data/ext/ruby_prof/ruby_prof.c +332 -1377
  35. data/ext/ruby_prof/ruby_prof.h +54 -188
  36. data/ext/ruby_prof/version.h +6 -3
  37. data/lib/1.8/ruby_prof.so +0 -0
  38. data/lib/1.9/ruby_prof.exp +0 -0
  39. data/lib/1.9/ruby_prof.ilk +0 -0
  40. data/lib/1.9/ruby_prof.lib +0 -0
  41. data/lib/1.9/ruby_prof.pdb +0 -0
  42. data/lib/1.9/ruby_prof.so +0 -0
  43. data/lib/ruby-prof.rb +32 -18
  44. data/lib/ruby-prof/abstract_printer.rb +15 -5
  45. data/lib/ruby-prof/aggregate_call_info.rb +11 -3
  46. data/lib/ruby-prof/call_info.rb +68 -1
  47. data/lib/ruby-prof/call_stack_printer.rb +775 -0
  48. data/lib/ruby-prof/call_tree_printer.rb +17 -9
  49. data/lib/ruby-prof/compatibility.rb +134 -0
  50. data/lib/ruby-prof/dot_printer.rb +152 -0
  51. data/lib/ruby-prof/empty.png +0 -0
  52. data/lib/ruby-prof/flat_printer.rb +23 -24
  53. data/lib/ruby-prof/flat_printer_with_line_numbers.rb +17 -21
  54. data/lib/ruby-prof/graph_html_printer.rb +69 -39
  55. data/lib/ruby-prof/graph_printer.rb +35 -35
  56. data/lib/ruby-prof/method_info.rb +26 -4
  57. data/lib/ruby-prof/minus.png +0 -0
  58. data/lib/ruby-prof/multi_printer.rb +56 -0
  59. data/lib/ruby-prof/plus.png +0 -0
  60. data/lib/ruby-prof/profile.rb +72 -0
  61. data/lib/ruby-prof/rack.rb +31 -0
  62. data/lib/ruby-prof/symbol_to_proc.rb +3 -1
  63. data/lib/ruby-prof/task.rb +20 -19
  64. data/lib/ruby-prof/test.rb +5 -3
  65. data/lib/ruby_prof.exp +0 -0
  66. data/lib/ruby_prof.ilk +0 -0
  67. data/lib/ruby_prof.lib +0 -0
  68. data/lib/ruby_prof.pdb +0 -0
  69. data/lib/ruby_prof.so +0 -0
  70. data/lib/unprof.rb +2 -0
  71. data/test/aggregate_test.rb +29 -14
  72. data/test/basic_test.rb +3 -251
  73. data/test/bug_test.rb +6 -0
  74. data/test/duplicate_names_test.rb +4 -4
  75. data/test/dynamic_method_test.rb +61 -0
  76. data/test/enumerable_test.rb +4 -4
  77. data/test/exceptions_test.rb +6 -5
  78. data/test/exclude_threads_test.rb +47 -47
  79. data/test/exec_test.rb +5 -5
  80. data/test/line_number_test.rb +16 -16
  81. data/test/measure_allocations_test.rb +25 -0
  82. data/test/measure_cpu_time_test.rb +212 -0
  83. data/test/measure_gc_runs_test.rb +29 -0
  84. data/test/measure_gc_time_test.rb +29 -0
  85. data/test/measure_memory_test.rb +36 -0
  86. data/test/measure_process_time_test.rb +205 -0
  87. data/test/measure_wall_time_test.rb +209 -0
  88. data/test/method_elimination_test.rb +74 -0
  89. data/test/module_test.rb +12 -21
  90. data/test/multi_printer_test.rb +81 -0
  91. data/test/no_method_class_test.rb +5 -3
  92. data/test/prime.rb +7 -10
  93. data/test/prime_test.rb +3 -3
  94. data/test/printers_test.rb +180 -54
  95. data/test/recursive_test.rb +34 -72
  96. data/test/singleton_test.rb +5 -4
  97. data/test/stack_printer_test.rb +73 -0
  98. data/test/stack_test.rb +7 -7
  99. data/test/start_stop_test.rb +23 -6
  100. data/test/test_helper.rb +81 -0
  101. data/test/test_suite.rb +35 -21
  102. data/test/thread_test.rb +40 -39
  103. data/test/unique_call_path_test.rb +6 -6
  104. metadata +106 -51
  105. data/ext/ruby_prof/measure_allocations.h +0 -58
  106. data/ext/ruby_prof/measure_cpu_time.h +0 -152
  107. data/ext/ruby_prof/measure_gc_runs.h +0 -76
  108. data/ext/ruby_prof/measure_gc_time.h +0 -57
  109. data/ext/ruby_prof/measure_memory.h +0 -101
  110. data/ext/ruby_prof/measure_process_time.h +0 -52
  111. data/ext/ruby_prof/measure_wall_time.h +0 -53
  112. data/ext/ruby_prof/mingw/Rakefile +0 -23
  113. data/ext/ruby_prof/mingw/build.rake +0 -38
  114. data/rails/environment/profile.rb +0 -24
  115. data/rails/example/example_test.rb +0 -9
  116. data/rails/profile_test_helper.rb +0 -21
  117. data/test/current_failures_windows +0 -8
  118. data/test/measurement_test.rb +0 -121
  119. data/test/ruby-prof-bin +0 -20
@@ -1,188 +1,54 @@
1
- /*
2
- * Copyright (C) 2008 Shugo Maeda <shugo@ruby-lang.org>
3
- * Charlie Savage <cfis@savagexi.com>
4
- * All rights reserved.
5
- *
6
- * Redistribution and use in source and binary forms, with or without
7
- * modification, are permitted provided that the following conditions
8
- * are met:
9
- * 1. Redistributions of source code must retain the above copyright
10
- * notice, this list of conditions and the following disclaimer.
11
- * 2. Redistributions in binary form must reproduce the above copyright
12
- * notice, this list of conditions and the following disclaimer in the
13
- * documentation and/or other materials provided with the distribution.
14
- *
15
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
16
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
19
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
- * SUCH DAMAGE.
26
- */
27
-
28
- /* ruby-prof tracks the time spent executing every method in ruby programming.
29
- The main players are:
30
-
31
- prof_result_t - Its one field, values, contains the overall results
32
- thread_data_t - Stores data about a single thread.
33
- prof_stack_t - The method call stack in a particular thread
34
- prof_method_t - Profiling information for each method
35
- prof_call_info_t - Keeps track a method's callers and callees.
36
-
37
- The final resulut is a hash table of thread_data_t, keyed on the thread
38
- id. Each thread has an hash a table of prof_method_t, keyed on the
39
- method id. A hash table is used for quick look up when doing a profile.
40
- However, it is exposed to Ruby as an array.
41
-
42
- Each prof_method_t has two hash tables, parent and children, of prof_call_info_t.
43
- These objects keep track of a method's callers (who called the method) and its
44
- callees (who the method called). These are keyed the method id, but once again,
45
- are exposed to Ruby as arrays. Each prof_call_into_t maintains a pointer to the
46
- caller or callee method, thereby making it easy to navigate through the call
47
- hierarchy in ruby - which is very helpful for creating call graphs.
48
- */
49
-
50
- /* #define DEBUG */
51
-
52
- #ifndef RUBY_PROF_H
53
- #define RUBY_PROF_H
54
-
55
- #include <stdio.h>
56
-
57
- #include <ruby.h>
58
-
59
- #ifndef RUBY_VM
60
- #include <node.h>
61
- #include <st.h>
62
- typedef rb_event_t rb_event_flag_t;
63
- #define rb_sourcefile() (node ? node->nd_file : 0)
64
- #define rb_sourceline() (node ? nd_line(node) : 0)
65
- #endif
66
-
67
- #include "version.h"
68
-
69
- /* ================ Constants =================*/
70
- #define INITIAL_STACK_SIZE 8
71
- #define INITIAL_CALL_INFOS_SIZE 2
72
-
73
-
74
- /* ================ Measurement =================*/
75
- #ifdef HAVE_LONG_LONG
76
- typedef unsigned LONG_LONG prof_measure_t; // long long is 8 bytes on 32-bit
77
- #else
78
- typedef unsigned long prof_measure_t;
79
- #endif
80
-
81
- #include "measure_process_time.h"
82
- #include "measure_wall_time.h"
83
- #include "measure_cpu_time.h"
84
- #include "measure_allocations.h"
85
- #include "measure_memory.h"
86
- #include "measure_gc_runs.h"
87
- #include "measure_gc_time.h"
88
-
89
- static prof_measure_t (*get_measurement)() = measure_process_time;
90
- static double (*convert_measurement)(prof_measure_t) = convert_process_time;
91
-
92
- /* ================ DataTypes =================*/
93
- static VALUE mProf;
94
- static VALUE cResult;
95
- static VALUE cMethodInfo;
96
- static VALUE cCallInfo;
97
-
98
- /* Profiling information for each method. */
99
- typedef struct {
100
- VALUE klass; /* The method's class. */
101
- ID mid; /* The method id. */
102
- int depth; /* The recursion depth. */
103
- int key; /* Cache calculated key */
104
- } prof_method_key_t;
105
-
106
- struct prof_call_infos_t;
107
-
108
- /* Profiling information for each method. */
109
- typedef struct {
110
- prof_method_key_t *key; /* Method key */
111
- const char *source_file; /* The method's source file */
112
- int line; /* The method's line number. */
113
- int active; /* Is this recursion depth. */
114
- struct prof_call_infos_t *call_infos; /* Call info objects for this method */
115
- VALUE object; /* Cahced ruby object */
116
- } prof_method_t;
117
-
118
- /* Callers and callee information for a method. */
119
- typedef struct prof_call_info_t {
120
- prof_method_t *target; /* Use target instead of method to avoid conflict with Ruby method */
121
- struct prof_call_info_t *parent;
122
- st_table *call_infos;
123
- int called;
124
- prof_measure_t total_time;
125
- prof_measure_t self_time;
126
- prof_measure_t wait_time;
127
- int line;
128
- VALUE object;
129
- VALUE children;
130
- } prof_call_info_t;
131
-
132
- /* Array of call_info objects */
133
- typedef struct prof_call_infos_t {
134
- prof_call_info_t **start;
135
- prof_call_info_t **end;
136
- prof_call_info_t **ptr;
137
- VALUE object;
138
- } prof_call_infos_t;
139
-
140
-
141
- /* Temporary object that maintains profiling information
142
- for active methods - there is one per method.*/
143
- typedef struct {
144
- /* Caching prof_method_t values significantly
145
- increases performance. */
146
- prof_call_info_t *call_info;
147
- prof_measure_t start_time;
148
- prof_measure_t wait_time;
149
- prof_measure_t child_time;
150
- unsigned int line;
151
- } prof_frame_t;
152
-
153
- /* Current stack of active methods.*/
154
- typedef struct {
155
- prof_frame_t *start;
156
- prof_frame_t *end;
157
- prof_frame_t *ptr;
158
- } prof_stack_t;
159
-
160
- /* Profiling information for a thread. */
161
- typedef struct {
162
- VALUE thread_id; /* Thread id */
163
- st_table* method_table; /* Methods called in the thread */
164
- prof_stack_t* stack; /* Active methods */
165
- prof_measure_t last_switch; /* Point of last context switch */
166
- } thread_data_t;
167
-
168
- typedef struct {
169
- VALUE threads;
170
- } prof_result_t;
171
-
172
-
173
- /* ================ Variables =================*/
174
- static int measure_mode;
175
- static st_table *threads_tbl = NULL;
176
- static st_table *exclude_threads_tbl = NULL;
177
-
178
- /* TODO - If Ruby become multi-threaded this has to turn into
179
- a separate stack since this isn't thread safe! */
180
- static thread_data_t* last_thread_data = NULL;
181
-
182
-
183
- /* Forward declarations */
184
- static VALUE prof_call_infos_wrap(prof_call_infos_t *call_infos);
185
- static VALUE prof_call_info_wrap(prof_call_info_t *call_info);
186
- static VALUE prof_method_wrap(prof_method_t *result);
187
-
188
- #endif
1
+ /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #ifndef __RUBY_PROF_H__
5
+ #define __RUBY_PROF_H__
6
+
7
+ #include <stdio.h>
8
+ #include <ruby.h>
9
+
10
+ #if RUBY_VERSION == 186
11
+ # error 1.8.6 is not supported. Please upgrade to 1.8.7 or 1.9.2 or higher.
12
+ #endif
13
+
14
+ #if RUBY_VERSION == 190
15
+ # error 1.9.0 is not supported. Please upgrade to 1.9.2 or higher.
16
+ #endif
17
+
18
+ #if RUBY_VERSION == 191
19
+ # error 1.9.1 is not supported. Please upgrade to 1.9.2 or higher.
20
+ #endif
21
+
22
+ #ifndef RUBY_VM
23
+ #include <node.h>
24
+ typedef rb_event_t rb_event_flag_t;
25
+ #define rb_sourcefile() (node ? node->nd_file : 0)
26
+ #define rb_sourceline() (node ? nd_line(node) : 0)
27
+ #endif
28
+
29
+ #include "version.h"
30
+
31
+ #include "rp_measure.h"
32
+ #include "rp_method.h"
33
+ #include "rp_call_info.h"
34
+ #include "rp_stack.h"
35
+ #include "rp_thread.h"
36
+
37
+ extern VALUE mProf;
38
+ extern VALUE cProfile;
39
+
40
+ void method_key(prof_method_key_t* key, VALUE klass, ID mid);
41
+
42
+ typedef struct
43
+ {
44
+ VALUE running;
45
+ prof_measurer_t* measurer;
46
+ double measurement;
47
+ VALUE threads;
48
+ st_table* threads_tbl;
49
+ st_table* exclude_threads_tbl;
50
+ thread_data_t* last_thread_data;
51
+ } prof_profile_t;
52
+
53
+
54
+ #endif //__RUBY_PROF_H__
@@ -1,4 +1,7 @@
1
- #define RUBY_PROF_VERSION "0.8.1"
1
+ /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #define RUBY_PROF_VERSION "0.11.0" // for easy parsing from rake files
2
5
  #define RUBY_PROF_VERSION_MAJ 0
3
- #define RUBY_PROF_VERSION_MIN 8
4
- #define RUBY_PROF_VERSION_MIC 1
6
+ #define RUBY_PROF_VERSION_MIN 11
7
+ #define RUBY_PROF_VERSION_MIC 0
data/lib/1.8/ruby_prof.so CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/1.9/ruby_prof.so CHANGED
Binary file
data/lib/ruby-prof.rb CHANGED
@@ -1,25 +1,38 @@
1
- # require the .so file
2
- me = File.dirname(__FILE__) + '/'
1
+ # encoding: utf-8
2
+
3
+ # Load the C-based binding.
3
4
  begin
4
- # fat binaries
5
- require "#{me}/#{RUBY_VERSION[0..2]}/ruby_prof"
6
- rescue Exception
7
- require "#{me}/../ext/ruby_prof/ruby_prof"
5
+ RUBY_VERSION =~ /(\d+.\d+)/
6
+ require "#{$1}/ruby_prof"
7
+ rescue LoadError
8
+ require "ruby_prof"
8
9
  end
9
10
 
10
- require "ruby-prof/method_info"
11
- require "ruby-prof/call_info"
12
- require "ruby-prof/aggregate_call_info"
13
- require "ruby-prof/flat_printer"
14
- require "ruby-prof/flat_printer_with_line_numbers"
15
- require "ruby-prof/graph_printer"
16
- require "ruby-prof/graph_html_printer"
17
- require "ruby-prof/call_tree_printer"
18
- require "ruby-prof/symbol_to_proc" # for 1.8's benefit
19
- #require "ruby-prof/result"
20
11
 
21
12
  module RubyProf
22
- # See if the user specified the clock mode via
13
+ def self.camelcase(phrase)
14
+ ('_' + phrase).gsub(/_([a-z])/){|b| b[1..1].upcase}
15
+ end
16
+
17
+ lib_dir = File.dirname(__FILE__) + '/ruby-prof/'
18
+
19
+ for file in ['abstract_printer', 'aggregate_call_info', 'flat_printer', 'flat_printer_with_line_numbers',
20
+ 'graph_printer', 'graph_html_printer', 'call_tree_printer', 'call_stack_printer', 'multi_printer', 'dot_printer']
21
+ autoload camelcase(file), lib_dir + file
22
+ end
23
+
24
+ # A few need to be loaded manually their classes were already defined by the .so file so autoload won't work for them.
25
+ # plus we need them anyway
26
+ for name in ['profile', 'method_info', 'call_info']
27
+ require lib_dir + name
28
+ end
29
+
30
+ # Compatability layer for suporting old api
31
+ require lib_dir + 'compatibility'
32
+
33
+ # we don't require unprof.rb, as well, purposefully
34
+
35
+ # Checks if the user specified the clock mode via
23
36
  # the RUBY_PROF_MEASURE_MODE environment variable
24
37
  def self.figure_measure_mode
25
38
  case ENV["RUBY_PROF_MEASURE_MODE"]
@@ -48,9 +61,10 @@ module RubyProf
48
61
  when "memory"
49
62
  RubyProf.measure_mode = RubyProf::MEMORY
50
63
  else
64
+ # the default...
51
65
  RubyProf.measure_mode = RubyProf::PROCESS_TIME
52
66
  end
53
67
  end
54
68
  end
55
69
 
56
- RubyProf::figure_measure_mode
70
+ RubyProf::figure_measure_mode
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module RubyProf
2
4
  class AbstractPrinter
3
5
  def initialize(result)
@@ -7,7 +9,7 @@ module RubyProf
7
9
  end
8
10
 
9
11
  # Specify print options.
10
- #
12
+ #
11
13
  # options - Hash table
12
14
  # :min_percent - Number 0 to 100 that specifes the minimum
13
15
  # %self (the methods self time divided by the
@@ -18,18 +20,26 @@ module RubyProf
18
20
  # :print_file - True or false. Specifies if a method's source
19
21
  # file should be printed. Default value if false.
20
22
  #
23
+ # :sort_method - Specifies method used for sorting method infos.
24
+ # Available values are :total_time, :self_time,
25
+ # :wait_time, :children_time
26
+ # Default value is :total_time
21
27
  def setup_options(options = {})
22
28
  @options = options
23
- end
29
+ end
24
30
 
25
31
  def min_percent
26
32
  @options[:min_percent] || 0
27
33
  end
28
-
34
+
29
35
  def print_file
30
36
  @options[:print_file] || false
31
37
  end
32
-
38
+
39
+ def sort_method
40
+ @options[:sort_method] || :total_time
41
+ end
42
+
33
43
  def method_name(method)
34
44
  name = method.full_name
35
45
  if print_file
@@ -38,4 +48,4 @@ module RubyProf
38
48
  name
39
49
  end
40
50
  end
41
- end
51
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module RubyProf
2
4
  class AggregateCallInfo
3
5
  attr_reader :call_infos
@@ -27,7 +29,7 @@ module RubyProf
27
29
  end
28
30
 
29
31
  def total_time
30
- aggregate(:total_time)
32
+ aggregate_minimal(:total_time)
31
33
  end
32
34
 
33
35
  def self_time
@@ -39,7 +41,7 @@ module RubyProf
39
41
  end
40
42
 
41
43
  def children_time
42
- aggregate(:children_time)
44
+ aggregate_minimal(:children_time)
43
45
  end
44
46
 
45
47
  def called
@@ -55,8 +57,14 @@ module RubyProf
55
57
  def aggregate(method_name)
56
58
  self.call_infos.inject(0) do |sum, call_info|
57
59
  sum += call_info.send(method_name)
60
+ end
61
+ end
62
+
63
+ def aggregate_minimal(method_name)
64
+ self.call_infos.inject(0) do |sum, call_info|
65
+ sum += call_info.send(method_name) if call_info.minimal?
58
66
  sum
59
67
  end
60
68
  end
61
69
  end
62
- end
70
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module RubyProf
2
4
  class CallInfo
3
5
  def depth
@@ -43,5 +45,70 @@ module RubyProf
43
45
  def to_s
44
46
  "#{call_sequence}"
45
47
  end
48
+
49
+ def minimal?
50
+ @minimal
51
+ end
52
+
53
+ def compute_minimality(parent_methods)
54
+ if parent_methods.include?(target)
55
+ @minimal = false
56
+ else
57
+ @minimal = true
58
+ parent_methods << target unless children.empty?
59
+ end
60
+ children.each {|ci| ci.compute_minimality(parent_methods)}
61
+ parent_methods.delete(target) if @minimal && !children.empty?
62
+ end
63
+
64
+ # eliminate call info from the call tree.
65
+ # adds self and wait time to parent and attaches called methods to parent.
66
+ # merges call trees for methods called from both praent end self.
67
+ def eliminate!
68
+ # puts "eliminating #{self}"
69
+ return unless parent
70
+ parent.add_self_time(self)
71
+ parent.add_wait_time(self)
72
+ children.each do |kid|
73
+ if call = parent.find_call(kid)
74
+ call.merge_call_tree(kid)
75
+ else
76
+ parent.children << kid
77
+ # $stderr.puts "setting parent of #{kid}\nto #{parent}"
78
+ kid.parent = parent
79
+ end
80
+ end
81
+ parent.children.delete(self)
82
+ end
83
+
84
+ # find a sepcific call in list of children. returns nil if not found.
85
+ # note: there can't be more than one child with a given target method. in other words:
86
+ # x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
87
+ def find_call(other)
88
+ matching = children.select { |kid| kid.target == other.target }
89
+ raise "inconsistent call tree" unless matching.size <= 1
90
+ matching.first
91
+ end
92
+
93
+ # merge two call trees. adds self, wait, and total time of other to self and merges children of other into children of self.
94
+ def merge_call_tree(other)
95
+ # $stderr.puts "merging #{self}\nand #{other}"
96
+ self.called += other.called
97
+ add_self_time(other)
98
+ add_wait_time(other)
99
+ add_total_time(other)
100
+ other.children.each do |other_kid|
101
+ if kid = find_call(other_kid)
102
+ # $stderr.puts "merging kids"
103
+ kid.merge_call_tree(other_kid)
104
+ else
105
+ other_kid.parent = self
106
+ children << other_kid
107
+ end
108
+ end
109
+ other.children.clear
110
+ other.target.call_infos.delete(other)
111
+ end
112
+
46
113
  end
47
- end
114
+ end