ruby-prof 0.16.2 → 1.1.0
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.
- checksums.yaml +5 -5
- data/CHANGES +532 -467
- data/LICENSE +24 -24
- data/README.rdoc +5 -454
- data/Rakefile +110 -113
- data/bin/ruby-prof +380 -340
- data/bin/ruby-prof-check-trace +45 -45
- data/ext/ruby_prof/extconf.rb +36 -64
- data/ext/ruby_prof/rp_allocation.c +279 -0
- data/ext/ruby_prof/rp_allocation.h +31 -0
- data/ext/ruby_prof/rp_call_info.c +271 -407
- data/ext/ruby_prof/rp_call_info.h +35 -48
- data/ext/ruby_prof/rp_measure_allocations.c +52 -76
- data/ext/ruby_prof/rp_measure_memory.c +42 -77
- data/ext/ruby_prof/rp_measure_process_time.c +67 -71
- data/ext/ruby_prof/rp_measure_wall_time.c +62 -45
- data/ext/ruby_prof/rp_measurement.c +230 -0
- data/ext/ruby_prof/rp_measurement.h +50 -0
- data/ext/ruby_prof/rp_method.c +630 -411
- data/ext/ruby_prof/rp_method.h +70 -52
- data/ext/ruby_prof/rp_profile.c +895 -0
- data/ext/ruby_prof/rp_profile.h +37 -0
- data/ext/ruby_prof/rp_stack.c +196 -128
- data/ext/ruby_prof/rp_stack.h +56 -51
- data/ext/ruby_prof/rp_thread.c +337 -273
- data/ext/ruby_prof/rp_thread.h +36 -27
- data/ext/ruby_prof/ruby_prof.c +48 -671
- data/ext/ruby_prof/ruby_prof.h +17 -56
- data/ext/ruby_prof/vc/ruby_prof.sln +20 -21
- data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +38 -5
- data/lib/ruby-prof.rb +52 -58
- data/lib/ruby-prof/assets/call_stack_printer.html.erb +713 -0
- data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
- data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
- data/lib/ruby-prof/call_info.rb +57 -126
- data/lib/ruby-prof/call_info_visitor.rb +38 -40
- data/lib/ruby-prof/compatibility.rb +109 -178
- data/lib/ruby-prof/exclude_common_methods.rb +198 -0
- data/lib/ruby-prof/measurement.rb +14 -0
- data/lib/ruby-prof/method_info.rb +90 -129
- data/lib/ruby-prof/printers/abstract_printer.rb +127 -85
- data/lib/ruby-prof/printers/call_info_printer.rb +51 -41
- data/lib/ruby-prof/printers/call_stack_printer.rb +182 -260
- data/lib/ruby-prof/printers/call_tree_printer.rb +151 -130
- data/lib/ruby-prof/printers/dot_printer.rb +132 -132
- data/lib/ruby-prof/printers/flat_printer.rb +52 -70
- data/lib/ruby-prof/printers/graph_html_printer.rb +63 -244
- data/lib/ruby-prof/printers/graph_printer.rb +114 -116
- data/lib/ruby-prof/printers/multi_printer.rb +127 -58
- data/lib/ruby-prof/profile.rb +33 -55
- data/lib/ruby-prof/rack.rb +171 -95
- data/lib/ruby-prof/task.rb +147 -147
- data/lib/ruby-prof/thread.rb +35 -41
- data/lib/ruby-prof/version.rb +3 -3
- data/lib/unprof.rb +10 -10
- data/ruby-prof.gemspec +58 -57
- data/test/abstract_printer_test.rb +26 -0
- data/test/alias_test.rb +129 -0
- data/test/basic_test.rb +129 -128
- data/test/call_info_visitor_test.rb +31 -31
- data/test/duplicate_names_test.rb +32 -32
- data/test/dynamic_method_test.rb +53 -55
- data/test/enumerable_test.rb +21 -21
- data/test/exceptions_test.rb +24 -16
- data/test/exclude_methods_test.rb +146 -0
- data/test/exclude_threads_test.rb +53 -53
- data/test/fiber_test.rb +73 -79
- data/test/gc_test.rb +96 -0
- data/test/line_number_test.rb +161 -71
- data/test/marshal_test.rb +119 -0
- data/test/measure_allocations.rb +30 -0
- data/test/measure_allocations_test.rb +385 -26
- data/test/measure_allocations_trace_test.rb +385 -0
- data/test/measure_memory_trace_test.rb +756 -0
- data/test/measure_process_time_test.rb +849 -63
- data/test/measure_times.rb +54 -0
- data/test/measure_wall_time_test.rb +459 -255
- data/test/multi_printer_test.rb +71 -83
- data/test/no_method_class_test.rb +15 -15
- data/test/parser_timings.rb +24 -0
- data/test/pause_resume_test.rb +166 -166
- data/test/prime.rb +56 -54
- data/test/printer_call_stack_test.rb +28 -0
- data/test/printer_call_tree_test.rb +31 -0
- data/test/printer_flat_test.rb +68 -0
- data/test/printer_graph_html_test.rb +60 -0
- data/test/printer_graph_test.rb +41 -0
- data/test/printers_test.rb +141 -255
- data/test/printing_recursive_graph_test.rb +81 -127
- data/test/rack_test.rb +157 -93
- data/test/recursive_test.rb +210 -215
- data/test/singleton_test.rb +38 -38
- data/test/stack_printer_test.rb +64 -78
- data/test/start_stop_test.rb +109 -112
- data/test/test_helper.rb +24 -264
- data/test/thread_test.rb +144 -187
- data/test/unique_call_path_test.rb +190 -202
- data/test/yarv_test.rb +56 -55
- metadata +34 -114
- data/doc/LICENSE.html +0 -114
- data/doc/README_rdoc.html +0 -603
- data/doc/Rack.html +0 -95
- data/doc/Rack/RubyProf.html +0 -226
- data/doc/RubyProf.html +0 -962
- data/doc/RubyProf/AbstractPrinter.html +0 -546
- data/doc/RubyProf/AggregateCallInfo.html +0 -551
- data/doc/RubyProf/CallInfo.html +0 -639
- data/doc/RubyProf/CallInfoPrinter.html +0 -120
- data/doc/RubyProf/CallInfoVisitor.html +0 -198
- data/doc/RubyProf/CallStackPrinter.html +0 -1121
- data/doc/RubyProf/CallTreePrinter.html +0 -641
- data/doc/RubyProf/Cmd.html +0 -631
- data/doc/RubyProf/DotPrinter.html +0 -257
- data/doc/RubyProf/FlatPrinter.html +0 -163
- data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -208
- data/doc/RubyProf/GraphHtmlPrinter.html +0 -552
- data/doc/RubyProf/GraphPrinter.html +0 -139
- data/doc/RubyProf/MethodInfo.html +0 -745
- data/doc/RubyProf/MultiPrinter.html +0 -360
- data/doc/RubyProf/Profile.html +0 -763
- data/doc/RubyProf/ProfileTask.html +0 -490
- data/doc/RubyProf/Thread.html +0 -310
- data/doc/created.rid +0 -31
- data/doc/css/fonts.css +0 -167
- data/doc/css/rdoc.css +0 -590
- data/doc/examples/flat_txt.html +0 -138
- data/doc/examples/graph_html.html +0 -909
- data/doc/examples/graph_txt.html +0 -247
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +0 -626
- data/doc/js/darkfish.js +0 -161
- data/doc/js/jquery.js +0 -4
- data/doc/js/navigation.js +0 -142
- data/doc/js/navigation.js.gz +0 -0
- data/doc/js/search.js +0 -109
- data/doc/js/search_index.js +0 -1
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js +0 -228
- data/doc/js/searcher.js.gz +0 -0
- data/doc/table_of_contents.html +0 -942
- data/examples/cachegrind.out.1 +0 -114
- data/examples/cachegrind.out.1.32313213 +0 -114
- data/examples/flat.txt +0 -50
- data/examples/graph.dot +0 -84
- data/examples/graph.html +0 -823
- data/examples/graph.txt +0 -139
- data/examples/multi.flat.txt +0 -23
- data/examples/multi.graph.html +0 -760
- data/examples/multi.grind.dat +0 -114
- data/examples/multi.stack.html +0 -547
- data/examples/stack.html +0 -547
- data/ext/ruby_prof/rp_measure.c +0 -40
- data/ext/ruby_prof/rp_measure.h +0 -45
- data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
- data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
- data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
- data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +0 -108
- data/ext/ruby_prof/vc/ruby_prof_19.vcxproj +0 -110
- data/lib/ruby-prof/aggregate_call_info.rb +0 -76
- data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
- data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -64
- data/test/aggregate_test.rb +0 -136
- data/test/block_test.rb +0 -74
- data/test/call_info_test.rb +0 -78
- data/test/issue137_test.rb +0 -63
- data/test/measure_cpu_time_test.rb +0 -213
- data/test/measure_gc_runs_test.rb +0 -32
- data/test/measure_gc_time_test.rb +0 -36
- data/test/measure_memory_test.rb +0 -33
- data/test/method_elimination_test.rb +0 -84
- data/test/module_test.rb +0 -45
- data/test/stack_test.rb +0 -138
@@ -0,0 +1,31 @@
|
|
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
|
+
#ifndef _RP_ALLOCATION_
|
5
|
+
#define _RP_ALLOCATION_
|
6
|
+
|
7
|
+
#include "ruby_prof.h"
|
8
|
+
#include "rp_method.h"
|
9
|
+
|
10
|
+
typedef struct
|
11
|
+
{
|
12
|
+
st_data_t key; /* Key in hash table */
|
13
|
+
unsigned int klass_flags; /* Information about the type of class */
|
14
|
+
VALUE klass; /* Klass that was created */
|
15
|
+
VALUE klass_name; /* Name of the class that was created */
|
16
|
+
VALUE source_file; /* Line number where allocation happens */
|
17
|
+
int source_line; /* Line number where allocation happens */
|
18
|
+
int count; /* Number of allocations */
|
19
|
+
size_t memory; /* Amount of allocated memory */
|
20
|
+
VALUE object; /* Cache to wrapped object */
|
21
|
+
} prof_allocation_t;
|
22
|
+
|
23
|
+
void rp_init_allocation(void);
|
24
|
+
void prof_allocation_free(prof_allocation_t* allocation);
|
25
|
+
void prof_allocation_mark(void *data);
|
26
|
+
VALUE prof_allocation_wrap(prof_allocation_t* allocation);
|
27
|
+
prof_allocation_t* prof_allocation_get(VALUE self);
|
28
|
+
prof_allocation_t* prof_allocate_increment(prof_method_t *method, rb_trace_arg_t *trace_arg);
|
29
|
+
|
30
|
+
|
31
|
+
#endif //_RP_ALLOCATION_
|
@@ -1,407 +1,271 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
2
|
-
Please see the LICENSE file for copyright and distribution information */
|
3
|
-
|
4
|
-
#include "
|
5
|
-
|
6
|
-
#define INITIAL_CALL_INFOS_SIZE 2
|
7
|
-
|
8
|
-
VALUE
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
result->
|
21
|
-
|
22
|
-
result->
|
23
|
-
result->
|
24
|
-
result->
|
25
|
-
|
26
|
-
result
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
call_info->
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
}
|
152
|
-
|
153
|
-
/* call-seq:
|
154
|
-
called
|
155
|
-
|
156
|
-
|
157
|
-
static VALUE
|
158
|
-
|
159
|
-
{
|
160
|
-
prof_call_info_t *
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
static VALUE
|
192
|
-
|
193
|
-
{
|
194
|
-
prof_call_info_t
|
195
|
-
return
|
196
|
-
}
|
197
|
-
|
198
|
-
/* call-seq:
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
static VALUE
|
203
|
-
|
204
|
-
{
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
prof_call_info_t *result = prof_get_call_info(self);
|
273
|
-
if (result->parent)
|
274
|
-
return prof_call_info_wrap(result->parent);
|
275
|
-
else
|
276
|
-
return Qnil;
|
277
|
-
}
|
278
|
-
|
279
|
-
/* call-seq:
|
280
|
-
parent=new_parent -> new_parent
|
281
|
-
|
282
|
-
Changes the parent of self to new_parent and returns it.*/
|
283
|
-
static VALUE
|
284
|
-
prof_call_info_set_parent(VALUE self, VALUE new_parent)
|
285
|
-
{
|
286
|
-
prof_call_info_t *result = prof_get_call_info(self);
|
287
|
-
if (new_parent == Qnil)
|
288
|
-
result->parent = NULL;
|
289
|
-
else
|
290
|
-
result->parent = prof_get_call_info(new_parent);
|
291
|
-
return prof_call_info_parent(self);
|
292
|
-
}
|
293
|
-
|
294
|
-
static int
|
295
|
-
prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result)
|
296
|
-
{
|
297
|
-
prof_call_info_t *call_info = (prof_call_info_t *) value;
|
298
|
-
VALUE arr = (VALUE) result;
|
299
|
-
rb_ary_push(arr, prof_call_info_wrap(call_info));
|
300
|
-
return ST_CONTINUE;
|
301
|
-
}
|
302
|
-
|
303
|
-
/* call-seq:
|
304
|
-
children -> hash
|
305
|
-
|
306
|
-
Returns an array of call info objects of methods that this method
|
307
|
-
called (ie, children).*/
|
308
|
-
static VALUE
|
309
|
-
prof_call_info_children(VALUE self)
|
310
|
-
{
|
311
|
-
prof_call_info_t *call_info = prof_get_call_info(self);
|
312
|
-
if (call_info->children == Qnil)
|
313
|
-
{
|
314
|
-
call_info->children = rb_ary_new();
|
315
|
-
st_foreach(call_info->call_infos, prof_call_info_collect_children, call_info->children);
|
316
|
-
}
|
317
|
-
return call_info->children;
|
318
|
-
}
|
319
|
-
|
320
|
-
/* ======= Call Infos ========*/
|
321
|
-
prof_call_infos_t*
|
322
|
-
prof_call_infos_create()
|
323
|
-
{
|
324
|
-
prof_call_infos_t *result = ALLOC(prof_call_infos_t);
|
325
|
-
result->start = ALLOC_N(prof_call_info_t*, INITIAL_CALL_INFOS_SIZE);
|
326
|
-
result->end = result->start + INITIAL_CALL_INFOS_SIZE;
|
327
|
-
result->ptr = result->start;
|
328
|
-
result->object = Qnil;
|
329
|
-
return result;
|
330
|
-
}
|
331
|
-
|
332
|
-
void
|
333
|
-
prof_call_infos_mark(prof_call_infos_t *call_infos)
|
334
|
-
{
|
335
|
-
prof_call_info_t **call_info;
|
336
|
-
|
337
|
-
if (call_infos->object)
|
338
|
-
rb_gc_mark(call_infos->object);
|
339
|
-
|
340
|
-
for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
|
341
|
-
{
|
342
|
-
prof_call_info_mark(*call_info);
|
343
|
-
}
|
344
|
-
}
|
345
|
-
|
346
|
-
void
|
347
|
-
prof_call_infos_free(prof_call_infos_t *call_infos)
|
348
|
-
{
|
349
|
-
prof_call_info_t **call_info;
|
350
|
-
|
351
|
-
for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
|
352
|
-
{
|
353
|
-
prof_call_info_free(*call_info);
|
354
|
-
}
|
355
|
-
}
|
356
|
-
|
357
|
-
void
|
358
|
-
prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info)
|
359
|
-
{
|
360
|
-
if (call_infos->ptr == call_infos->end)
|
361
|
-
{
|
362
|
-
size_t len = call_infos->ptr - call_infos->start;
|
363
|
-
size_t new_capacity = (call_infos->end - call_infos->start) * 2;
|
364
|
-
REALLOC_N(call_infos->start, prof_call_info_t*, new_capacity);
|
365
|
-
call_infos->ptr = call_infos->start + len;
|
366
|
-
call_infos->end = call_infos->start + new_capacity;
|
367
|
-
}
|
368
|
-
*call_infos->ptr = call_info;
|
369
|
-
call_infos->ptr++;
|
370
|
-
}
|
371
|
-
|
372
|
-
VALUE
|
373
|
-
prof_call_infos_wrap(prof_call_infos_t *call_infos)
|
374
|
-
{
|
375
|
-
if (call_infos->object == Qnil)
|
376
|
-
{
|
377
|
-
prof_call_info_t **i;
|
378
|
-
call_infos->object = rb_ary_new();
|
379
|
-
for(i=call_infos->start; i<call_infos->ptr; i++)
|
380
|
-
{
|
381
|
-
VALUE call_info = prof_call_info_wrap(*i);
|
382
|
-
rb_ary_push(call_infos->object, call_info);
|
383
|
-
}
|
384
|
-
}
|
385
|
-
return call_infos->object;
|
386
|
-
}
|
387
|
-
|
388
|
-
void rp_init_call_info()
|
389
|
-
{
|
390
|
-
/* CallInfo */
|
391
|
-
cCallInfo = rb_define_class_under(mProf, "CallInfo", rb_cObject);
|
392
|
-
rb_undef_method(CLASS_OF(cCallInfo), "new");
|
393
|
-
rb_define_method(cCallInfo, "parent", prof_call_info_parent, 0);
|
394
|
-
rb_define_method(cCallInfo, "parent=", prof_call_info_set_parent, 1);
|
395
|
-
rb_define_method(cCallInfo, "children", prof_call_info_children, 0);
|
396
|
-
rb_define_method(cCallInfo, "target", prof_call_info_target, 0);
|
397
|
-
rb_define_method(cCallInfo, "called", prof_call_info_called, 0);
|
398
|
-
rb_define_method(cCallInfo, "called=", prof_call_info_set_called, 1);
|
399
|
-
rb_define_method(cCallInfo, "total_time", prof_call_info_total_time, 0);
|
400
|
-
rb_define_method(cCallInfo, "add_total_time", prof_call_info_add_total_time, 1);
|
401
|
-
rb_define_method(cCallInfo, "self_time", prof_call_info_self_time, 0);
|
402
|
-
rb_define_method(cCallInfo, "add_self_time", prof_call_info_add_self_time, 1);
|
403
|
-
rb_define_method(cCallInfo, "wait_time", prof_call_info_wait_time, 0);
|
404
|
-
rb_define_method(cCallInfo, "add_wait_time", prof_call_info_add_wait_time, 1);
|
405
|
-
rb_define_method(cCallInfo, "depth", prof_call_info_depth, 0);
|
406
|
-
rb_define_method(cCallInfo, "line", prof_call_info_line, 0);
|
407
|
-
}
|
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 "rp_call_info.h"
|
5
|
+
|
6
|
+
#define INITIAL_CALL_INFOS_SIZE 2
|
7
|
+
|
8
|
+
VALUE cRpCallnfo;
|
9
|
+
|
10
|
+
/* ======= prof_call_info_t ========*/
|
11
|
+
prof_call_info_t *
|
12
|
+
prof_call_info_create(prof_method_t *method, prof_method_t *parent, VALUE source_file, int source_line)
|
13
|
+
{
|
14
|
+
prof_call_info_t *result = ALLOC(prof_call_info_t);
|
15
|
+
result->method = method;
|
16
|
+
result->parent = parent;
|
17
|
+
result->object = Qnil;
|
18
|
+
result->measurement = prof_measurement_create();
|
19
|
+
|
20
|
+
result->visits = 0;
|
21
|
+
|
22
|
+
result->depth = 0;
|
23
|
+
result->source_line = source_line;
|
24
|
+
result->source_file = source_file;
|
25
|
+
|
26
|
+
return result;
|
27
|
+
}
|
28
|
+
|
29
|
+
static void
|
30
|
+
prof_call_info_ruby_gc_free(void *data)
|
31
|
+
{
|
32
|
+
prof_call_info_t *call_info = (prof_call_info_t*)data;
|
33
|
+
|
34
|
+
/* Has this call info object been accessed by Ruby? If
|
35
|
+
yes clean it up so to avoid a segmentation fault. */
|
36
|
+
if (call_info->object != Qnil)
|
37
|
+
{
|
38
|
+
RDATA(call_info->object)->dmark = NULL;
|
39
|
+
RDATA(call_info->object)->dfree = NULL;
|
40
|
+
RDATA(call_info->object)->data = NULL;
|
41
|
+
call_info->object = Qnil;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
void
|
46
|
+
prof_call_info_free(prof_call_info_t *call_info)
|
47
|
+
{
|
48
|
+
prof_measurement_free(call_info->measurement);
|
49
|
+
prof_call_info_ruby_gc_free(call_info);
|
50
|
+
xfree(call_info);
|
51
|
+
}
|
52
|
+
|
53
|
+
size_t
|
54
|
+
prof_call_info_size(const void *data)
|
55
|
+
{
|
56
|
+
return sizeof(prof_call_info_t);
|
57
|
+
}
|
58
|
+
|
59
|
+
void
|
60
|
+
prof_call_info_mark(void *data)
|
61
|
+
{
|
62
|
+
prof_call_info_t *call_info = (prof_call_info_t*)data;
|
63
|
+
|
64
|
+
if (call_info->source_file != Qnil)
|
65
|
+
rb_gc_mark(call_info->source_file);
|
66
|
+
|
67
|
+
if (call_info->object != Qnil)
|
68
|
+
rb_gc_mark(call_info->object);
|
69
|
+
|
70
|
+
if (call_info->method && call_info->method->object != Qnil)
|
71
|
+
rb_gc_mark(call_info->method->object);
|
72
|
+
|
73
|
+
if (call_info->parent && call_info->parent->object != Qnil)
|
74
|
+
rb_gc_mark(call_info->parent->object);
|
75
|
+
|
76
|
+
prof_measurement_mark(call_info->measurement);
|
77
|
+
}
|
78
|
+
|
79
|
+
VALUE
|
80
|
+
prof_call_info_wrap(prof_call_info_t *call_info)
|
81
|
+
{
|
82
|
+
if (call_info->object == Qnil)
|
83
|
+
{
|
84
|
+
call_info->object = Data_Wrap_Struct(cRpCallnfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
|
85
|
+
}
|
86
|
+
return call_info->object;
|
87
|
+
}
|
88
|
+
|
89
|
+
static VALUE
|
90
|
+
prof_call_info_allocate(VALUE klass)
|
91
|
+
{
|
92
|
+
prof_call_info_t* call_info = prof_call_info_create(NULL, NULL, Qnil, 0);
|
93
|
+
call_info->object = prof_call_info_wrap(call_info);
|
94
|
+
return call_info->object;
|
95
|
+
}
|
96
|
+
|
97
|
+
prof_call_info_t *
|
98
|
+
prof_get_call_info(VALUE self)
|
99
|
+
{
|
100
|
+
/* Can't use Data_Get_Struct because that triggers the event hook
|
101
|
+
ending up in endless recursion. */
|
102
|
+
prof_call_info_t* result = DATA_PTR(self);
|
103
|
+
|
104
|
+
if (!result)
|
105
|
+
rb_raise(rb_eRuntimeError, "This RubyProf::CallInfo instance has already been freed, likely because its profile has been freed.");
|
106
|
+
|
107
|
+
return result;
|
108
|
+
}
|
109
|
+
|
110
|
+
/* ======= Call Info Table ========*/
|
111
|
+
st_table *
|
112
|
+
call_info_table_create()
|
113
|
+
{
|
114
|
+
return st_init_numtable();
|
115
|
+
}
|
116
|
+
|
117
|
+
size_t
|
118
|
+
call_info_table_insert(st_table *table, st_data_t key, prof_call_info_t *val)
|
119
|
+
{
|
120
|
+
return st_insert(table, (st_data_t) key, (st_data_t) val);
|
121
|
+
}
|
122
|
+
|
123
|
+
prof_call_info_t *
|
124
|
+
call_info_table_lookup(st_table *table, st_data_t key)
|
125
|
+
{
|
126
|
+
st_data_t val;
|
127
|
+
if (st_lookup(table, (st_data_t) key, &val))
|
128
|
+
{
|
129
|
+
return (prof_call_info_t *) val;
|
130
|
+
}
|
131
|
+
else
|
132
|
+
{
|
133
|
+
return NULL;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
/* ======= RubyProf::CallInfo ========*/
|
138
|
+
|
139
|
+
/* call-seq:
|
140
|
+
parent -> call_info
|
141
|
+
|
142
|
+
Returns the call_infos parent call_info object (the method that called this method).*/
|
143
|
+
static VALUE
|
144
|
+
prof_call_info_parent(VALUE self)
|
145
|
+
{
|
146
|
+
prof_call_info_t* call_info = prof_get_call_info(self);
|
147
|
+
if (call_info->parent)
|
148
|
+
return prof_method_wrap(call_info->parent);
|
149
|
+
else
|
150
|
+
return Qnil;
|
151
|
+
}
|
152
|
+
|
153
|
+
/* call-seq:
|
154
|
+
called -> MethodInfo
|
155
|
+
|
156
|
+
Returns the target method. */
|
157
|
+
static VALUE
|
158
|
+
prof_call_info_target(VALUE self)
|
159
|
+
{
|
160
|
+
prof_call_info_t *call_info = prof_get_call_info(self);
|
161
|
+
return prof_method_wrap(call_info->method);
|
162
|
+
}
|
163
|
+
|
164
|
+
/* call-seq:
|
165
|
+
called -> Measurement
|
166
|
+
|
167
|
+
Returns the measurement associated with this call_info. */
|
168
|
+
static VALUE
|
169
|
+
prof_call_info_measurement(VALUE self)
|
170
|
+
{
|
171
|
+
prof_call_info_t* call_info = prof_get_call_info(self);
|
172
|
+
return prof_measurement_wrap(call_info->measurement);
|
173
|
+
}
|
174
|
+
|
175
|
+
/* call-seq:
|
176
|
+
depth -> int
|
177
|
+
|
178
|
+
returns the depth of this call info in the call graph */
|
179
|
+
static VALUE
|
180
|
+
prof_call_info_depth(VALUE self)
|
181
|
+
{
|
182
|
+
prof_call_info_t *result = prof_get_call_info(self);
|
183
|
+
return rb_int_new(result->depth);
|
184
|
+
}
|
185
|
+
|
186
|
+
/* call-seq:
|
187
|
+
source_file => string
|
188
|
+
|
189
|
+
return the source file of the method
|
190
|
+
*/
|
191
|
+
static VALUE
|
192
|
+
prof_call_info_source_file(VALUE self)
|
193
|
+
{
|
194
|
+
prof_call_info_t* result = prof_get_call_info(self);
|
195
|
+
return result->source_file;
|
196
|
+
}
|
197
|
+
|
198
|
+
/* call-seq:
|
199
|
+
line_no -> int
|
200
|
+
|
201
|
+
returns the line number of the method */
|
202
|
+
static VALUE
|
203
|
+
prof_call_info_line(VALUE self)
|
204
|
+
{
|
205
|
+
prof_call_info_t *result = prof_get_call_info(self);
|
206
|
+
return INT2FIX(result->source_line);
|
207
|
+
}
|
208
|
+
|
209
|
+
/* :nodoc: */
|
210
|
+
static VALUE
|
211
|
+
prof_call_info_dump(VALUE self)
|
212
|
+
{
|
213
|
+
prof_call_info_t* call_info_data = prof_get_call_info(self);
|
214
|
+
VALUE result = rb_hash_new();
|
215
|
+
|
216
|
+
rb_hash_aset(result, ID2SYM(rb_intern("measurement")), prof_measurement_wrap(call_info_data->measurement));
|
217
|
+
|
218
|
+
rb_hash_aset(result, ID2SYM(rb_intern("depth")), INT2FIX(call_info_data->depth));
|
219
|
+
rb_hash_aset(result, ID2SYM(rb_intern("source_file")), call_info_data->source_file);
|
220
|
+
rb_hash_aset(result, ID2SYM(rb_intern("source_line")), INT2FIX(call_info_data->source_line));
|
221
|
+
|
222
|
+
rb_hash_aset(result, ID2SYM(rb_intern("parent")), prof_call_info_parent(self));
|
223
|
+
rb_hash_aset(result, ID2SYM(rb_intern("target")), prof_call_info_target(self));
|
224
|
+
|
225
|
+
return result;
|
226
|
+
}
|
227
|
+
|
228
|
+
/* :nodoc: */
|
229
|
+
static VALUE
|
230
|
+
prof_call_info_load(VALUE self, VALUE data)
|
231
|
+
{
|
232
|
+
VALUE target = Qnil;
|
233
|
+
VALUE parent = Qnil;
|
234
|
+
prof_call_info_t* call_info = prof_get_call_info(self);
|
235
|
+
call_info->object = self;
|
236
|
+
|
237
|
+
VALUE measurement = rb_hash_aref(data, ID2SYM(rb_intern("measurement")));
|
238
|
+
call_info->measurement = prof_get_measurement(measurement);
|
239
|
+
|
240
|
+
call_info->depth = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("depth"))));
|
241
|
+
call_info->source_file = rb_hash_aref(data, ID2SYM(rb_intern("source_file")));
|
242
|
+
call_info->source_line = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("source_line"))));
|
243
|
+
|
244
|
+
parent = rb_hash_aref(data, ID2SYM(rb_intern("parent")));
|
245
|
+
if (parent != Qnil)
|
246
|
+
call_info->parent = prof_method_get(parent);
|
247
|
+
|
248
|
+
target = rb_hash_aref(data, ID2SYM(rb_intern("target")));
|
249
|
+
call_info->method = prof_method_get(target);
|
250
|
+
|
251
|
+
return data;
|
252
|
+
}
|
253
|
+
|
254
|
+
void rp_init_call_info()
|
255
|
+
{
|
256
|
+
/* CallInfo */
|
257
|
+
cRpCallnfo = rb_define_class_under(mProf, "CallInfo", rb_cData);
|
258
|
+
rb_undef_method(CLASS_OF(cRpCallnfo), "new");
|
259
|
+
rb_define_alloc_func(cRpCallnfo, prof_call_info_allocate);
|
260
|
+
|
261
|
+
rb_define_method(cRpCallnfo, "parent", prof_call_info_parent, 0);
|
262
|
+
rb_define_method(cRpCallnfo, "target", prof_call_info_target, 0);
|
263
|
+
rb_define_method(cRpCallnfo, "measurement", prof_call_info_measurement, 0);
|
264
|
+
|
265
|
+
rb_define_method(cRpCallnfo, "depth", prof_call_info_depth, 0);
|
266
|
+
rb_define_method(cRpCallnfo, "source_file", prof_call_info_source_file, 0);
|
267
|
+
rb_define_method(cRpCallnfo, "line", prof_call_info_line, 0);
|
268
|
+
|
269
|
+
rb_define_method(cRpCallnfo, "_dump_data", prof_call_info_dump, 0);
|
270
|
+
rb_define_method(cRpCallnfo, "_load_data", prof_call_info_load, 1);
|
271
|
+
}
|