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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +23 -0
  3. data/LICENSE +2 -2
  4. data/README.rdoc +1 -483
  5. data/Rakefile +3 -6
  6. data/bin/ruby-prof +65 -30
  7. data/ext/ruby_prof/extconf.rb +6 -38
  8. data/ext/ruby_prof/rp_allocation.c +292 -0
  9. data/ext/ruby_prof/rp_allocation.h +31 -0
  10. data/ext/ruby_prof/rp_call_info.c +137 -279
  11. data/ext/ruby_prof/rp_call_info.h +16 -34
  12. data/ext/ruby_prof/rp_measure_allocations.c +25 -49
  13. data/ext/ruby_prof/rp_measure_memory.c +21 -56
  14. data/ext/ruby_prof/rp_measure_process_time.c +28 -36
  15. data/ext/ruby_prof/rp_measure_wall_time.c +36 -19
  16. data/ext/ruby_prof/rp_measurement.c +236 -0
  17. data/ext/ruby_prof/rp_measurement.h +49 -0
  18. data/ext/ruby_prof/rp_method.c +395 -383
  19. data/ext/ruby_prof/rp_method.h +34 -39
  20. data/ext/ruby_prof/rp_profile.c +881 -0
  21. data/ext/ruby_prof/rp_profile.h +36 -0
  22. data/ext/ruby_prof/rp_stack.c +103 -80
  23. data/ext/ruby_prof/rp_stack.h +5 -12
  24. data/ext/ruby_prof/rp_thread.c +149 -88
  25. data/ext/ruby_prof/rp_thread.h +15 -6
  26. data/ext/ruby_prof/ruby_prof.c +11 -757
  27. data/ext/ruby_prof/ruby_prof.h +4 -47
  28. data/ext/ruby_prof/vc/ruby_prof.vcxproj +10 -8
  29. data/lib/ruby-prof.rb +2 -17
  30. data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
  31. data/lib/ruby-prof/call_info.rb +35 -93
  32. data/lib/ruby-prof/call_info_visitor.rb +19 -21
  33. data/lib/ruby-prof/compatibility.rb +37 -107
  34. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  35. data/lib/ruby-prof/measurement.rb +14 -0
  36. data/lib/ruby-prof/method_info.rb +52 -83
  37. data/lib/ruby-prof/printers/abstract_printer.rb +66 -52
  38. data/lib/ruby-prof/printers/call_info_printer.rb +13 -3
  39. data/lib/ruby-prof/printers/call_stack_printer.rb +32 -28
  40. data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
  41. data/lib/ruby-prof/printers/dot_printer.rb +5 -5
  42. data/lib/ruby-prof/printers/flat_printer.rb +6 -24
  43. data/lib/ruby-prof/printers/graph_html_printer.rb +7 -192
  44. data/lib/ruby-prof/printers/graph_printer.rb +13 -15
  45. data/lib/ruby-prof/printers/multi_printer.rb +66 -23
  46. data/lib/ruby-prof/profile.rb +10 -3
  47. data/lib/ruby-prof/rack.rb +0 -3
  48. data/lib/ruby-prof/thread.rb +12 -12
  49. data/lib/ruby-prof/version.rb +1 -1
  50. data/ruby-prof.gemspec +2 -2
  51. data/test/abstract_printer_test.rb +0 -27
  52. data/test/alias_test.rb +129 -0
  53. data/test/basic_test.rb +41 -40
  54. data/test/call_info_visitor_test.rb +3 -3
  55. data/test/dynamic_method_test.rb +0 -2
  56. data/test/line_number_test.rb +120 -39
  57. data/test/marshal_test.rb +119 -0
  58. data/test/measure_allocations.rb +30 -0
  59. data/test/measure_allocations_test.rb +371 -12
  60. data/test/measure_allocations_trace_test.rb +385 -0
  61. data/test/measure_memory_trace_test.rb +756 -0
  62. data/test/measure_process_time_test.rb +821 -33
  63. data/test/measure_times.rb +54 -0
  64. data/test/measure_wall_time_test.rb +349 -145
  65. data/test/multi_printer_test.rb +1 -34
  66. data/test/parser_timings.rb +24 -0
  67. data/test/pause_resume_test.rb +5 -5
  68. data/test/prime.rb +2 -0
  69. data/test/printer_call_tree_test.rb +31 -0
  70. data/test/printer_flat_test.rb +68 -0
  71. data/test/printer_graph_html_test.rb +60 -0
  72. data/test/printer_graph_test.rb +41 -0
  73. data/test/printers_test.rb +32 -166
  74. data/test/printing_recursive_graph_test.rb +26 -72
  75. data/test/recursive_test.rb +72 -77
  76. data/test/stack_printer_test.rb +2 -15
  77. data/test/start_stop_test.rb +22 -25
  78. data/test/test_helper.rb +5 -248
  79. data/test/thread_test.rb +11 -54
  80. data/test/unique_call_path_test.rb +16 -28
  81. data/test/yarv_test.rb +1 -0
  82. metadata +24 -34
  83. data/examples/flat.txt +0 -50
  84. data/examples/graph.dot +0 -84
  85. data/examples/graph.html +0 -823
  86. data/examples/graph.txt +0 -139
  87. data/examples/multi.flat.txt +0 -23
  88. data/examples/multi.graph.html +0 -760
  89. data/examples/multi.grind.dat +0 -114
  90. data/examples/multi.stack.html +0 -547
  91. data/examples/stack.html +0 -547
  92. data/ext/ruby_prof/rp_measure.c +0 -40
  93. data/ext/ruby_prof/rp_measure.h +0 -45
  94. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  95. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  96. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  97. data/lib/ruby-prof/aggregate_call_info.rb +0 -76
  98. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
  99. data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
  100. data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
  101. data/test/aggregate_test.rb +0 -136
  102. data/test/block_test.rb +0 -74
  103. data/test/call_info_test.rb +0 -78
  104. data/test/fiber_test.rb +0 -79
  105. data/test/issue137_test.rb +0 -63
  106. data/test/measure_cpu_time_test.rb +0 -212
  107. data/test/measure_gc_runs_test.rb +0 -32
  108. data/test/measure_gc_time_test.rb +0 -36
  109. data/test/measure_memory_test.rb +0 -33
  110. data/test/method_elimination_test.rb +0 -84
  111. data/test/module_test.rb +0 -45
  112. 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 "ruby_prof.h"
4
+ #include "rp_call_info.h"
5
5
 
6
6
  #define INITIAL_CALL_INFOS_SIZE 2
7
7
 
8
- VALUE cCallInfo;
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* method, prof_call_info_t* parent)
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->object = Qnil;
21
- result->target = method;
15
+ result->method = method;
22
16
  result->parent = parent;
23
- result->call_infos = call_info_table_create();
24
- result->children = Qnil;
25
-
26
- result->total_time = 0;
27
- result->self_time = 0;
28
- result->wait_time = 0;
17
+ result->object = Qnil;
18
+ result->measurement = prof_measurement_create();
29
19
 
30
- result->called = 0;
20
+ result->visits = 0;
31
21
 
32
- result->recursive = 0;
33
22
  result->depth = 0;
34
- result->line = 0;
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(prof_call_info_t *call_info)
30
+ prof_call_info_ruby_gc_free(void *data)
40
31
  {
41
- /* Has this thread object been accessed by Ruby? If
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
- static void
45
+ void
53
46
  prof_call_info_free(prof_call_info_t *call_info)
54
47
  {
55
- prof_call_info_ruby_gc_free(call_info);
56
- st_free_table(call_info->call_infos);
57
- xfree(call_info);
48
+ prof_call_info_ruby_gc_free(call_info);
49
+ xfree(call_info);
58
50
  }
59
51
 
60
- static void
61
- prof_call_info_mark(prof_call_info_t *call_info)
52
+ size_t
53
+ prof_call_info_size(const void *data)
62
54
  {
63
- if (call_info->object)
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
- if (call_info->children)
67
- rb_gc_mark(call_info->children);
69
+ if (call_info->method && call_info->method->object != Qnil)
70
+ rb_gc_mark(call_info->method->object);
68
71
 
69
- /* We don't mark the call info child table since that will be done
70
- via the appropriate method */
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
- if (call_info->object == Qnil)
77
- {
78
- call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
79
- }
80
- return call_info->object;
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 prof_call_info_t *
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
- return st_init_table(&type_method_hash);
126
+ return st_init_numtable();
101
127
  }
102
128
 
103
129
  size_t
104
- call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val)
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, const prof_method_key_t *key)
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
- called -> MethodInfo
134
-
135
- Returns the target method. */
136
- static VALUE
137
- prof_call_info_target(VALUE self)
138
- {
139
- /* Target is a pointer to a method_info - so we have to be careful
140
- about the GC. We will wrap the method_info but provide no
141
- free method so the underlying object is not freed twice! */
142
-
143
- prof_call_info_t *result = prof_get_call_info(self);
144
- return prof_method_wrap(result->target);
145
- }
146
-
147
- /* call-seq:
148
- called -> int
152
+ parent -> call_info
149
153
 
150
- Returns the total amount of times this method was called. */
154
+ Returns the call_infos parent call_info object (the method that called this method).*/
151
155
  static VALUE
152
- prof_call_info_called(VALUE self)
156
+ prof_call_info_parent(VALUE self)
153
157
  {
154
- prof_call_info_t *result = prof_get_call_info(self);
155
- return INT2NUM(result->called);
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=n -> n
166
+ called -> MethodInfo
160
167
 
161
- Sets the call count to n. */
168
+ Returns the target method. */
162
169
  static VALUE
163
- prof_call_info_set_called(VALUE self, VALUE called)
170
+ prof_call_info_target(VALUE self)
164
171
  {
165
- prof_call_info_t *result = prof_get_call_info(self);
166
- result->called = NUM2INT(called);
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
- recursive? -> boolean
177
+ called -> Measurement
172
178
 
173
- Returns the true if this call info is a recursive invocation */
179
+ Returns the measurement associated with this call_info. */
174
180
  static VALUE
175
- prof_call_info_recursive(VALUE self)
181
+ prof_call_info_measurement(VALUE self)
176
182
  {
177
- prof_call_info_t *result = prof_get_call_info(self);
178
- return result->recursive ? Qtrue : Qfalse;
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
- line_no -> int
194
-
195
- returns the line number of the method */
196
- static VALUE
197
- prof_call_info_line(VALUE self)
198
- {
199
- prof_call_info_t *result = prof_get_call_info(self);
200
- return rb_int_new(result->line);
201
- }
202
-
203
- /* call-seq:
204
- total_time -> float
205
-
206
- Returns the total amount of time spent in this method and its children. */
207
- static VALUE
208
- prof_call_info_total_time(VALUE self)
209
- {
210
- prof_call_info_t *result = prof_get_call_info(self);
211
- return rb_float_new(result->total_time);
212
- }
213
-
214
- /* call-seq:
215
- add_total_time(call_info) -> nil
216
-
217
- adds total time time from call_info to self. */
218
- static VALUE
219
- prof_call_info_add_total_time(VALUE self, VALUE other)
220
- {
221
- prof_call_info_t *result = prof_get_call_info(self);
222
- prof_call_info_t *other_info = prof_get_call_info(other);
223
-
224
- result->total_time += other_info->total_time;
225
- return Qnil;
226
- }
227
-
228
- /* call-seq:
229
- self_time -> float
199
+ source_file => string
230
200
 
231
- Returns the total amount of time spent in this method. */
201
+ return the source file of the method
202
+ */
232
203
  static VALUE
233
- prof_call_info_self_time(VALUE self)
204
+ prof_call_info_source_file(VALUE self)
234
205
  {
235
- prof_call_info_t *result = prof_get_call_info(self);
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
- add_self_time(call_info) -> nil
211
+ line_no -> int
242
212
 
243
- adds self time from call_info to self. */
213
+ returns the line number of the method */
244
214
  static VALUE
245
- prof_call_info_add_self_time(VALUE self, VALUE other)
215
+ prof_call_info_line(VALUE self)
246
216
  {
247
- prof_call_info_t *result = prof_get_call_info(self);
248
- prof_call_info_t *other_info = prof_get_call_info(other);
249
-
250
- result->self_time += other_info->self_time;
251
- return Qnil;
217
+ prof_call_info_t *result = prof_get_call_info(self);
218
+ return INT2FIX(result->source_line);
252
219
  }
253
220
 
254
- /* call-seq:
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
- prof_call_info_wait_time(VALUE self)
223
+ prof_call_info_dump(VALUE self)
260
224
  {
261
- prof_call_info_t *result = prof_get_call_info(self);
225
+ prof_call_info_t* call_info_data = prof_get_call_info(self);
226
+ VALUE result = rb_hash_new();
262
227
 
263
- return rb_float_new(result->wait_time);
264
- }
228
+ rb_hash_aset(result, ID2SYM(rb_intern("measurement")), prof_measurement_wrap(call_info_data->measurement));
265
229
 
266
- /* call-seq:
267
- add_wait_time(call_info) -> nil
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
- static VALUE
272
- prof_call_info_add_wait_time(VALUE self, VALUE other)
273
- {
274
- prof_call_info_t *result = prof_get_call_info(self);
275
- prof_call_info_t *other_info = prof_get_call_info(other);
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->wait_time += other_info->wait_time;
278
- return Qnil;
237
+ return result;
279
238
  }
280
239
 
281
- /* call-seq:
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
- prof_call_info_parent(VALUE self)
242
+ prof_call_info_load(VALUE self, VALUE data)
287
243
  {
288
- prof_call_info_t *result = prof_get_call_info(self);
289
- if (result->parent)
290
- return prof_call_info_wrap(result->parent);
291
- else
292
- return Qnil;
293
- }
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
- /* call-seq:
296
- parent=new_parent -> new_parent
249
+ VALUE measurement = rb_hash_aref(data, ID2SYM(rb_intern("measurement")));
250
+ call_info->measurement = prof_get_measurement(measurement);
297
251
 
298
- Changes the parent of self to new_parent and returns it.*/
299
- static VALUE
300
- prof_call_info_set_parent(VALUE self, VALUE new_parent)
301
- {
302
- prof_call_info_t *result = prof_get_call_info(self);
303
- if (new_parent == Qnil)
304
- result->parent = NULL;
305
- else
306
- result->parent = prof_get_call_info(new_parent);
307
- return prof_call_info_parent(self);
308
- }
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
- static int
311
- prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result)
312
- {
313
- prof_call_info_t *call_info = (prof_call_info_t *) value;
314
- VALUE arr = (VALUE) result;
315
- rb_ary_push(arr, prof_call_info_wrap(call_info));
316
- return ST_CONTINUE;
317
- }
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
- /* call-seq:
320
- children -> hash
260
+ target = rb_hash_aref(data, ID2SYM(rb_intern("target")));
261
+ call_info->method = prof_method_get(target);
321
262
 
322
- Returns an array of call info objects of methods that this method
323
- called (ie, children).*/
324
- static VALUE
325
- prof_call_info_children(VALUE self)
326
- {
327
- prof_call_info_t *call_info = prof_get_call_info(self);
328
- if (call_info->children == Qnil)
329
- {
330
- call_info->children = rb_ary_new();
331
- st_foreach(call_info->call_infos, prof_call_info_collect_children, call_info->children);
332
- }
333
- return call_info->children;
263
+ return data;
334
264
  }
335
265
 
336
- /* ======= Call Infos ========*/
337
- prof_call_infos_t*
338
- prof_call_infos_create()
339
- {
340
- prof_call_infos_t *result = ALLOC(prof_call_infos_t);
341
- result->start = ALLOC_N(prof_call_info_t*, INITIAL_CALL_INFOS_SIZE);
342
- result->end = result->start + INITIAL_CALL_INFOS_SIZE;
343
- result->ptr = result->start;
344
- result->object = Qnil;
345
- return result;
346
- }
347
-
348
- void
349
- prof_call_infos_mark(prof_call_infos_t *call_infos)
350
- {
351
- prof_call_info_t **call_info;
352
-
353
- if (call_infos->object)
354
- rb_gc_mark(call_infos->object);
355
-
356
- for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
357
- {
358
- prof_call_info_mark(*call_info);
359
- }
360
- }
361
-
362
- void
363
- prof_call_infos_free(prof_call_infos_t *call_infos)
266
+ void rp_init_call_info()
364
267
  {
365
- prof_call_info_t **call_info;
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
- for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
368
- {
369
- prof_call_info_free(*call_info);
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
- void
374
- prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info)
375
- {
376
- if (call_infos->ptr == call_infos->end)
377
- {
378
- size_t len = call_infos->ptr - call_infos->start;
379
- size_t new_capacity = (call_infos->end - call_infos->start) * 2;
380
- REALLOC_N(call_infos->start, prof_call_info_t*, new_capacity);
381
- call_infos->ptr = call_infos->start + len;
382
- call_infos->end = call_infos->start + new_capacity;
383
- }
384
- *call_infos->ptr = call_info;
385
- call_infos->ptr++;
386
- }
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
- VALUE
389
- prof_call_infos_wrap(prof_call_infos_t *call_infos)
390
- {
391
- if (call_infos->object == Qnil)
392
- {
393
- prof_call_info_t **i;
394
- call_infos->object = rb_ary_new();
395
- for(i=call_infos->start; i<call_infos->ptr; i++)
396
- {
397
- VALUE call_info = prof_call_info_wrap(*i);
398
- rb_ary_push(call_infos->object, call_info);
399
- }
400
- }
401
- return call_infos->object;
402
- }
403
-
404
- void rp_init_call_info()
405
- {
406
- /* CallInfo */
407
- cCallInfo = rb_define_class_under(mProf, "CallInfo", rb_cObject);
408
- rb_undef_method(CLASS_OF(cCallInfo), "new");
409
- rb_define_method(cCallInfo, "parent", prof_call_info_parent, 0);
410
- rb_define_method(cCallInfo, "parent=", prof_call_info_set_parent, 1);
411
- rb_define_method(cCallInfo, "children", prof_call_info_children, 0);
412
- rb_define_method(cCallInfo, "target", prof_call_info_target, 0);
413
- rb_define_method(cCallInfo, "called", prof_call_info_called, 0);
414
- rb_define_method(cCallInfo, "called=", prof_call_info_set_called, 1);
415
- rb_define_method(cCallInfo, "total_time", prof_call_info_total_time, 0);
416
- rb_define_method(cCallInfo, "add_total_time", prof_call_info_add_total_time, 1);
417
- rb_define_method(cCallInfo, "self_time", prof_call_info_self_time, 0);
418
- rb_define_method(cCallInfo, "add_self_time", prof_call_info_add_self_time, 1);
419
- rb_define_method(cCallInfo, "wait_time", prof_call_info_wait_time, 0);
420
- rb_define_method(cCallInfo, "add_wait_time", prof_call_info_add_wait_time, 1);
421
-
422
- rb_define_method(cCallInfo, "recursive?", prof_call_info_recursive, 0);
423
- rb_define_method(cCallInfo, "depth", prof_call_info_depth, 0);
424
- rb_define_method(cCallInfo, "line", prof_call_info_line, 0);
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
  }