ruby-prof 0.10.8 → 0.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/CHANGES +38 -18
  2. data/LICENSE +4 -3
  3. data/README.rdoc +30 -66
  4. data/Rakefile +47 -54
  5. data/bin/ruby-prof +24 -4
  6. data/ext/ruby_prof/extconf.rb +9 -16
  7. data/ext/ruby_prof/rp_call_info.c +369 -0
  8. data/ext/ruby_prof/rp_call_info.h +46 -0
  9. data/ext/ruby_prof/rp_measure.c +48 -0
  10. data/ext/ruby_prof/rp_measure.h +45 -0
  11. data/ext/ruby_prof/rp_measure_allocations.c +86 -0
  12. data/ext/ruby_prof/rp_measure_cpu_time.c +112 -0
  13. data/ext/ruby_prof/rp_measure_gc_runs.c +87 -0
  14. data/ext/ruby_prof/rp_measure_gc_time.c +73 -0
  15. data/ext/ruby_prof/rp_measure_memory.c +81 -0
  16. data/ext/ruby_prof/rp_measure_process_time.c +71 -0
  17. data/ext/ruby_prof/rp_measure_wall_time.c +42 -0
  18. data/ext/ruby_prof/rp_method.c +363 -0
  19. data/ext/ruby_prof/rp_method.h +55 -0
  20. data/ext/ruby_prof/rp_stack.c +61 -0
  21. data/ext/ruby_prof/rp_stack.h +40 -0
  22. data/ext/ruby_prof/rp_thread.c +113 -0
  23. data/ext/ruby_prof/rp_thread.h +20 -0
  24. data/ext/ruby_prof/ruby_prof.c +259 -1398
  25. data/ext/ruby_prof/ruby_prof.h +54 -190
  26. data/ext/ruby_prof/version.h +6 -3
  27. data/lib/1.8/ruby_prof.so +0 -0
  28. data/lib/1.9/ruby_prof.exp +0 -0
  29. data/lib/1.9/ruby_prof.ilk +0 -0
  30. data/lib/1.9/ruby_prof.lib +0 -0
  31. data/lib/1.9/ruby_prof.pdb +0 -0
  32. data/lib/1.9/ruby_prof.so +0 -0
  33. data/lib/ruby-prof.rb +14 -11
  34. data/lib/ruby-prof/abstract_printer.rb +10 -0
  35. data/lib/ruby-prof/aggregate_call_info.rb +2 -0
  36. data/lib/ruby-prof/call_info.rb +2 -0
  37. data/lib/ruby-prof/call_stack_printer.rb +2 -4
  38. data/lib/ruby-prof/call_tree_printer.rb +1 -0
  39. data/lib/ruby-prof/compatibility.rb +134 -0
  40. data/lib/ruby-prof/dot_printer.rb +7 -7
  41. data/lib/ruby-prof/flat_printer.rb +7 -7
  42. data/lib/ruby-prof/flat_printer_with_line_numbers.rb +2 -5
  43. data/lib/ruby-prof/graph_html_printer.rb +4 -2
  44. data/lib/ruby-prof/graph_printer.rb +4 -3
  45. data/lib/ruby-prof/method_info.rb +2 -0
  46. data/lib/ruby-prof/multi_printer.rb +2 -0
  47. data/lib/ruby-prof/{result.rb → profile.rb} +3 -1
  48. data/lib/ruby-prof/rack.rb +1 -0
  49. data/lib/ruby-prof/symbol_to_proc.rb +2 -0
  50. data/lib/ruby-prof/task.rb +1 -0
  51. data/lib/ruby-prof/test.rb +2 -0
  52. data/lib/ruby_prof.exp +0 -0
  53. data/lib/ruby_prof.ilk +0 -0
  54. data/lib/ruby_prof.lib +0 -0
  55. data/lib/ruby_prof.pdb +0 -0
  56. data/lib/ruby_prof.so +0 -0
  57. data/lib/unprof.rb +2 -0
  58. data/test/aggregate_test.rb +8 -8
  59. data/test/basic_test.rb +3 -251
  60. data/test/bug_test.rb +6 -0
  61. data/test/duplicate_names_test.rb +2 -2
  62. data/test/dynamic_method_test.rb +61 -0
  63. data/test/enumerable_test.rb +2 -2
  64. data/test/exceptions_test.rb +4 -3
  65. data/test/exclude_threads_test.rb +2 -2
  66. data/test/exec_test.rb +3 -3
  67. data/test/line_number_test.rb +5 -5
  68. data/test/measure_allocations_test.rb +25 -0
  69. data/test/measure_cpu_time_test.rb +212 -0
  70. data/test/measure_gc_runs_test.rb +29 -0
  71. data/test/measure_gc_time_test.rb +29 -0
  72. data/test/measure_memory_test.rb +36 -0
  73. data/test/measure_process_time_test.rb +205 -0
  74. data/test/measure_wall_time_test.rb +209 -0
  75. data/test/method_elimination_test.rb +2 -2
  76. data/test/module_test.rb +3 -2
  77. data/test/multi_printer_test.rb +2 -2
  78. data/test/no_method_class_test.rb +3 -1
  79. data/test/prime_test.rb +3 -3
  80. data/test/printers_test.rb +106 -8
  81. data/test/recursive_test.rb +7 -6
  82. data/test/singleton_test.rb +2 -2
  83. data/test/stack_printer_test.rb +2 -3
  84. data/test/stack_test.rb +2 -2
  85. data/test/start_stop_test.rb +2 -2
  86. data/test/test_helper.rb +81 -0
  87. data/test/test_suite.rb +34 -29
  88. data/test/thread_test.rb +24 -23
  89. data/test/unique_call_path_test.rb +2 -2
  90. metadata +101 -69
  91. data/ext/ruby_prof/measure_allocations.h +0 -83
  92. data/ext/ruby_prof/measure_cpu_time.h +0 -152
  93. data/ext/ruby_prof/measure_gc_runs.h +0 -76
  94. data/ext/ruby_prof/measure_gc_time.h +0 -57
  95. data/ext/ruby_prof/measure_memory.h +0 -101
  96. data/ext/ruby_prof/measure_process_time.h +0 -63
  97. data/ext/ruby_prof/measure_wall_time.h +0 -53
  98. data/ext/ruby_prof/mingw/Rakefile +0 -23
  99. data/ext/ruby_prof/mingw/build.rake +0 -38
  100. data/rails/environment/profile.rb +0 -24
  101. data/rails/example/example_test.rb +0 -9
  102. data/rails/profile_test_helper.rb +0 -21
  103. data/test/current_failures_windows +0 -8
  104. data/test/measurement_test.rb +0 -132
  105. data/test/ruby-prof-bin +0 -20
@@ -0,0 +1,81 @@
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
+ /* :nodoc: */
5
+
6
+ #include "ruby_prof.h"
7
+
8
+ static VALUE cMeasureMemory;
9
+
10
+ #if defined(HAVE_RB_GC_ALLOCATED_SIZE)
11
+ #define TOGGLE_GC_STATS 1
12
+ #define MEASURE_GC_TIME_ENABLED Qtrue
13
+
14
+ static double
15
+ measure_memory()
16
+ {
17
+ #if defined(HAVE_LONG_LONG)
18
+ return NUM2LL(rb_gc_allocated_size() / 1024);
19
+ #else
20
+ return NUM2ULONG(rb_gc_allocated_size() / 1024);
21
+ #endif
22
+ }
23
+
24
+ #elif defined(HAVE_RB_GC_MALLOC_ALLOCATED_SIZE)
25
+
26
+ #define MEASURE_MEMORY_ENABLED Qtrue
27
+
28
+ static double
29
+ measure_memory()
30
+ {
31
+ return rb_gc_malloc_allocated_size() / 1024;
32
+ }
33
+
34
+
35
+ #elif defined(HAVE_RB_HEAP_TOTAL_MEM)
36
+
37
+ #define MEASURE_MEMORY_ENABLED Qtrue
38
+
39
+ static double
40
+ measure_memory()
41
+ {
42
+ return rb_heap_total_mem() / 1024;
43
+ }
44
+
45
+ #else
46
+
47
+ #define MEASURE_MEMORY_ENABLED Qfalse
48
+
49
+ static double
50
+ measure_memory()
51
+ {
52
+ return 0;
53
+ }
54
+
55
+ #endif
56
+
57
+ prof_measurer_t* prof_measurer_memory()
58
+ {
59
+ prof_measurer_t* measure = ALLOC(prof_measurer_t);
60
+ measure->measure = measure_memory;
61
+ return measure;
62
+ }
63
+
64
+ /* call-seq:
65
+ measure_process_time -> float
66
+
67
+ Returns the process time.*/
68
+ static VALUE
69
+ prof_measure_memory(VALUE self)
70
+ {
71
+ return rb_float_new(measure_memory());
72
+ }
73
+
74
+ void rp_init_measure_memory()
75
+ {
76
+ rb_define_const(mProf, "MEMORY", INT2NUM(MEASURE_MEMORY));
77
+ rb_define_const(mProf, "MEMORY_ENABLED", MEASURE_MEMORY_ENABLED);
78
+
79
+ cMeasureMemory = rb_define_class_under(mMeasure, "Memory", rb_cObject);
80
+ rb_define_singleton_method(cMeasureMemory, "measure", prof_measure_memory, 0);
81
+ }
@@ -0,0 +1,71 @@
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
+ #include <time.h>
6
+
7
+ static VALUE cMeasureProcessTime;
8
+
9
+ static double
10
+ measure_process_time()
11
+ {
12
+ #if defined(__linux__)
13
+ struct timespec clock;
14
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID , &clock);
15
+ return (clock.tv_sec * 1000000000 + clock.tv_nsec) / 1000000000.0;
16
+ #elif defined(_win32)
17
+ FILETIME createTime;
18
+ FILETIME exitTime;
19
+ FILETIME sysTime;
20
+ FILETIME cpuTime;
21
+
22
+ ULARGE_INTEGER sysTimeInt;
23
+ ULARGE_INTEGER cpuTimeInt;
24
+ ULONGLONG totalTime;
25
+
26
+ GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &cpuTime);
27
+
28
+ /* Doing this based on MSFT's recommendation in the FILETIME structure documentation at
29
+ http://msdn.microsoft.com/en-us/library/ms724284%28VS.85%29.aspx*/
30
+
31
+ sysTimeInt.LowPart = sysTime.dwLowDateTime;
32
+ sysTimeInt.HighPart = sysTime.dwHighDateTime;
33
+ cpuTimeInt.LowPart = cpuTime.dwLowDateTime;
34
+ cpuTimeInt.HighPart = cpuTime.dwHighDateTime;
35
+
36
+ totalTime = sysTimeInt.QuadPart + cpuTimeInt.QuadPart;
37
+
38
+ // Times are in 100-nanosecond time units. So instead of 10-9 use 10-7
39
+ return totalTime / 10000000.0;
40
+ #else
41
+ return ((double)clock()) / CLOCKS_PER_SEC;
42
+ #endif
43
+ }
44
+
45
+ /* call-seq:
46
+ measure_process_time -> float
47
+
48
+ Returns the process time.*/
49
+ static VALUE
50
+ prof_measure_process_time(VALUE self)
51
+ {
52
+ return rb_float_new(measure_process_time());
53
+ }
54
+
55
+ prof_measurer_t* prof_measurer_process_time()
56
+ {
57
+ prof_measurer_t* measure = ALLOC(prof_measurer_t);
58
+ measure->measure = measure_process_time;
59
+ return measure;
60
+ }
61
+
62
+
63
+ void rp_init_measure_process_time()
64
+ {
65
+ rb_define_const(mProf, "CLOCKS_PER_SEC", INT2NUM(CLOCKS_PER_SEC));
66
+ rb_define_const(mProf, "PROCESS_TIME", INT2NUM(MEASURE_PROCESS_TIME));
67
+ rb_define_const(mProf, "PROCESS_TIME_ENABLED", Qtrue);
68
+
69
+ cMeasureProcessTime = rb_define_class_under(mMeasure, "ProcessTime", rb_cObject);
70
+ rb_define_singleton_method(cMeasureProcessTime, "measure", prof_measure_process_time, 0);
71
+ }
@@ -0,0 +1,42 @@
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
+ /* :nodoc: */
5
+ #include "ruby_prof.h"
6
+
7
+ static VALUE cMeasureWallTime;
8
+
9
+ static double
10
+ measure_wall_time()
11
+ {
12
+ struct timeval tv;
13
+ gettimeofday(&tv, NULL);
14
+ return (tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.0;
15
+ }
16
+
17
+ prof_measurer_t* prof_measurer_wall_time()
18
+ {
19
+ prof_measurer_t* measure = ALLOC(prof_measurer_t);
20
+ measure->measure = measure_wall_time;
21
+ return measure;
22
+ }
23
+
24
+ /* Document-method: prof_measure_wall_time
25
+ call-seq:
26
+ measure_wall_time -> float
27
+
28
+ Returns the wall time.*/
29
+ static VALUE
30
+ prof_measure_wall_time(VALUE self)
31
+ {
32
+ return rb_float_new(measure_wall_time());
33
+ }
34
+
35
+ void rp_init_measure_wall_time()
36
+ {
37
+ rb_define_const(mProf, "WALL_TIME", INT2NUM(MEASURE_WALL_TIME));
38
+ rb_define_const(mProf, "WALL_TIME_ENABLED", Qtrue);
39
+
40
+ cMeasureWallTime = rb_define_class_under(mMeasure, "WallTime", rb_cObject);
41
+ rb_define_singleton_method(cMeasureWallTime, "measure", prof_measure_wall_time, 0);
42
+ }
@@ -0,0 +1,363 @@
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
+ VALUE cMethodInfo;
7
+
8
+ /* ================ Helper Functions =================*/
9
+ static VALUE
10
+ figure_singleton_name(VALUE klass)
11
+ {
12
+ VALUE result = Qnil;
13
+
14
+ /* We have come across a singleton object. First
15
+ figure out what it is attached to.*/
16
+ VALUE attached = rb_iv_get(klass, "__attached__");
17
+
18
+ /* Is this a singleton class acting as a metaclass? */
19
+ if (BUILTIN_TYPE(attached) == T_CLASS)
20
+ {
21
+ result = rb_str_new2("<Class::");
22
+ rb_str_append(result, rb_inspect(attached));
23
+ rb_str_cat2(result, ">");
24
+ }
25
+
26
+ /* Is this for singleton methods on a module? */
27
+ else if (BUILTIN_TYPE(attached) == T_MODULE)
28
+ {
29
+ result = rb_str_new2("<Module::");
30
+ rb_str_append(result, rb_inspect(attached));
31
+ rb_str_cat2(result, ">");
32
+ }
33
+
34
+ /* Is this for singleton methods on an object? */
35
+ else if (BUILTIN_TYPE(attached) == T_OBJECT)
36
+ {
37
+ /* Make sure to get the super class so that we don't
38
+ mistakenly grab a T_ICLASS which would lead to
39
+ unknown method errors. */
40
+ #ifdef HAVE_RB_CLASS_SUPERCLASS
41
+ // 1.9.3
42
+ VALUE super = rb_class_superclass(klass);
43
+ #else
44
+ # ifdef RCLASS_SUPER
45
+ VALUE super = rb_class_real(RCLASS_SUPER(klass));
46
+ # else
47
+ VALUE super = rb_class_real(RCLASS(klass)->super);
48
+ # endif
49
+ #endif
50
+ result = rb_str_new2("<Object::");
51
+ rb_str_append(result, rb_inspect(super));
52
+ rb_str_cat2(result, ">");
53
+ }
54
+
55
+ /* Ok, this could be other things like an array made put onto
56
+ a singleton object (yeah, it happens, see the singleton
57
+ objects test case). */
58
+ else
59
+ {
60
+ result = rb_inspect(klass);
61
+ }
62
+
63
+ return result;
64
+ }
65
+
66
+ static VALUE
67
+ klass_name(VALUE klass)
68
+ {
69
+ VALUE result = Qnil;
70
+
71
+ if (klass == 0 || klass == Qnil)
72
+ {
73
+ result = rb_str_new2("Global");
74
+ }
75
+ else if (BUILTIN_TYPE(klass) == T_MODULE)
76
+ {
77
+ result = rb_inspect(klass);
78
+ }
79
+ else if (BUILTIN_TYPE(klass) == T_CLASS && FL_TEST(klass, FL_SINGLETON))
80
+ {
81
+ result = figure_singleton_name(klass);
82
+ }
83
+ else if (BUILTIN_TYPE(klass) == T_CLASS)
84
+ {
85
+ result = rb_inspect(klass);
86
+ }
87
+ else
88
+ {
89
+ /* Should never happen. */
90
+ result = rb_str_new2("Unknown");
91
+ }
92
+
93
+ return result;
94
+ }
95
+
96
+ static VALUE
97
+ method_name(ID mid)
98
+ {
99
+ VALUE result;
100
+
101
+ if (mid == ID_ALLOCATOR)
102
+ result = rb_str_new2("allocate");
103
+ else if (mid == 0)
104
+ result = rb_str_new2("[No method]");
105
+ else
106
+ result = rb_String(ID2SYM(mid));
107
+
108
+ return result;
109
+ }
110
+
111
+ static VALUE
112
+ full_name(VALUE klass, ID mid)
113
+ {
114
+ VALUE result = klass_name(klass);
115
+ rb_str_cat2(result, "#");
116
+ rb_str_append(result, method_name(mid));
117
+
118
+ return result;
119
+ }
120
+
121
+
122
+ /* ================ Method Table =================*/
123
+ int
124
+ method_table_cmp(prof_method_key_t *key1, prof_method_key_t *key2)
125
+ {
126
+ return (key1->klass != key2->klass) || (key1->mid != key2->mid);
127
+ }
128
+
129
+ st_index_t
130
+ method_table_hash(prof_method_key_t *key)
131
+ {
132
+ return key->key;
133
+ }
134
+
135
+ struct st_hash_type type_method_hash = {
136
+ method_table_cmp,
137
+ method_table_hash
138
+ };
139
+
140
+ st_table *
141
+ method_table_create()
142
+ {
143
+ return st_init_table(&type_method_hash);
144
+ }
145
+
146
+ size_t
147
+ method_table_insert(st_table *table, const prof_method_key_t *key, prof_method_t *val)
148
+ {
149
+ return st_insert(table, (st_data_t) key, (st_data_t) val);
150
+ }
151
+
152
+ prof_method_t *
153
+ method_table_lookup(st_table *table, const prof_method_key_t* key)
154
+ {
155
+ st_data_t val;
156
+ if (st_lookup(table, (st_data_t)key, &val))
157
+ {
158
+ return (prof_method_t *) val;
159
+ }
160
+ else
161
+ {
162
+ return NULL;
163
+ }
164
+ }
165
+
166
+ void
167
+ method_table_free(st_table *table)
168
+ {
169
+ /* Don't free the contents since they are wrapped by
170
+ Ruby objects! */
171
+ st_free_table(table);
172
+ }
173
+
174
+
175
+ /* ================ Method Info =================*/
176
+ /* Document-class: RubyProf::MethodInfo
177
+ The RubyProf::MethodInfo class stores profiling data for a method.
178
+ One instance of the RubyProf::MethodInfo class is created per method
179
+ called per thread. Thus, if a method is called in two different
180
+ thread then there will be two RubyProf::MethodInfo objects
181
+ created. RubyProf::MethodInfo objects can be accessed via
182
+ the RubyProf::Result object.
183
+ */
184
+
185
+ prof_method_t*
186
+ prof_method_create(prof_method_key_t *key, const char* source_file, int line)
187
+ {
188
+ prof_method_t *result = ALLOC(prof_method_t);
189
+ result->object = Qnil;
190
+ result->key = ALLOC(prof_method_key_t);
191
+ method_key(result->key, key->klass, key->mid);
192
+
193
+ result->call_infos = prof_call_infos_create();
194
+
195
+ if (source_file != NULL)
196
+ {
197
+ size_t len = strlen(source_file) + 1;
198
+ char *buffer = ALLOC_N(char, len);
199
+
200
+ MEMCPY(buffer, source_file, char, len);
201
+ result->source_file = buffer;
202
+ }
203
+ else
204
+ {
205
+ result->source_file = source_file;
206
+ }
207
+ result->line = line;
208
+
209
+ return result;
210
+ }
211
+
212
+ void
213
+ prof_method_mark(prof_method_t *method)
214
+ {
215
+ rb_gc_mark(method->call_infos->object);
216
+ rb_gc_mark(method->key->klass);
217
+ }
218
+
219
+ static void
220
+ prof_method_free(prof_method_t *method)
221
+ {
222
+ if (method->source_file)
223
+ {
224
+ xfree((char*)method->source_file);
225
+ }
226
+
227
+ prof_call_infos_free(method->call_infos);
228
+ xfree(method->key);
229
+ xfree(method);
230
+ }
231
+
232
+ VALUE
233
+ prof_method_wrap(prof_method_t *result)
234
+ {
235
+ if (result->object == Qnil)
236
+ {
237
+ result->object = Data_Wrap_Struct(cMethodInfo, prof_method_mark, prof_method_free, result);
238
+ }
239
+ return result->object;
240
+ }
241
+
242
+ static prof_method_t *
243
+ get_prof_method(VALUE obj)
244
+ {
245
+ return (prof_method_t *) DATA_PTR(obj);
246
+ }
247
+
248
+ /* call-seq:
249
+ line_no -> int
250
+
251
+ returns the line number of the method */
252
+ static VALUE
253
+ prof_method_line(VALUE self)
254
+ {
255
+ return rb_int_new(get_prof_method(self)->line);
256
+ }
257
+
258
+ /* call-seq:
259
+ source_file => string
260
+
261
+ return the source file of the method
262
+ */
263
+ static VALUE prof_method_source_file(VALUE self)
264
+ {
265
+ const char* sf = get_prof_method(self)->source_file;
266
+ if(!sf)
267
+ {
268
+ return rb_str_new2("ruby_runtime");
269
+ }
270
+ else
271
+ {
272
+ return rb_str_new2(sf);
273
+ }
274
+ }
275
+
276
+
277
+ /* call-seq:
278
+ method_class -> klass
279
+
280
+ Returns the Ruby klass that owns this method. */
281
+ static VALUE
282
+ prof_method_klass(VALUE self)
283
+ {
284
+ prof_method_t *result = get_prof_method(self);
285
+ return result->key->klass;
286
+ }
287
+
288
+ /* call-seq:
289
+ method_id -> ID
290
+
291
+ Returns the id of this method. */
292
+ static VALUE
293
+ prof_method_id(VALUE self)
294
+ {
295
+ prof_method_t *result = get_prof_method(self);
296
+ return ID2SYM(result->key->mid);
297
+ }
298
+
299
+ /* call-seq:
300
+ klass_name -> string
301
+
302
+ Returns the name of this method's class. Singleton classes
303
+ will have the form <Object::Object>. */
304
+
305
+ static VALUE
306
+ prof_klass_name(VALUE self)
307
+ {
308
+ prof_method_t *method = get_prof_method(self);
309
+ return klass_name(method->key->klass);
310
+ }
311
+
312
+ /* call-seq:
313
+ method_name -> string
314
+
315
+ Returns the name of this method in the format Object#method. Singletons
316
+ methods will be returned in the format <Object::Object>#method.*/
317
+
318
+ static VALUE
319
+ prof_method_name(VALUE self)
320
+ {
321
+ prof_method_t *method = get_prof_method(self);
322
+ return method_name(method->key->mid);
323
+ }
324
+
325
+ /* call-seq:
326
+ full_name -> string
327
+
328
+ Returns the full name of this method in the format Object#method.*/
329
+
330
+ static VALUE
331
+ prof_full_name(VALUE self)
332
+ {
333
+ prof_method_t *method = get_prof_method(self);
334
+ return full_name(method->key->klass, method->key->mid);
335
+ }
336
+
337
+ /* call-seq:
338
+ call_infos -> Array of call_info
339
+
340
+ Returns an array of call info objects that contain profiling information
341
+ about the current method.*/
342
+ static VALUE
343
+ prof_method_call_infos(VALUE self)
344
+ {
345
+ prof_method_t *method = get_prof_method(self);
346
+ return prof_call_infos_wrap(method->call_infos);
347
+ }
348
+
349
+ void rp_init_method_info()
350
+ {
351
+ /* MethodInfo */
352
+ cMethodInfo = rb_define_class_under(mProf, "MethodInfo", rb_cObject);
353
+ rb_undef_method(CLASS_OF(cMethodInfo), "new");
354
+
355
+ rb_define_method(cMethodInfo, "klass", prof_method_klass, 0);
356
+ rb_define_method(cMethodInfo, "klass_name", prof_klass_name, 0);
357
+ rb_define_method(cMethodInfo, "method_name", prof_method_name, 0);
358
+ rb_define_method(cMethodInfo, "full_name", prof_full_name, 0);
359
+ rb_define_method(cMethodInfo, "method_id", prof_method_id, 0);
360
+ rb_define_method(cMethodInfo, "source_file", prof_method_source_file,0);
361
+ rb_define_method(cMethodInfo, "line", prof_method_line, 0);
362
+ rb_define_method(cMethodInfo, "call_infos", prof_method_call_infos, 0);
363
+ }