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
@@ -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
+ }