ruby-prof 0.10.8 → 0.11.0.rc1
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 +38 -18
- data/LICENSE +4 -3
- data/README.rdoc +30 -66
- data/Rakefile +47 -54
- data/bin/ruby-prof +24 -4
- data/ext/ruby_prof/extconf.rb +9 -16
- 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 +259 -1398
- data/ext/ruby_prof/ruby_prof.h +54 -190
- 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 +14 -11
- data/lib/ruby-prof/abstract_printer.rb +10 -0
- data/lib/ruby-prof/aggregate_call_info.rb +2 -0
- data/lib/ruby-prof/call_info.rb +2 -0
- data/lib/ruby-prof/call_stack_printer.rb +2 -4
- data/lib/ruby-prof/call_tree_printer.rb +1 -0
- data/lib/ruby-prof/compatibility.rb +134 -0
- data/lib/ruby-prof/dot_printer.rb +7 -7
- data/lib/ruby-prof/flat_printer.rb +7 -7
- data/lib/ruby-prof/flat_printer_with_line_numbers.rb +2 -5
- data/lib/ruby-prof/graph_html_printer.rb +4 -2
- data/lib/ruby-prof/graph_printer.rb +4 -3
- data/lib/ruby-prof/method_info.rb +2 -0
- data/lib/ruby-prof/multi_printer.rb +2 -0
- data/lib/ruby-prof/{result.rb → profile.rb} +3 -1
- data/lib/ruby-prof/rack.rb +1 -0
- data/lib/ruby-prof/symbol_to_proc.rb +2 -0
- data/lib/ruby-prof/task.rb +1 -0
- data/lib/ruby-prof/test.rb +2 -0
- 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 +8 -8
- data/test/basic_test.rb +3 -251
- data/test/bug_test.rb +6 -0
- data/test/duplicate_names_test.rb +2 -2
- data/test/dynamic_method_test.rb +61 -0
- data/test/enumerable_test.rb +2 -2
- data/test/exceptions_test.rb +4 -3
- data/test/exclude_threads_test.rb +2 -2
- data/test/exec_test.rb +3 -3
- data/test/line_number_test.rb +5 -5
- 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 +2 -2
- data/test/module_test.rb +3 -2
- data/test/multi_printer_test.rb +2 -2
- data/test/no_method_class_test.rb +3 -1
- data/test/prime_test.rb +3 -3
- data/test/printers_test.rb +106 -8
- data/test/recursive_test.rb +7 -6
- data/test/singleton_test.rb +2 -2
- data/test/stack_printer_test.rb +2 -3
- data/test/stack_test.rb +2 -2
- data/test/start_stop_test.rb +2 -2
- data/test/test_helper.rb +81 -0
- data/test/test_suite.rb +34 -29
- data/test/thread_test.rb +24 -23
- data/test/unique_call_path_test.rb +2 -2
- metadata +101 -69
- data/ext/ruby_prof/measure_allocations.h +0 -83
- 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 -63
- 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 -132
- data/test/ruby-prof-bin +0 -20
data/ext/ruby_prof/extconf.rb
CHANGED
@@ -1,17 +1,12 @@
|
|
1
1
|
require "mkmf"
|
2
2
|
|
3
|
-
if RUBY_VERSION
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
STDERR.print("Ruby version is too old\n")
|
11
|
-
exit(1)
|
12
|
-
end
|
13
|
-
else
|
14
|
-
STDERR.print("Ruby version is too old\n")
|
3
|
+
if RUBY_VERSION == "1.8.6"
|
4
|
+
STDERR.print("Ruby #{RUBY_VERSION} is no longer supported. Please upgrade to 1.8.7 or 1.9.2 or higher\n")
|
5
|
+
exit(1)
|
6
|
+
end
|
7
|
+
|
8
|
+
if RUBY_VERSION == "1.9.0" or RUBY_VERSION == "1.9.1"
|
9
|
+
STDERR.print("Ruby #{RUBY_VERSION} is no longer supported. Please upgrade to 1.9.2 or higher\n")
|
15
10
|
exit(1)
|
16
11
|
end
|
17
12
|
|
@@ -30,9 +25,6 @@ have_func("rb_class_superclass")
|
|
30
25
|
have_func("rb_heap_total_mem")
|
31
26
|
have_func("rb_gc_heap_info")
|
32
27
|
|
33
|
-
# Ruby 1.9 unexposed methods
|
34
|
-
have_func("rb_gc_malloc_allocations")
|
35
|
-
have_func("rb_gc_malloc_allocated_size")
|
36
28
|
|
37
29
|
def add_define(name, value = nil)
|
38
30
|
if value
|
@@ -41,6 +33,7 @@ def add_define(name, value = nil)
|
|
41
33
|
$defs.push("-D#{name}")
|
42
34
|
end
|
43
35
|
end
|
36
|
+
|
44
37
|
require 'rubygems'
|
45
38
|
unless Gem.win_platform? || RUBY_PLATFORM =~ /darwin/
|
46
39
|
$LDFLAGS += " -lrt" # for clock_gettime
|
@@ -57,4 +50,4 @@ if RUBY_VERSION > "1.9"
|
|
57
50
|
add_define("THREADS_INHERIT_EVENT_FLAGS", (threads.size == 2) ? "1" : "0")
|
58
51
|
end
|
59
52
|
|
60
|
-
create_makefile("
|
53
|
+
create_makefile("ruby_prof")
|
@@ -0,0 +1,369 @@
|
|
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
|
+
#include "ruby_prof.h"
|
5
|
+
|
6
|
+
#define INITIAL_CALL_INFOS_SIZE 2
|
7
|
+
|
8
|
+
VALUE cCallInfo;
|
9
|
+
|
10
|
+
/* ======= Call Info ========*/
|
11
|
+
st_table *
|
12
|
+
call_info_table_create()
|
13
|
+
{
|
14
|
+
return st_init_table(&type_method_hash);
|
15
|
+
}
|
16
|
+
|
17
|
+
size_t
|
18
|
+
call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val)
|
19
|
+
{
|
20
|
+
return st_insert(table, (st_data_t) key, (st_data_t) val);
|
21
|
+
}
|
22
|
+
|
23
|
+
prof_call_info_t *
|
24
|
+
call_info_table_lookup(st_table *table, const prof_method_key_t *key)
|
25
|
+
{
|
26
|
+
st_data_t val;
|
27
|
+
if (st_lookup(table, (st_data_t) key, &val))
|
28
|
+
{
|
29
|
+
return (prof_call_info_t *) val;
|
30
|
+
}
|
31
|
+
else
|
32
|
+
{
|
33
|
+
return NULL;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
static void
|
38
|
+
call_info_table_free(st_table *table)
|
39
|
+
{
|
40
|
+
st_free_table(table);
|
41
|
+
}
|
42
|
+
|
43
|
+
/* Document-class: RubyProf::CallInfo
|
44
|
+
RubyProf::CallInfo is a helper class used by RubyProf::MethodInfo
|
45
|
+
to keep track of which child methods were called and how long
|
46
|
+
they took to execute. */
|
47
|
+
|
48
|
+
/* :nodoc: */
|
49
|
+
prof_call_info_t *
|
50
|
+
prof_call_info_create(prof_method_t* method, prof_call_info_t* parent)
|
51
|
+
{
|
52
|
+
prof_call_info_t *result = ALLOC(prof_call_info_t);
|
53
|
+
result->object = Qnil;
|
54
|
+
result->target = method;
|
55
|
+
result->parent = parent;
|
56
|
+
result->call_infos = call_info_table_create();
|
57
|
+
result->children = Qnil;
|
58
|
+
|
59
|
+
result->called = 0;
|
60
|
+
result->total_time = 0;
|
61
|
+
result->self_time = 0;
|
62
|
+
result->wait_time = 0;
|
63
|
+
result->line = 0;
|
64
|
+
return result;
|
65
|
+
}
|
66
|
+
|
67
|
+
static void
|
68
|
+
prof_call_info_mark(prof_call_info_t *call_info)
|
69
|
+
{
|
70
|
+
{
|
71
|
+
VALUE target = call_info->target->object;
|
72
|
+
if (NIL_P(target))
|
73
|
+
prof_method_mark(call_info->target);
|
74
|
+
else
|
75
|
+
rb_gc_mark(target);
|
76
|
+
}
|
77
|
+
rb_gc_mark(call_info->children);
|
78
|
+
if (call_info->parent) {
|
79
|
+
VALUE parent = call_info->parent->object;
|
80
|
+
if (NIL_P(parent)) {
|
81
|
+
prof_call_info_mark(call_info->parent);
|
82
|
+
}
|
83
|
+
else {
|
84
|
+
rb_gc_mark(parent);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
static void
|
90
|
+
prof_call_info_free(prof_call_info_t *call_info)
|
91
|
+
{
|
92
|
+
call_info_table_free(call_info->call_infos);
|
93
|
+
xfree(call_info);
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE
|
97
|
+
prof_call_info_wrap(prof_call_info_t *call_info)
|
98
|
+
{
|
99
|
+
if (call_info->object == Qnil)
|
100
|
+
{
|
101
|
+
call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_free, call_info);
|
102
|
+
}
|
103
|
+
return call_info->object;
|
104
|
+
}
|
105
|
+
|
106
|
+
static prof_call_info_t *
|
107
|
+
prof_get_call_info_result(VALUE obj)
|
108
|
+
{
|
109
|
+
if (BUILTIN_TYPE(obj) != T_DATA)
|
110
|
+
{
|
111
|
+
/* Should never happen */
|
112
|
+
rb_raise(rb_eTypeError, "Not a call info object");
|
113
|
+
}
|
114
|
+
return (prof_call_info_t *) DATA_PTR(obj);
|
115
|
+
}
|
116
|
+
|
117
|
+
|
118
|
+
/* call-seq:
|
119
|
+
called -> MethodInfo
|
120
|
+
|
121
|
+
Returns the target method. */
|
122
|
+
static VALUE
|
123
|
+
prof_call_info_target(VALUE self)
|
124
|
+
{
|
125
|
+
/* Target is a pointer to a method_info - so we have to be careful
|
126
|
+
about the GC. We will wrap the method_info but provide no
|
127
|
+
free method so the underlying object is not freed twice! */
|
128
|
+
|
129
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
130
|
+
return prof_method_wrap(result->target);
|
131
|
+
}
|
132
|
+
|
133
|
+
/* call-seq:
|
134
|
+
called -> int
|
135
|
+
|
136
|
+
Returns the total amount of times this method was called. */
|
137
|
+
static VALUE
|
138
|
+
prof_call_info_called(VALUE self)
|
139
|
+
{
|
140
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
141
|
+
return INT2NUM(result->called);
|
142
|
+
}
|
143
|
+
|
144
|
+
/* call-seq:
|
145
|
+
called=n -> n
|
146
|
+
|
147
|
+
Sets the call count to n. */
|
148
|
+
static VALUE
|
149
|
+
prof_call_info_set_called(VALUE self, VALUE called)
|
150
|
+
{
|
151
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
152
|
+
result->called = NUM2INT(called);
|
153
|
+
return called;
|
154
|
+
}
|
155
|
+
|
156
|
+
/* call-seq:
|
157
|
+
line_no -> int
|
158
|
+
|
159
|
+
returns the line number of the method */
|
160
|
+
static VALUE
|
161
|
+
prof_call_info_line(VALUE self)
|
162
|
+
{
|
163
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
164
|
+
return rb_int_new(result->line);
|
165
|
+
}
|
166
|
+
|
167
|
+
/* call-seq:
|
168
|
+
total_time -> float
|
169
|
+
|
170
|
+
Returns the total amount of time spent in this method and its children. */
|
171
|
+
static VALUE
|
172
|
+
prof_call_info_total_time(VALUE self)
|
173
|
+
{
|
174
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
175
|
+
return rb_float_new(result->total_time);
|
176
|
+
}
|
177
|
+
|
178
|
+
/* call-seq:
|
179
|
+
add_total_time(call_info) -> nil
|
180
|
+
|
181
|
+
adds total time time from call_info to self. */
|
182
|
+
static VALUE
|
183
|
+
prof_call_info_add_total_time(VALUE self, VALUE other)
|
184
|
+
{
|
185
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
186
|
+
prof_call_info_t *other_info = prof_get_call_info_result(other);
|
187
|
+
|
188
|
+
result->total_time += other_info->total_time;
|
189
|
+
return Qnil;
|
190
|
+
}
|
191
|
+
|
192
|
+
/* call-seq:
|
193
|
+
self_time -> float
|
194
|
+
|
195
|
+
Returns the total amount of time spent in this method. */
|
196
|
+
static VALUE
|
197
|
+
prof_call_info_self_time(VALUE self)
|
198
|
+
{
|
199
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
200
|
+
|
201
|
+
return rb_float_new(result->self_time);
|
202
|
+
}
|
203
|
+
|
204
|
+
/* call-seq:
|
205
|
+
add_self_time(call_info) -> nil
|
206
|
+
|
207
|
+
adds self time from call_info to self. */
|
208
|
+
static VALUE
|
209
|
+
prof_call_info_add_self_time(VALUE self, VALUE other)
|
210
|
+
{
|
211
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
212
|
+
prof_call_info_t *other_info = prof_get_call_info_result(other);
|
213
|
+
|
214
|
+
result->self_time += other_info->self_time;
|
215
|
+
return Qnil;
|
216
|
+
}
|
217
|
+
|
218
|
+
/* call-seq:
|
219
|
+
wait_time -> float
|
220
|
+
|
221
|
+
Returns the total amount of time this method waited for other threads. */
|
222
|
+
static VALUE
|
223
|
+
prof_call_info_wait_time(VALUE self)
|
224
|
+
{
|
225
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
226
|
+
|
227
|
+
return rb_float_new(result->wait_time);
|
228
|
+
}
|
229
|
+
|
230
|
+
/* call-seq:
|
231
|
+
add_wait_time(call_info) -> nil
|
232
|
+
|
233
|
+
adds wait time from call_info to self. */
|
234
|
+
|
235
|
+
static VALUE
|
236
|
+
prof_call_info_add_wait_time(VALUE self, VALUE other)
|
237
|
+
{
|
238
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
239
|
+
prof_call_info_t *other_info = prof_get_call_info_result(other);
|
240
|
+
|
241
|
+
result->wait_time += other_info->wait_time;
|
242
|
+
return Qnil;
|
243
|
+
}
|
244
|
+
|
245
|
+
/* call-seq:
|
246
|
+
parent -> call_info
|
247
|
+
|
248
|
+
Returns the call_infos parent call_info object (the method that called this method).*/
|
249
|
+
static VALUE
|
250
|
+
prof_call_info_parent(VALUE self)
|
251
|
+
{
|
252
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
253
|
+
if (result->parent)
|
254
|
+
return prof_call_info_wrap(result->parent);
|
255
|
+
else
|
256
|
+
return Qnil;
|
257
|
+
}
|
258
|
+
|
259
|
+
/* call-seq:
|
260
|
+
parent=new_parent -> new_parent
|
261
|
+
|
262
|
+
Changes the parent of self to new_parent and returns it.*/
|
263
|
+
static VALUE
|
264
|
+
prof_call_info_set_parent(VALUE self, VALUE new_parent)
|
265
|
+
{
|
266
|
+
prof_call_info_t *result = prof_get_call_info_result(self);
|
267
|
+
if (new_parent == Qnil)
|
268
|
+
result->parent = NULL;
|
269
|
+
else
|
270
|
+
result->parent = prof_get_call_info_result(new_parent);
|
271
|
+
return prof_call_info_parent(self);
|
272
|
+
}
|
273
|
+
|
274
|
+
static int
|
275
|
+
prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result)
|
276
|
+
{
|
277
|
+
prof_call_info_t *call_info = (prof_call_info_t *) value;
|
278
|
+
VALUE arr = (VALUE) result;
|
279
|
+
rb_ary_push(arr, prof_call_info_wrap(call_info));
|
280
|
+
return ST_CONTINUE;
|
281
|
+
}
|
282
|
+
|
283
|
+
/* call-seq:
|
284
|
+
children -> hash
|
285
|
+
|
286
|
+
Returns an array of call info objects of methods that this method
|
287
|
+
called (ie, children).*/
|
288
|
+
static VALUE
|
289
|
+
prof_call_info_children(VALUE self)
|
290
|
+
{
|
291
|
+
prof_call_info_t *call_info = prof_get_call_info_result(self);
|
292
|
+
if (call_info->children == Qnil)
|
293
|
+
{
|
294
|
+
call_info->children = rb_ary_new();
|
295
|
+
st_foreach(call_info->call_infos, prof_call_info_collect_children, call_info->children);
|
296
|
+
}
|
297
|
+
return call_info->children;
|
298
|
+
}
|
299
|
+
|
300
|
+
/* ======= Call Infos ========*/
|
301
|
+
prof_call_infos_t*
|
302
|
+
prof_call_infos_create()
|
303
|
+
{
|
304
|
+
prof_call_infos_t *result = ALLOC(prof_call_infos_t);
|
305
|
+
result->start = ALLOC_N(prof_call_info_t*, INITIAL_CALL_INFOS_SIZE);
|
306
|
+
result->end = result->start + INITIAL_CALL_INFOS_SIZE;
|
307
|
+
result->ptr = result->start;
|
308
|
+
result->object = Qnil;
|
309
|
+
return result;
|
310
|
+
}
|
311
|
+
|
312
|
+
void
|
313
|
+
prof_call_infos_free(prof_call_infos_t *call_infos)
|
314
|
+
{
|
315
|
+
xfree(call_infos->start);
|
316
|
+
xfree(call_infos);
|
317
|
+
}
|
318
|
+
|
319
|
+
void
|
320
|
+
prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info)
|
321
|
+
{
|
322
|
+
if (call_infos->ptr == call_infos->end)
|
323
|
+
{
|
324
|
+
size_t len = call_infos->ptr - call_infos->start;
|
325
|
+
size_t new_capacity = (call_infos->end - call_infos->start) * 2;
|
326
|
+
REALLOC_N(call_infos->start, prof_call_info_t*, new_capacity);
|
327
|
+
call_infos->ptr = call_infos->start + len;
|
328
|
+
call_infos->end = call_infos->start + new_capacity;
|
329
|
+
}
|
330
|
+
*call_infos->ptr = call_info;
|
331
|
+
call_infos->ptr++;
|
332
|
+
}
|
333
|
+
|
334
|
+
VALUE
|
335
|
+
prof_call_infos_wrap(prof_call_infos_t *call_infos)
|
336
|
+
{
|
337
|
+
if (call_infos->object == Qnil)
|
338
|
+
{
|
339
|
+
prof_call_info_t **i;
|
340
|
+
call_infos->object = rb_ary_new();
|
341
|
+
for(i=call_infos->start; i<call_infos->ptr; i++)
|
342
|
+
{
|
343
|
+
VALUE call_info = prof_call_info_wrap(*i);
|
344
|
+
rb_ary_push(call_infos->object, call_info);
|
345
|
+
}
|
346
|
+
}
|
347
|
+
return call_infos->object;
|
348
|
+
}
|
349
|
+
|
350
|
+
|
351
|
+
void rp_init_call_info()
|
352
|
+
{
|
353
|
+
/* CallInfo */
|
354
|
+
cCallInfo = rb_define_class_under(mProf, "CallInfo", rb_cObject);
|
355
|
+
rb_undef_method(CLASS_OF(cCallInfo), "new");
|
356
|
+
rb_define_method(cCallInfo, "parent", prof_call_info_parent, 0);
|
357
|
+
rb_define_method(cCallInfo, "parent=", prof_call_info_set_parent, 1);
|
358
|
+
rb_define_method(cCallInfo, "children", prof_call_info_children, 0);
|
359
|
+
rb_define_method(cCallInfo, "target", prof_call_info_target, 0);
|
360
|
+
rb_define_method(cCallInfo, "called", prof_call_info_called, 0);
|
361
|
+
rb_define_method(cCallInfo, "called=", prof_call_info_set_called, 1);
|
362
|
+
rb_define_method(cCallInfo, "total_time", prof_call_info_total_time, 0);
|
363
|
+
rb_define_method(cCallInfo, "add_total_time", prof_call_info_add_total_time, 1);
|
364
|
+
rb_define_method(cCallInfo, "self_time", prof_call_info_self_time, 0);
|
365
|
+
rb_define_method(cCallInfo, "add_self_time", prof_call_info_add_self_time, 1);
|
366
|
+
rb_define_method(cCallInfo, "wait_time", prof_call_info_wait_time, 0);
|
367
|
+
rb_define_method(cCallInfo, "add_wait_time", prof_call_info_add_wait_time, 1);
|
368
|
+
rb_define_method(cCallInfo, "line", prof_call_info_line, 0);
|
369
|
+
}
|
@@ -0,0 +1,46 @@
|
|
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 __RP_CALL_INFO_H__
|
5
|
+
#define __RP_CALL_INFO_H__
|
6
|
+
|
7
|
+
#include "rp_measure.h"
|
8
|
+
#include "rp_method.h"
|
9
|
+
|
10
|
+
extern VALUE cCallInfo;
|
11
|
+
|
12
|
+
/* Callers and callee information for a method. */
|
13
|
+
typedef struct prof_call_info_t
|
14
|
+
{
|
15
|
+
prof_method_t *target; /* Use target instead of method to avoid conflict with Ruby method */
|
16
|
+
struct prof_call_info_t *parent;
|
17
|
+
st_table *call_infos;
|
18
|
+
int called;
|
19
|
+
double total_time;
|
20
|
+
double self_time;
|
21
|
+
double wait_time;
|
22
|
+
int line;
|
23
|
+
VALUE object;
|
24
|
+
VALUE children;
|
25
|
+
} prof_call_info_t;
|
26
|
+
|
27
|
+
/* Array of call_info objects */
|
28
|
+
typedef struct prof_call_infos_t
|
29
|
+
{
|
30
|
+
prof_call_info_t **start;
|
31
|
+
prof_call_info_t **end;
|
32
|
+
prof_call_info_t **ptr;
|
33
|
+
VALUE object;
|
34
|
+
} prof_call_infos_t;
|
35
|
+
|
36
|
+
|
37
|
+
void rp_init_call_info(void);
|
38
|
+
prof_call_infos_t* prof_call_infos_create();
|
39
|
+
void prof_call_infos_free(prof_call_infos_t *call_infos);
|
40
|
+
void prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info);
|
41
|
+
VALUE prof_call_infos_wrap(prof_call_infos_t *call_infos);
|
42
|
+
prof_call_info_t * prof_call_info_create(prof_method_t* method, prof_call_info_t* parent);
|
43
|
+
prof_call_info_t * call_info_table_lookup(st_table *table, const prof_method_key_t *key);
|
44
|
+
size_t call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val);
|
45
|
+
|
46
|
+
#endif //__RP_CALL_INFO_H__
|