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.
- data/CHANGES +89 -13
- data/LICENSE +4 -3
- data/{README → README.rdoc} +155 -162
- data/Rakefile +50 -123
- data/bin/ruby-prof +86 -47
- data/examples/empty.png +0 -0
- data/examples/graph.dot +106 -0
- data/examples/graph.png +0 -0
- data/examples/minus.png +0 -0
- data/examples/multi.flat.txt +23 -0
- data/examples/multi.graph.html +906 -0
- data/examples/multi.grind.dat +194 -0
- data/examples/multi.stack.html +573 -0
- data/examples/plus.png +0 -0
- data/examples/stack.html +573 -0
- data/ext/ruby_prof/extconf.rb +53 -0
- data/ext/ruby_prof/rp_call_info.c +369 -0
- data/ext/ruby_prof/rp_call_info.h +46 -0
- data/ext/ruby_prof/rp_measure.c +48 -0
- data/ext/ruby_prof/rp_measure.h +45 -0
- data/ext/ruby_prof/rp_measure_allocations.c +86 -0
- data/ext/ruby_prof/rp_measure_cpu_time.c +112 -0
- data/ext/ruby_prof/rp_measure_gc_runs.c +87 -0
- data/ext/ruby_prof/rp_measure_gc_time.c +73 -0
- data/ext/ruby_prof/rp_measure_memory.c +81 -0
- data/ext/ruby_prof/rp_measure_process_time.c +71 -0
- data/ext/ruby_prof/rp_measure_wall_time.c +42 -0
- data/ext/ruby_prof/rp_method.c +363 -0
- data/ext/ruby_prof/rp_method.h +55 -0
- data/ext/ruby_prof/rp_stack.c +61 -0
- data/ext/ruby_prof/rp_stack.h +40 -0
- data/ext/ruby_prof/rp_thread.c +113 -0
- data/ext/ruby_prof/rp_thread.h +20 -0
- data/ext/ruby_prof/ruby_prof.c +332 -1377
- data/ext/ruby_prof/ruby_prof.h +54 -188
- data/ext/ruby_prof/version.h +6 -3
- data/lib/1.8/ruby_prof.so +0 -0
- data/lib/1.9/ruby_prof.exp +0 -0
- data/lib/1.9/ruby_prof.ilk +0 -0
- data/lib/1.9/ruby_prof.lib +0 -0
- data/lib/1.9/ruby_prof.pdb +0 -0
- data/lib/1.9/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +32 -18
- data/lib/ruby-prof/abstract_printer.rb +15 -5
- data/lib/ruby-prof/aggregate_call_info.rb +11 -3
- data/lib/ruby-prof/call_info.rb +68 -1
- data/lib/ruby-prof/call_stack_printer.rb +775 -0
- data/lib/ruby-prof/call_tree_printer.rb +17 -9
- data/lib/ruby-prof/compatibility.rb +134 -0
- data/lib/ruby-prof/dot_printer.rb +152 -0
- data/lib/ruby-prof/empty.png +0 -0
- data/lib/ruby-prof/flat_printer.rb +23 -24
- data/lib/ruby-prof/flat_printer_with_line_numbers.rb +17 -21
- data/lib/ruby-prof/graph_html_printer.rb +69 -39
- data/lib/ruby-prof/graph_printer.rb +35 -35
- data/lib/ruby-prof/method_info.rb +26 -4
- data/lib/ruby-prof/minus.png +0 -0
- data/lib/ruby-prof/multi_printer.rb +56 -0
- data/lib/ruby-prof/plus.png +0 -0
- data/lib/ruby-prof/profile.rb +72 -0
- data/lib/ruby-prof/rack.rb +31 -0
- data/lib/ruby-prof/symbol_to_proc.rb +3 -1
- data/lib/ruby-prof/task.rb +20 -19
- data/lib/ruby-prof/test.rb +5 -3
- data/lib/ruby_prof.exp +0 -0
- data/lib/ruby_prof.ilk +0 -0
- data/lib/ruby_prof.lib +0 -0
- data/lib/ruby_prof.pdb +0 -0
- data/lib/ruby_prof.so +0 -0
- data/lib/unprof.rb +2 -0
- data/test/aggregate_test.rb +29 -14
- data/test/basic_test.rb +3 -251
- data/test/bug_test.rb +6 -0
- data/test/duplicate_names_test.rb +4 -4
- data/test/dynamic_method_test.rb +61 -0
- data/test/enumerable_test.rb +4 -4
- data/test/exceptions_test.rb +6 -5
- data/test/exclude_threads_test.rb +47 -47
- data/test/exec_test.rb +5 -5
- data/test/line_number_test.rb +16 -16
- data/test/measure_allocations_test.rb +25 -0
- data/test/measure_cpu_time_test.rb +212 -0
- data/test/measure_gc_runs_test.rb +29 -0
- data/test/measure_gc_time_test.rb +29 -0
- data/test/measure_memory_test.rb +36 -0
- data/test/measure_process_time_test.rb +205 -0
- data/test/measure_wall_time_test.rb +209 -0
- data/test/method_elimination_test.rb +74 -0
- data/test/module_test.rb +12 -21
- data/test/multi_printer_test.rb +81 -0
- data/test/no_method_class_test.rb +5 -3
- data/test/prime.rb +7 -10
- data/test/prime_test.rb +3 -3
- data/test/printers_test.rb +180 -54
- data/test/recursive_test.rb +34 -72
- data/test/singleton_test.rb +5 -4
- data/test/stack_printer_test.rb +73 -0
- data/test/stack_test.rb +7 -7
- data/test/start_stop_test.rb +23 -6
- data/test/test_helper.rb +81 -0
- data/test/test_suite.rb +35 -21
- data/test/thread_test.rb +40 -39
- data/test/unique_call_path_test.rb +6 -6
- metadata +106 -51
- data/ext/ruby_prof/measure_allocations.h +0 -58
- data/ext/ruby_prof/measure_cpu_time.h +0 -152
- data/ext/ruby_prof/measure_gc_runs.h +0 -76
- data/ext/ruby_prof/measure_gc_time.h +0 -57
- data/ext/ruby_prof/measure_memory.h +0 -101
- data/ext/ruby_prof/measure_process_time.h +0 -52
- data/ext/ruby_prof/measure_wall_time.h +0 -53
- data/ext/ruby_prof/mingw/Rakefile +0 -23
- data/ext/ruby_prof/mingw/build.rake +0 -38
- data/rails/environment/profile.rb +0 -24
- data/rails/example/example_test.rb +0 -9
- data/rails/profile_test_helper.rb +0 -21
- data/test/current_failures_windows +0 -8
- data/test/measurement_test.rb +0 -121
- data/test/ruby-prof-bin +0 -20
data/ext/ruby_prof/ruby_prof.h
CHANGED
@@ -1,188 +1,54 @@
|
|
1
|
-
/*
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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__
|
data/ext/ruby_prof/version.h
CHANGED
@@ -1,4 +1,7 @@
|
|
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
|
4
|
-
#define RUBY_PROF_VERSION_MIC
|
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
|
-
#
|
2
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Load the C-based binding.
|
3
4
|
begin
|
4
|
-
|
5
|
-
require "#{
|
6
|
-
rescue
|
7
|
-
require "
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/ruby-prof/call_info.rb
CHANGED
@@ -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
|