ruby-prof 0.18.0-x64-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 (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +500 -0
  3. data/LICENSE +25 -0
  4. data/README.rdoc +487 -0
  5. data/Rakefile +113 -0
  6. data/bin/ruby-prof +345 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/examples/flat.txt +50 -0
  9. data/examples/graph.dot +84 -0
  10. data/examples/graph.html +823 -0
  11. data/examples/graph.txt +139 -0
  12. data/examples/multi.flat.txt +23 -0
  13. data/examples/multi.graph.html +760 -0
  14. data/examples/multi.grind.dat +114 -0
  15. data/examples/multi.stack.html +547 -0
  16. data/examples/stack.html +547 -0
  17. data/ext/ruby_prof/extconf.rb +68 -0
  18. data/ext/ruby_prof/rp_call_info.c +425 -0
  19. data/ext/ruby_prof/rp_call_info.h +53 -0
  20. data/ext/ruby_prof/rp_measure.c +40 -0
  21. data/ext/ruby_prof/rp_measure.h +45 -0
  22. data/ext/ruby_prof/rp_measure_allocations.c +76 -0
  23. data/ext/ruby_prof/rp_measure_cpu_time.c +136 -0
  24. data/ext/ruby_prof/rp_measure_gc_runs.c +73 -0
  25. data/ext/ruby_prof/rp_measure_gc_time.c +60 -0
  26. data/ext/ruby_prof/rp_measure_memory.c +77 -0
  27. data/ext/ruby_prof/rp_measure_process_time.c +71 -0
  28. data/ext/ruby_prof/rp_measure_wall_time.c +45 -0
  29. data/ext/ruby_prof/rp_method.c +630 -0
  30. data/ext/ruby_prof/rp_method.h +75 -0
  31. data/ext/ruby_prof/rp_stack.c +173 -0
  32. data/ext/ruby_prof/rp_stack.h +63 -0
  33. data/ext/ruby_prof/rp_thread.c +277 -0
  34. data/ext/ruby_prof/rp_thread.h +27 -0
  35. data/ext/ruby_prof/ruby_prof.c +794 -0
  36. data/ext/ruby_prof/ruby_prof.h +60 -0
  37. data/ext/ruby_prof/vc/ruby_prof.sln +31 -0
  38. data/ext/ruby_prof/vc/ruby_prof.vcxproj +141 -0
  39. data/lib/2.6.3/ruby_prof.so +0 -0
  40. data/lib/ruby-prof.rb +68 -0
  41. data/lib/ruby-prof/aggregate_call_info.rb +76 -0
  42. data/lib/ruby-prof/assets/call_stack_printer.css.html +117 -0
  43. data/lib/ruby-prof/assets/call_stack_printer.js.html +385 -0
  44. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  45. data/lib/ruby-prof/call_info.rb +115 -0
  46. data/lib/ruby-prof/call_info_visitor.rb +40 -0
  47. data/lib/ruby-prof/compatibility.rb +179 -0
  48. data/lib/ruby-prof/method_info.rb +121 -0
  49. data/lib/ruby-prof/printers/abstract_printer.rb +104 -0
  50. data/lib/ruby-prof/printers/call_info_printer.rb +41 -0
  51. data/lib/ruby-prof/printers/call_stack_printer.rb +265 -0
  52. data/lib/ruby-prof/printers/call_tree_printer.rb +143 -0
  53. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  54. data/lib/ruby-prof/printers/flat_printer.rb +70 -0
  55. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -0
  56. data/lib/ruby-prof/printers/graph_html_printer.rb +249 -0
  57. data/lib/ruby-prof/printers/graph_printer.rb +116 -0
  58. data/lib/ruby-prof/printers/multi_printer.rb +84 -0
  59. data/lib/ruby-prof/profile.rb +26 -0
  60. data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -0
  61. data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -0
  62. data/lib/ruby-prof/rack.rb +174 -0
  63. data/lib/ruby-prof/task.rb +147 -0
  64. data/lib/ruby-prof/thread.rb +35 -0
  65. data/lib/ruby-prof/version.rb +3 -0
  66. data/lib/unprof.rb +10 -0
  67. data/ruby-prof.gemspec +58 -0
  68. data/test/abstract_printer_test.rb +53 -0
  69. data/test/aggregate_test.rb +136 -0
  70. data/test/basic_test.rb +128 -0
  71. data/test/block_test.rb +74 -0
  72. data/test/call_info_test.rb +78 -0
  73. data/test/call_info_visitor_test.rb +31 -0
  74. data/test/duplicate_names_test.rb +32 -0
  75. data/test/dynamic_method_test.rb +55 -0
  76. data/test/enumerable_test.rb +21 -0
  77. data/test/exceptions_test.rb +24 -0
  78. data/test/exclude_methods_test.rb +146 -0
  79. data/test/exclude_threads_test.rb +53 -0
  80. data/test/fiber_test.rb +79 -0
  81. data/test/issue137_test.rb +63 -0
  82. data/test/line_number_test.rb +80 -0
  83. data/test/measure_allocations_test.rb +26 -0
  84. data/test/measure_cpu_time_test.rb +212 -0
  85. data/test/measure_gc_runs_test.rb +32 -0
  86. data/test/measure_gc_time_test.rb +36 -0
  87. data/test/measure_memory_test.rb +33 -0
  88. data/test/measure_process_time_test.rb +61 -0
  89. data/test/measure_wall_time_test.rb +255 -0
  90. data/test/method_elimination_test.rb +84 -0
  91. data/test/module_test.rb +45 -0
  92. data/test/multi_printer_test.rb +104 -0
  93. data/test/no_method_class_test.rb +15 -0
  94. data/test/pause_resume_test.rb +166 -0
  95. data/test/prime.rb +54 -0
  96. data/test/printers_test.rb +275 -0
  97. data/test/printing_recursive_graph_test.rb +127 -0
  98. data/test/rack_test.rb +157 -0
  99. data/test/recursive_test.rb +215 -0
  100. data/test/singleton_test.rb +38 -0
  101. data/test/stack_printer_test.rb +77 -0
  102. data/test/stack_test.rb +138 -0
  103. data/test/start_stop_test.rb +112 -0
  104. data/test/test_helper.rb +267 -0
  105. data/test/thread_test.rb +187 -0
  106. data/test/unique_call_path_test.rb +202 -0
  107. data/test/yarv_test.rb +55 -0
  108. metadata +199 -0
@@ -0,0 +1,68 @@
1
+ require "mkmf"
2
+
3
+ if RUBY_ENGINE != "ruby"
4
+ STDERR.puts("\n\n***** This gem is MRI-specific. It does not support #{RUBY_ENGINE}. *****\n\n")
5
+ exit(1)
6
+ end
7
+
8
+ if RUBY_VERSION < "1.9.3"
9
+ STDERR.puts("\n\n***** Ruby version #{RUBY_VERSION} is no longer supported. Please upgrade to 1.9.3 or higher. *****\n\n")
10
+ exit(1)
11
+ end
12
+
13
+ # For the love of bitfields...
14
+ $CFLAGS += ' -std=c99'
15
+
16
+ # standard ruby methods
17
+ have_func("rb_gc_stat")
18
+ have_func("rb_gc_count")
19
+ have_func("rb_remove_event_hook_with_data")
20
+
21
+ # Alexander Dymo GC patch
22
+ have_func("rb_os_allocated_objects")
23
+ have_func("rb_gc_allocated_size")
24
+
25
+ # Stefan Kaes GC patches
26
+ have_func("rb_gc_collections")
27
+ have_func("rb_gc_time")
28
+ # for ruby 2.1
29
+ have_func("rb_gc_total_time")
30
+ have_func("rb_gc_total_mallocs")
31
+ have_func("rb_gc_total_malloced_bytes")
32
+
33
+ # Lloyd Hilaiel's heap info patch
34
+ have_func("rb_heap_total_mem")
35
+ have_func("rb_gc_heap_info")
36
+
37
+ def add_define(name, value = nil)
38
+ if value
39
+ $defs.push("-D#{name}=#{value}")
40
+ else
41
+ $defs.push("-D#{name}")
42
+ end
43
+ end
44
+
45
+ def windows?
46
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
47
+ end
48
+
49
+ if !windows? && RUBY_PLATFORM !~ /(darwin|openbsd)/
50
+ $LDFLAGS += " -lrt" # for clock_gettime
51
+ end
52
+ add_define("RUBY_PROF_RUBY_VERSION", RUBY_VERSION.split('.')[0..2].inject(0){|v,d| v*100+d.to_i})
53
+
54
+ # for ruby 1.9, determine whether threads inherit trace flags (latest 1.9.2 and later should work correctly)
55
+ if RUBY_VERSION > "1.9"
56
+ require 'set'
57
+ threads = Set.new
58
+ set_trace_func lambda { |*args| threads << Thread.current.object_id }
59
+ Thread.new{1}.join
60
+ set_trace_func nil
61
+ if threads.size < 2
62
+ # if we end up here, ruby does not automatically activate tracing in spawned threads
63
+ STDERR.puts("Ruby #{RUBY_VERSION} does not activate tracing in spawned threads. Consider upgrading.")
64
+ exit(1)
65
+ end
66
+ end
67
+
68
+ create_makefile("ruby_prof")
@@ -0,0 +1,425 @@
1
+ /* Copyright (C) 2005-2019 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
+
11
+ // Forward declarations
12
+ st_table * call_info_table_create();
13
+
14
+
15
+ /* ======= prof_call_info_t ========*/
16
+ prof_call_info_t *
17
+ prof_call_info_create(prof_method_t* method, prof_call_info_t* parent)
18
+ {
19
+ prof_call_info_t *result = ALLOC(prof_call_info_t);
20
+ result->object = Qnil;
21
+ result->target = method;
22
+ result->parent = parent;
23
+ result->call_infos = call_info_table_create();
24
+ result->children = Qnil;
25
+
26
+ result->total_time = 0;
27
+ result->self_time = 0;
28
+ result->wait_time = 0;
29
+
30
+ result->called = 0;
31
+
32
+ result->recursive = 0;
33
+ result->depth = 0;
34
+ result->line = 0;
35
+
36
+ return result;
37
+ }
38
+ static void
39
+ prof_call_info_ruby_gc_free(prof_call_info_t *call_info)
40
+ {
41
+ /* Has this thread object been accessed by Ruby? If
42
+ yes clean it up so to avoid a segmentation fault. */
43
+ if (call_info->object != Qnil)
44
+ {
45
+ RDATA(call_info->object)->data = NULL;
46
+ RDATA(call_info->object)->dfree = NULL;
47
+ RDATA(call_info->object)->dmark = NULL;
48
+ }
49
+ call_info->object = Qnil;
50
+ }
51
+
52
+ static void
53
+ prof_call_info_free(prof_call_info_t *call_info)
54
+ {
55
+ prof_call_info_ruby_gc_free(call_info);
56
+ st_free_table(call_info->call_infos);
57
+ xfree(call_info);
58
+ }
59
+
60
+ static void
61
+ prof_call_info_mark(prof_call_info_t *call_info)
62
+ {
63
+ if (call_info->object)
64
+ rb_gc_mark(call_info->object);
65
+
66
+ if (call_info->children)
67
+ rb_gc_mark(call_info->children);
68
+
69
+ /* We don't mark the call info child table since that will be done
70
+ via the appropriate method */
71
+ }
72
+
73
+ VALUE
74
+ prof_call_info_wrap(prof_call_info_t *call_info)
75
+ {
76
+ if (call_info->object == Qnil)
77
+ {
78
+ call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
79
+ }
80
+ return call_info->object;
81
+ }
82
+
83
+ static prof_call_info_t *
84
+ prof_get_call_info(VALUE self)
85
+ {
86
+ /* Can't use Data_Get_Struct because that triggers the event hook
87
+ ending up in endless recursion. */
88
+ prof_call_info_t* result = DATA_PTR(self);
89
+
90
+ if (!result)
91
+ rb_raise(rb_eRuntimeError, "This RubyProf::CallInfo instance has already been freed, likely because its profile has been freed.");
92
+
93
+ return result;
94
+ }
95
+
96
+ /* ======= Call Info Table ========*/
97
+ st_table *
98
+ call_info_table_create()
99
+ {
100
+ return st_init_table(&type_method_hash);
101
+ }
102
+
103
+ size_t
104
+ call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val)
105
+ {
106
+ return st_insert(table, (st_data_t) key, (st_data_t) val);
107
+ }
108
+
109
+ prof_call_info_t *
110
+ call_info_table_lookup(st_table *table, const prof_method_key_t *key)
111
+ {
112
+ st_data_t val;
113
+ if (st_lookup(table, (st_data_t) key, &val))
114
+ {
115
+ return (prof_call_info_t *) val;
116
+ }
117
+ else
118
+ {
119
+ return NULL;
120
+ }
121
+ }
122
+
123
+
124
+ /* ======= RubyProf::CallInfo ========*/
125
+
126
+ /* Document-class: RubyProf::CallInfo
127
+ RubyProf::CallInfo is a helper class used by RubyProf::MethodInfo
128
+ to keep track of which child methods were called and how long
129
+ they took to execute. */
130
+
131
+
132
+ /* call-seq:
133
+ called -> MethodInfo
134
+
135
+ Returns the target method. */
136
+ static VALUE
137
+ prof_call_info_target(VALUE self)
138
+ {
139
+ /* Target is a pointer to a method_info - so we have to be careful
140
+ about the GC. We will wrap the method_info but provide no
141
+ free method so the underlying object is not freed twice! */
142
+
143
+ prof_call_info_t *result = prof_get_call_info(self);
144
+ return prof_method_wrap(result->target);
145
+ }
146
+
147
+ /* call-seq:
148
+ called -> int
149
+
150
+ Returns the total amount of times this method was called. */
151
+ static VALUE
152
+ prof_call_info_called(VALUE self)
153
+ {
154
+ prof_call_info_t *result = prof_get_call_info(self);
155
+ return INT2NUM(result->called);
156
+ }
157
+
158
+ /* call-seq:
159
+ called=n -> n
160
+
161
+ Sets the call count to n. */
162
+ static VALUE
163
+ prof_call_info_set_called(VALUE self, VALUE called)
164
+ {
165
+ prof_call_info_t *result = prof_get_call_info(self);
166
+ result->called = NUM2INT(called);
167
+ return called;
168
+ }
169
+
170
+ /* call-seq:
171
+ recursive? -> boolean
172
+
173
+ Returns the true if this call info is a recursive invocation */
174
+ static VALUE
175
+ prof_call_info_recursive(VALUE self)
176
+ {
177
+ prof_call_info_t *result = prof_get_call_info(self);
178
+ return result->recursive ? Qtrue : Qfalse;
179
+ }
180
+
181
+ /* call-seq:
182
+ depth -> int
183
+
184
+ returns the depth of this call info in the call graph */
185
+ static VALUE
186
+ prof_call_info_depth(VALUE self)
187
+ {
188
+ prof_call_info_t *result = prof_get_call_info(self);
189
+ return rb_int_new(result->depth);
190
+ }
191
+
192
+ /* call-seq:
193
+ line_no -> int
194
+
195
+ returns the line number of the method */
196
+ static VALUE
197
+ prof_call_info_line(VALUE self)
198
+ {
199
+ prof_call_info_t *result = prof_get_call_info(self);
200
+ return rb_int_new(result->line);
201
+ }
202
+
203
+ /* call-seq:
204
+ total_time -> float
205
+
206
+ Returns the total amount of time spent in this method and its children. */
207
+ static VALUE
208
+ prof_call_info_total_time(VALUE self)
209
+ {
210
+ prof_call_info_t *result = prof_get_call_info(self);
211
+ return rb_float_new(result->total_time);
212
+ }
213
+
214
+ /* call-seq:
215
+ add_total_time(call_info) -> nil
216
+
217
+ adds total time time from call_info to self. */
218
+ static VALUE
219
+ prof_call_info_add_total_time(VALUE self, VALUE other)
220
+ {
221
+ prof_call_info_t *result = prof_get_call_info(self);
222
+ prof_call_info_t *other_info = prof_get_call_info(other);
223
+
224
+ result->total_time += other_info->total_time;
225
+ return Qnil;
226
+ }
227
+
228
+ /* call-seq:
229
+ self_time -> float
230
+
231
+ Returns the total amount of time spent in this method. */
232
+ static VALUE
233
+ prof_call_info_self_time(VALUE self)
234
+ {
235
+ prof_call_info_t *result = prof_get_call_info(self);
236
+
237
+ return rb_float_new(result->self_time);
238
+ }
239
+
240
+ /* call-seq:
241
+ add_self_time(call_info) -> nil
242
+
243
+ adds self time from call_info to self. */
244
+ static VALUE
245
+ prof_call_info_add_self_time(VALUE self, VALUE other)
246
+ {
247
+ prof_call_info_t *result = prof_get_call_info(self);
248
+ prof_call_info_t *other_info = prof_get_call_info(other);
249
+
250
+ result->self_time += other_info->self_time;
251
+ return Qnil;
252
+ }
253
+
254
+ /* call-seq:
255
+ wait_time -> float
256
+
257
+ Returns the total amount of time this method waited for other threads. */
258
+ static VALUE
259
+ prof_call_info_wait_time(VALUE self)
260
+ {
261
+ prof_call_info_t *result = prof_get_call_info(self);
262
+
263
+ return rb_float_new(result->wait_time);
264
+ }
265
+
266
+ /* call-seq:
267
+ add_wait_time(call_info) -> nil
268
+
269
+ adds wait time from call_info to self. */
270
+
271
+ static VALUE
272
+ prof_call_info_add_wait_time(VALUE self, VALUE other)
273
+ {
274
+ prof_call_info_t *result = prof_get_call_info(self);
275
+ prof_call_info_t *other_info = prof_get_call_info(other);
276
+
277
+ result->wait_time += other_info->wait_time;
278
+ return Qnil;
279
+ }
280
+
281
+ /* call-seq:
282
+ parent -> call_info
283
+
284
+ Returns the call_infos parent call_info object (the method that called this method).*/
285
+ static VALUE
286
+ prof_call_info_parent(VALUE self)
287
+ {
288
+ prof_call_info_t *result = prof_get_call_info(self);
289
+ if (result->parent)
290
+ return prof_call_info_wrap(result->parent);
291
+ else
292
+ return Qnil;
293
+ }
294
+
295
+ /* call-seq:
296
+ parent=new_parent -> new_parent
297
+
298
+ Changes the parent of self to new_parent and returns it.*/
299
+ static VALUE
300
+ prof_call_info_set_parent(VALUE self, VALUE new_parent)
301
+ {
302
+ prof_call_info_t *result = prof_get_call_info(self);
303
+ if (new_parent == Qnil)
304
+ result->parent = NULL;
305
+ else
306
+ result->parent = prof_get_call_info(new_parent);
307
+ return prof_call_info_parent(self);
308
+ }
309
+
310
+ static int
311
+ prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result)
312
+ {
313
+ prof_call_info_t *call_info = (prof_call_info_t *) value;
314
+ VALUE arr = (VALUE) result;
315
+ rb_ary_push(arr, prof_call_info_wrap(call_info));
316
+ return ST_CONTINUE;
317
+ }
318
+
319
+ /* call-seq:
320
+ children -> hash
321
+
322
+ Returns an array of call info objects of methods that this method
323
+ called (ie, children).*/
324
+ static VALUE
325
+ prof_call_info_children(VALUE self)
326
+ {
327
+ prof_call_info_t *call_info = prof_get_call_info(self);
328
+ if (call_info->children == Qnil)
329
+ {
330
+ call_info->children = rb_ary_new();
331
+ st_foreach(call_info->call_infos, prof_call_info_collect_children, call_info->children);
332
+ }
333
+ return call_info->children;
334
+ }
335
+
336
+ /* ======= Call Infos ========*/
337
+ prof_call_infos_t*
338
+ prof_call_infos_create()
339
+ {
340
+ prof_call_infos_t *result = ALLOC(prof_call_infos_t);
341
+ result->start = ALLOC_N(prof_call_info_t*, INITIAL_CALL_INFOS_SIZE);
342
+ result->end = result->start + INITIAL_CALL_INFOS_SIZE;
343
+ result->ptr = result->start;
344
+ result->object = Qnil;
345
+ return result;
346
+ }
347
+
348
+ void
349
+ prof_call_infos_mark(prof_call_infos_t *call_infos)
350
+ {
351
+ prof_call_info_t **call_info;
352
+
353
+ if (call_infos->object)
354
+ rb_gc_mark(call_infos->object);
355
+
356
+ for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
357
+ {
358
+ prof_call_info_mark(*call_info);
359
+ }
360
+ }
361
+
362
+ void
363
+ prof_call_infos_free(prof_call_infos_t *call_infos)
364
+ {
365
+ prof_call_info_t **call_info;
366
+
367
+ for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
368
+ {
369
+ prof_call_info_free(*call_info);
370
+ }
371
+ }
372
+
373
+ void
374
+ prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info)
375
+ {
376
+ if (call_infos->ptr == call_infos->end)
377
+ {
378
+ size_t len = call_infos->ptr - call_infos->start;
379
+ size_t new_capacity = (call_infos->end - call_infos->start) * 2;
380
+ REALLOC_N(call_infos->start, prof_call_info_t*, new_capacity);
381
+ call_infos->ptr = call_infos->start + len;
382
+ call_infos->end = call_infos->start + new_capacity;
383
+ }
384
+ *call_infos->ptr = call_info;
385
+ call_infos->ptr++;
386
+ }
387
+
388
+ VALUE
389
+ prof_call_infos_wrap(prof_call_infos_t *call_infos)
390
+ {
391
+ if (call_infos->object == Qnil)
392
+ {
393
+ prof_call_info_t **i;
394
+ call_infos->object = rb_ary_new();
395
+ for(i=call_infos->start; i<call_infos->ptr; i++)
396
+ {
397
+ VALUE call_info = prof_call_info_wrap(*i);
398
+ rb_ary_push(call_infos->object, call_info);
399
+ }
400
+ }
401
+ return call_infos->object;
402
+ }
403
+
404
+ void rp_init_call_info()
405
+ {
406
+ /* CallInfo */
407
+ cCallInfo = rb_define_class_under(mProf, "CallInfo", rb_cObject);
408
+ rb_undef_method(CLASS_OF(cCallInfo), "new");
409
+ rb_define_method(cCallInfo, "parent", prof_call_info_parent, 0);
410
+ rb_define_method(cCallInfo, "parent=", prof_call_info_set_parent, 1);
411
+ rb_define_method(cCallInfo, "children", prof_call_info_children, 0);
412
+ rb_define_method(cCallInfo, "target", prof_call_info_target, 0);
413
+ rb_define_method(cCallInfo, "called", prof_call_info_called, 0);
414
+ rb_define_method(cCallInfo, "called=", prof_call_info_set_called, 1);
415
+ rb_define_method(cCallInfo, "total_time", prof_call_info_total_time, 0);
416
+ rb_define_method(cCallInfo, "add_total_time", prof_call_info_add_total_time, 1);
417
+ rb_define_method(cCallInfo, "self_time", prof_call_info_self_time, 0);
418
+ rb_define_method(cCallInfo, "add_self_time", prof_call_info_add_self_time, 1);
419
+ rb_define_method(cCallInfo, "wait_time", prof_call_info_wait_time, 0);
420
+ rb_define_method(cCallInfo, "add_wait_time", prof_call_info_add_wait_time, 1);
421
+
422
+ rb_define_method(cCallInfo, "recursive?", prof_call_info_recursive, 0);
423
+ rb_define_method(cCallInfo, "depth", prof_call_info_depth, 0);
424
+ rb_define_method(cCallInfo, "line", prof_call_info_line, 0);
425
+ }