ruby-prof 0.18.0 → 1.0.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 +4 -4
- data/CHANGES +23 -0
- data/LICENSE +2 -2
- data/README.rdoc +1 -483
- data/Rakefile +3 -6
- data/bin/ruby-prof +65 -30
- data/ext/ruby_prof/extconf.rb +6 -38
- data/ext/ruby_prof/rp_allocation.c +292 -0
- data/ext/ruby_prof/rp_allocation.h +31 -0
- data/ext/ruby_prof/rp_call_info.c +137 -279
- data/ext/ruby_prof/rp_call_info.h +16 -34
- data/ext/ruby_prof/rp_measure_allocations.c +25 -49
- data/ext/ruby_prof/rp_measure_memory.c +21 -56
- data/ext/ruby_prof/rp_measure_process_time.c +28 -36
- data/ext/ruby_prof/rp_measure_wall_time.c +36 -19
- data/ext/ruby_prof/rp_measurement.c +236 -0
- data/ext/ruby_prof/rp_measurement.h +49 -0
- data/ext/ruby_prof/rp_method.c +395 -383
- data/ext/ruby_prof/rp_method.h +34 -39
- data/ext/ruby_prof/rp_profile.c +881 -0
- data/ext/ruby_prof/rp_profile.h +36 -0
- data/ext/ruby_prof/rp_stack.c +103 -80
- data/ext/ruby_prof/rp_stack.h +5 -12
- data/ext/ruby_prof/rp_thread.c +149 -88
- data/ext/ruby_prof/rp_thread.h +15 -6
- data/ext/ruby_prof/ruby_prof.c +11 -757
- data/ext/ruby_prof/ruby_prof.h +4 -47
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +10 -8
- data/lib/ruby-prof.rb +2 -17
- data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
- data/lib/ruby-prof/call_info.rb +35 -93
- data/lib/ruby-prof/call_info_visitor.rb +19 -21
- data/lib/ruby-prof/compatibility.rb +37 -107
- 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 +52 -83
- data/lib/ruby-prof/printers/abstract_printer.rb +66 -52
- data/lib/ruby-prof/printers/call_info_printer.rb +13 -3
- data/lib/ruby-prof/printers/call_stack_printer.rb +32 -28
- data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
- data/lib/ruby-prof/printers/dot_printer.rb +5 -5
- data/lib/ruby-prof/printers/flat_printer.rb +6 -24
- data/lib/ruby-prof/printers/graph_html_printer.rb +7 -192
- data/lib/ruby-prof/printers/graph_printer.rb +13 -15
- data/lib/ruby-prof/printers/multi_printer.rb +66 -23
- data/lib/ruby-prof/profile.rb +10 -3
- data/lib/ruby-prof/rack.rb +0 -3
- data/lib/ruby-prof/thread.rb +12 -12
- data/lib/ruby-prof/version.rb +1 -1
- data/ruby-prof.gemspec +2 -2
- data/test/abstract_printer_test.rb +0 -27
- data/test/alias_test.rb +129 -0
- data/test/basic_test.rb +41 -40
- data/test/call_info_visitor_test.rb +3 -3
- data/test/dynamic_method_test.rb +0 -2
- data/test/line_number_test.rb +120 -39
- data/test/marshal_test.rb +119 -0
- data/test/measure_allocations.rb +30 -0
- data/test/measure_allocations_test.rb +371 -12
- 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 +821 -33
- data/test/measure_times.rb +54 -0
- data/test/measure_wall_time_test.rb +349 -145
- data/test/multi_printer_test.rb +1 -34
- data/test/parser_timings.rb +24 -0
- data/test/pause_resume_test.rb +5 -5
- data/test/prime.rb +2 -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 +32 -166
- data/test/printing_recursive_graph_test.rb +26 -72
- data/test/recursive_test.rb +72 -77
- data/test/stack_printer_test.rb +2 -15
- data/test/start_stop_test.rb +22 -25
- data/test/test_helper.rb +5 -248
- data/test/thread_test.rb +11 -54
- data/test/unique_call_path_test.rb +16 -28
- data/test/yarv_test.rb +1 -0
- metadata +24 -34
- 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/lib/ruby-prof/aggregate_call_info.rb +0 -76
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
- data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
- data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
- data/test/aggregate_test.rb +0 -136
- data/test/block_test.rb +0 -74
- data/test/call_info_test.rb +0 -78
- data/test/fiber_test.rb +0 -79
- data/test/issue137_test.rb +0 -63
- data/test/measure_cpu_time_test.rb +0 -212
- 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,44 +1,37 @@
|
|
1
1
|
/* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
|
-
#include "
|
4
|
+
#include "rp_call_info.h"
|
5
5
|
|
6
6
|
#define INITIAL_CALL_INFOS_SIZE 2
|
7
7
|
|
8
|
-
VALUE
|
9
|
-
|
10
|
-
|
11
|
-
// Forward declarations
|
12
|
-
st_table * call_info_table_create();
|
13
|
-
|
8
|
+
VALUE cRpCallnfo;
|
14
9
|
|
15
10
|
/* ======= prof_call_info_t ========*/
|
16
11
|
prof_call_info_t *
|
17
|
-
prof_call_info_create(prof_method_t*
|
12
|
+
prof_call_info_create(prof_method_t *method, prof_method_t *parent, VALUE source_file, int source_line)
|
18
13
|
{
|
19
14
|
prof_call_info_t *result = ALLOC(prof_call_info_t);
|
20
|
-
result->
|
21
|
-
result->target = method;
|
15
|
+
result->method = method;
|
22
16
|
result->parent = parent;
|
23
|
-
result->
|
24
|
-
result->
|
25
|
-
|
26
|
-
result->total_time = 0;
|
27
|
-
result->self_time = 0;
|
28
|
-
result->wait_time = 0;
|
17
|
+
result->object = Qnil;
|
18
|
+
result->measurement = prof_measurement_create();
|
29
19
|
|
30
|
-
result->
|
20
|
+
result->visits = 0;
|
31
21
|
|
32
|
-
result->recursive = 0;
|
33
22
|
result->depth = 0;
|
34
|
-
result->
|
23
|
+
result->source_line = source_line;
|
24
|
+
result->source_file = source_file;
|
35
25
|
|
36
26
|
return result;
|
37
27
|
}
|
28
|
+
|
38
29
|
static void
|
39
|
-
prof_call_info_ruby_gc_free(
|
30
|
+
prof_call_info_ruby_gc_free(void *data)
|
40
31
|
{
|
41
|
-
|
32
|
+
prof_call_info_t *call_info = (prof_call_info_t*)data;
|
33
|
+
|
34
|
+
/* Has this thread object been accessed by Ruby? If
|
42
35
|
yes clean it up so to avoid a segmentation fault. */
|
43
36
|
if (call_info->object != Qnil)
|
44
37
|
{
|
@@ -49,38 +42,71 @@ prof_call_info_ruby_gc_free(prof_call_info_t *call_info)
|
|
49
42
|
call_info->object = Qnil;
|
50
43
|
}
|
51
44
|
|
52
|
-
|
45
|
+
void
|
53
46
|
prof_call_info_free(prof_call_info_t *call_info)
|
54
47
|
{
|
55
|
-
|
56
|
-
|
57
|
-
xfree(call_info);
|
48
|
+
prof_call_info_ruby_gc_free(call_info);
|
49
|
+
xfree(call_info);
|
58
50
|
}
|
59
51
|
|
60
|
-
|
61
|
-
|
52
|
+
size_t
|
53
|
+
prof_call_info_size(const void *data)
|
62
54
|
{
|
63
|
-
|
55
|
+
return sizeof(prof_call_info_t);
|
56
|
+
}
|
57
|
+
|
58
|
+
void
|
59
|
+
prof_call_info_mark(void *data)
|
60
|
+
{
|
61
|
+
prof_call_info_t *call_info = (prof_call_info_t*)data;
|
62
|
+
|
63
|
+
if (call_info->source_file != Qnil)
|
64
|
+
rb_gc_mark(call_info->source_file);
|
65
|
+
|
66
|
+
if (call_info->object != Qnil)
|
64
67
|
rb_gc_mark(call_info->object);
|
65
68
|
|
66
|
-
|
67
|
-
|
69
|
+
if (call_info->method && call_info->method->object != Qnil)
|
70
|
+
rb_gc_mark(call_info->method->object);
|
68
71
|
|
69
|
-
|
70
|
-
|
72
|
+
if (call_info->parent && call_info->parent->object != Qnil)
|
73
|
+
rb_gc_mark(call_info->parent->object);
|
74
|
+
|
75
|
+
prof_measurement_mark(call_info->measurement);
|
71
76
|
}
|
72
77
|
|
78
|
+
static const rb_data_type_t call_info_type =
|
79
|
+
{
|
80
|
+
.wrap_struct_name = "CallInfo",
|
81
|
+
.function =
|
82
|
+
{
|
83
|
+
.dmark = prof_call_info_mark,
|
84
|
+
.dfree = prof_call_info_ruby_gc_free,
|
85
|
+
.dsize = prof_call_info_size,
|
86
|
+
},
|
87
|
+
.data = NULL,
|
88
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
89
|
+
};
|
90
|
+
|
73
91
|
VALUE
|
74
92
|
prof_call_info_wrap(prof_call_info_t *call_info)
|
75
93
|
{
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
94
|
+
if (call_info->object == Qnil)
|
95
|
+
{
|
96
|
+
call_info->object = TypedData_Wrap_Struct(cRpCallnfo, &call_info_type, call_info);
|
97
|
+
}
|
98
|
+
return call_info->object;
|
81
99
|
}
|
82
100
|
|
83
|
-
static
|
101
|
+
static VALUE
|
102
|
+
prof_call_info_allocate(VALUE klass)
|
103
|
+
{
|
104
|
+
prof_call_info_t* call_info = prof_call_info_create(NULL, NULL, Qnil, 0);
|
105
|
+
call_info->object = prof_call_info_wrap(call_info);
|
106
|
+
return call_info->object;
|
107
|
+
}
|
108
|
+
|
109
|
+
prof_call_info_t *
|
84
110
|
prof_get_call_info(VALUE self)
|
85
111
|
{
|
86
112
|
/* Can't use Data_Get_Struct because that triggers the event hook
|
@@ -97,17 +123,17 @@ prof_get_call_info(VALUE self)
|
|
97
123
|
st_table *
|
98
124
|
call_info_table_create()
|
99
125
|
{
|
100
|
-
|
126
|
+
return st_init_numtable();
|
101
127
|
}
|
102
128
|
|
103
129
|
size_t
|
104
|
-
call_info_table_insert(st_table *table,
|
130
|
+
call_info_table_insert(st_table *table, st_data_t key, prof_call_info_t *val)
|
105
131
|
{
|
106
132
|
return st_insert(table, (st_data_t) key, (st_data_t) val);
|
107
133
|
}
|
108
134
|
|
109
135
|
prof_call_info_t *
|
110
|
-
call_info_table_lookup(st_table *table,
|
136
|
+
call_info_table_lookup(st_table *table, st_data_t key)
|
111
137
|
{
|
112
138
|
st_data_t val;
|
113
139
|
if (st_lookup(table, (st_data_t) key, &val))
|
@@ -120,62 +146,42 @@ call_info_table_lookup(st_table *table, const prof_method_key_t *key)
|
|
120
146
|
}
|
121
147
|
}
|
122
148
|
|
123
|
-
|
124
149
|
/* ======= RubyProf::CallInfo ========*/
|
125
150
|
|
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
151
|
/* call-seq:
|
133
|
-
|
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
|
152
|
+
parent -> call_info
|
149
153
|
|
150
|
-
Returns the
|
154
|
+
Returns the call_infos parent call_info object (the method that called this method).*/
|
151
155
|
static VALUE
|
152
|
-
|
156
|
+
prof_call_info_parent(VALUE self)
|
153
157
|
{
|
154
|
-
prof_call_info_t
|
155
|
-
|
158
|
+
prof_call_info_t* call_info = prof_get_call_info(self);
|
159
|
+
if (call_info->parent)
|
160
|
+
return prof_method_wrap(call_info->parent);
|
161
|
+
else
|
162
|
+
return Qnil;
|
156
163
|
}
|
157
164
|
|
158
165
|
/* call-seq:
|
159
|
-
called
|
166
|
+
called -> MethodInfo
|
160
167
|
|
161
|
-
|
168
|
+
Returns the target method. */
|
162
169
|
static VALUE
|
163
|
-
|
170
|
+
prof_call_info_target(VALUE self)
|
164
171
|
{
|
165
|
-
prof_call_info_t *
|
166
|
-
|
167
|
-
return called;
|
172
|
+
prof_call_info_t *call_info = prof_get_call_info(self);
|
173
|
+
return prof_method_wrap(call_info->method);
|
168
174
|
}
|
169
175
|
|
170
176
|
/* call-seq:
|
171
|
-
|
177
|
+
called -> Measurement
|
172
178
|
|
173
|
-
|
179
|
+
Returns the measurement associated with this call_info. */
|
174
180
|
static VALUE
|
175
|
-
|
181
|
+
prof_call_info_measurement(VALUE self)
|
176
182
|
{
|
177
|
-
|
178
|
-
|
183
|
+
prof_call_info_t* call_info = prof_get_call_info(self);
|
184
|
+
return prof_measurement_wrap(call_info->measurement);
|
179
185
|
}
|
180
186
|
|
181
187
|
/* call-seq:
|
@@ -190,236 +196,88 @@ prof_call_info_depth(VALUE self)
|
|
190
196
|
}
|
191
197
|
|
192
198
|
/* call-seq:
|
193
|
-
|
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
|
199
|
+
source_file => string
|
230
200
|
|
231
|
-
|
201
|
+
return the source file of the method
|
202
|
+
*/
|
232
203
|
static VALUE
|
233
|
-
|
204
|
+
prof_call_info_source_file(VALUE self)
|
234
205
|
{
|
235
|
-
prof_call_info_t
|
236
|
-
|
237
|
-
return rb_float_new(result->self_time);
|
206
|
+
prof_call_info_t* result = prof_get_call_info(self);
|
207
|
+
return result->source_file;
|
238
208
|
}
|
239
209
|
|
240
210
|
/* call-seq:
|
241
|
-
|
211
|
+
line_no -> int
|
242
212
|
|
243
|
-
|
213
|
+
returns the line number of the method */
|
244
214
|
static VALUE
|
245
|
-
|
215
|
+
prof_call_info_line(VALUE self)
|
246
216
|
{
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
result->self_time += other_info->self_time;
|
251
|
-
return Qnil;
|
217
|
+
prof_call_info_t *result = prof_get_call_info(self);
|
218
|
+
return INT2FIX(result->source_line);
|
252
219
|
}
|
253
220
|
|
254
|
-
/*
|
255
|
-
wait_time -> float
|
256
|
-
|
257
|
-
Returns the total amount of time this method waited for other threads. */
|
221
|
+
/* :nodoc: */
|
258
222
|
static VALUE
|
259
|
-
|
223
|
+
prof_call_info_dump(VALUE self)
|
260
224
|
{
|
261
|
-
prof_call_info_t
|
225
|
+
prof_call_info_t* call_info_data = prof_get_call_info(self);
|
226
|
+
VALUE result = rb_hash_new();
|
262
227
|
|
263
|
-
|
264
|
-
}
|
228
|
+
rb_hash_aset(result, ID2SYM(rb_intern("measurement")), prof_measurement_wrap(call_info_data->measurement));
|
265
229
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
adds wait time from call_info to self. */
|
230
|
+
rb_hash_aset(result, ID2SYM(rb_intern("depth")), INT2FIX(call_info_data->depth));
|
231
|
+
rb_hash_aset(result, ID2SYM(rb_intern("source_file")), call_info_data->source_file);
|
232
|
+
rb_hash_aset(result, ID2SYM(rb_intern("source_line")), INT2FIX(call_info_data->source_line));
|
270
233
|
|
271
|
-
|
272
|
-
|
273
|
-
{
|
274
|
-
prof_call_info_t *result = prof_get_call_info(self);
|
275
|
-
prof_call_info_t *other_info = prof_get_call_info(other);
|
234
|
+
rb_hash_aset(result, ID2SYM(rb_intern("parent")), prof_call_info_parent(self));
|
235
|
+
rb_hash_aset(result, ID2SYM(rb_intern("target")), prof_call_info_target(self));
|
276
236
|
|
277
|
-
result
|
278
|
-
return Qnil;
|
237
|
+
return result;
|
279
238
|
}
|
280
239
|
|
281
|
-
/*
|
282
|
-
parent -> call_info
|
283
|
-
|
284
|
-
Returns the call_infos parent call_info object (the method that called this method).*/
|
240
|
+
/* :nodoc: */
|
285
241
|
static VALUE
|
286
|
-
|
242
|
+
prof_call_info_load(VALUE self, VALUE data)
|
287
243
|
{
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
return Qnil;
|
293
|
-
}
|
244
|
+
VALUE target = Qnil;
|
245
|
+
VALUE parent = Qnil;
|
246
|
+
prof_call_info_t* call_info = prof_get_call_info(self);
|
247
|
+
call_info->object = self;
|
294
248
|
|
295
|
-
|
296
|
-
|
249
|
+
VALUE measurement = rb_hash_aref(data, ID2SYM(rb_intern("measurement")));
|
250
|
+
call_info->measurement = prof_get_measurement(measurement);
|
297
251
|
|
298
|
-
|
299
|
-
|
300
|
-
|
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
|
-
}
|
252
|
+
call_info->depth = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("depth"))));
|
253
|
+
call_info->source_file = rb_hash_aref(data, ID2SYM(rb_intern("source_file")));
|
254
|
+
call_info->source_line = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("source_line"))));
|
309
255
|
|
310
|
-
|
311
|
-
|
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
|
-
}
|
256
|
+
parent = rb_hash_aref(data, ID2SYM(rb_intern("parent")));
|
257
|
+
if (parent != Qnil)
|
258
|
+
call_info->parent = prof_method_get(parent);
|
318
259
|
|
319
|
-
|
320
|
-
|
260
|
+
target = rb_hash_aref(data, ID2SYM(rb_intern("target")));
|
261
|
+
call_info->method = prof_method_get(target);
|
321
262
|
|
322
|
-
|
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;
|
263
|
+
return data;
|
334
264
|
}
|
335
265
|
|
336
|
-
|
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)
|
266
|
+
void rp_init_call_info()
|
364
267
|
{
|
365
|
-
|
268
|
+
/* CallInfo */
|
269
|
+
cRpCallnfo = rb_define_class_under(mProf, "CallInfo", rb_cData);
|
270
|
+
rb_undef_method(CLASS_OF(cRpCallnfo), "new");
|
271
|
+
rb_define_alloc_func(cRpCallnfo, prof_call_info_allocate);
|
366
272
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
}
|
371
|
-
}
|
273
|
+
rb_define_method(cRpCallnfo, "parent", prof_call_info_parent, 0);
|
274
|
+
rb_define_method(cRpCallnfo, "target", prof_call_info_target, 0);
|
275
|
+
rb_define_method(cRpCallnfo, "measurement", prof_call_info_measurement, 0);
|
372
276
|
|
373
|
-
|
374
|
-
|
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
|
-
}
|
277
|
+
rb_define_method(cRpCallnfo, "depth", prof_call_info_depth, 0);
|
278
|
+
rb_define_method(cRpCallnfo, "source_file", prof_call_info_source_file, 0);
|
279
|
+
rb_define_method(cRpCallnfo, "line", prof_call_info_line, 0);
|
387
280
|
|
388
|
-
|
389
|
-
|
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);
|
281
|
+
rb_define_method(cRpCallnfo, "_dump_data", prof_call_info_dump, 0);
|
282
|
+
rb_define_method(cRpCallnfo, "_load_data", prof_call_info_load, 1);
|
425
283
|
}
|