ruby-prof 1.5.0-x64-mingw-ucrt → 1.6.2-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +19 -0
  3. data/bin/ruby-prof +105 -87
  4. data/ext/ruby_prof/rp_allocation.c +136 -81
  5. data/ext/ruby_prof/rp_allocation.h +8 -6
  6. data/ext/ruby_prof/rp_call_tree.c +502 -457
  7. data/ext/ruby_prof/rp_call_tree.h +47 -44
  8. data/ext/ruby_prof/rp_call_trees.c +1 -1
  9. data/ext/ruby_prof/rp_measurement.c +10 -3
  10. data/ext/ruby_prof/rp_method.c +86 -79
  11. data/ext/ruby_prof/rp_method.h +63 -62
  12. data/ext/ruby_prof/rp_profile.c +933 -948
  13. data/ext/ruby_prof/rp_profile.h +1 -0
  14. data/ext/ruby_prof/rp_thread.c +433 -410
  15. data/ext/ruby_prof/rp_thread.h +39 -39
  16. data/ext/ruby_prof/vc/ruby_prof.vcxproj +6 -3
  17. data/lib/3.1/ruby_prof.so +0 -0
  18. data/lib/3.2/ruby_prof.so +0 -0
  19. data/lib/ruby-prof/compatibility.rb +14 -0
  20. data/lib/ruby-prof/printers/abstract_printer.rb +2 -1
  21. data/lib/ruby-prof/printers/call_tree_printer.rb +1 -1
  22. data/lib/ruby-prof/printers/multi_printer.rb +17 -17
  23. data/lib/ruby-prof/profile.rb +70 -70
  24. data/lib/ruby-prof/rack.rb +31 -21
  25. data/lib/ruby-prof/version.rb +1 -1
  26. data/test/abstract_printer_test.rb +1 -0
  27. data/test/alias_test.rb +6 -11
  28. data/test/call_tree_test.rb +94 -197
  29. data/test/call_tree_visitor_test.rb +1 -6
  30. data/test/call_trees_test.rb +2 -2
  31. data/test/{basic_test.rb → compatibility_test.rb} +8 -2
  32. data/test/duplicate_names_test.rb +1 -1
  33. data/test/dynamic_method_test.rb +1 -6
  34. data/test/enumerable_test.rb +1 -1
  35. data/test/exceptions_test.rb +2 -2
  36. data/test/exclude_methods_test.rb +3 -8
  37. data/test/exclude_threads_test.rb +4 -9
  38. data/test/fiber_test.rb +2 -58
  39. data/test/gc_test.rb +2 -2
  40. data/test/inverse_call_tree_test.rb +33 -34
  41. data/test/line_number_test.rb +1 -1
  42. data/test/marshal_test.rb +3 -3
  43. data/test/measure_allocations_test.rb +8 -17
  44. data/test/measure_memory_test.rb +3 -12
  45. data/test/measure_process_time_test.rb +32 -36
  46. data/test/measure_wall_time_test.rb +176 -181
  47. data/test/merge_test.rb +146 -0
  48. data/test/multi_printer_test.rb +0 -5
  49. data/test/no_method_class_test.rb +1 -1
  50. data/test/pause_resume_test.rb +12 -16
  51. data/test/printer_call_stack_test.rb +2 -2
  52. data/test/printer_call_tree_test.rb +2 -2
  53. data/test/printer_flat_test.rb +1 -1
  54. data/test/printer_graph_html_test.rb +2 -2
  55. data/test/printer_graph_test.rb +2 -2
  56. data/test/printers_test.rb +14 -20
  57. data/test/printing_recursive_graph_test.rb +2 -2
  58. data/test/recursive_test.rb +2 -7
  59. data/test/scheduler.rb +9 -0
  60. data/test/singleton_test.rb +1 -1
  61. data/test/stack_printer_test.rb +5 -8
  62. data/test/start_stop_test.rb +11 -14
  63. data/test/test_helper.rb +7 -0
  64. data/test/thread_test.rb +84 -19
  65. data/test/unique_call_path_test.rb +4 -4
  66. data/test/yarv_test.rb +3 -3
  67. metadata +6 -5
@@ -1,44 +1,47 @@
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_CALL_TREE_H__
5
- #define __RP_CALL_TREE_H__
6
-
7
- #include "ruby_prof.h"
8
- #include "rp_measurement.h"
9
- #include "rp_method.h"
10
-
11
- extern VALUE cRpCallTree;
12
-
13
- /* Callers and callee information for a method. */
14
- typedef struct prof_call_tree_t
15
- {
16
- prof_owner_t owner;
17
- prof_method_t* method;
18
- struct prof_call_tree_t* parent;
19
- st_table* children; /* Call infos that this call info calls */
20
- prof_measurement_t* measurement;
21
- VALUE object;
22
-
23
- int visits; /* Current visits on the stack */
24
-
25
- unsigned int source_line;
26
- VALUE source_file;
27
- } prof_call_tree_t;
28
-
29
- prof_call_tree_t* prof_call_tree_create(prof_method_t* method, prof_call_tree_t* parent, VALUE source_file, int source_line);
30
- prof_call_tree_t* prof_call_tree_copy(prof_call_tree_t* other);
31
- void prof_call_tree_merge_internal(prof_call_tree_t* destination, prof_call_tree_t* other);
32
- void prof_call_tree_mark(void* data);
33
- prof_call_tree_t* call_tree_table_lookup(st_table* table, st_data_t key);
34
-
35
- void prof_call_tree_add_parent(prof_call_tree_t* self, prof_call_tree_t* parent);
36
- void prof_call_tree_add_child(prof_call_tree_t* self, prof_call_tree_t* child);
37
-
38
- uint32_t prof_call_figure_depth(prof_call_tree_t* call_tree_data);
39
- prof_call_tree_t* prof_get_call_tree(VALUE self);
40
- VALUE prof_call_tree_wrap(prof_call_tree_t* call_tree);
41
- void prof_call_tree_free(prof_call_tree_t* call_tree);
42
- void rp_init_call_tree();
43
-
44
- #endif //__RP_CALL_TREE_H__
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_CALL_TREE_H__
5
+ #define __RP_CALL_TREE_H__
6
+
7
+ #include "ruby_prof.h"
8
+ #include "rp_measurement.h"
9
+ #include "rp_method.h"
10
+
11
+ extern VALUE cRpCallTree;
12
+
13
+ /* Callers and callee information for a method. */
14
+ typedef struct prof_call_tree_t
15
+ {
16
+ prof_owner_t owner;
17
+ prof_method_t* method;
18
+ struct prof_call_tree_t* parent;
19
+ st_table* children; /* Call infos that this call info calls */
20
+ prof_measurement_t* measurement;
21
+ VALUE object;
22
+
23
+ int visits; /* Current visits on the stack */
24
+
25
+ unsigned int source_line;
26
+ VALUE source_file;
27
+ } prof_call_tree_t;
28
+
29
+ prof_call_tree_t* prof_call_tree_create(prof_method_t* method, prof_call_tree_t* parent, VALUE source_file, int source_line);
30
+ prof_call_tree_t* prof_call_tree_copy(prof_call_tree_t* other);
31
+ void prof_call_tree_merge_internal(prof_call_tree_t* destination, prof_call_tree_t* other, st_table* method_table);
32
+ void prof_call_tree_mark(void* data);
33
+ prof_call_tree_t* call_tree_table_lookup(st_table* table, st_data_t key);
34
+
35
+ void prof_call_tree_add_parent(prof_call_tree_t* self, prof_call_tree_t* parent);
36
+ void prof_call_tree_add_child(prof_call_tree_t* self, prof_call_tree_t* child);
37
+
38
+ uint32_t prof_call_tree_figure_depth(prof_call_tree_t* call_tree);
39
+ VALUE prof_call_tree_methods(prof_call_tree_t* call_tree);
40
+
41
+ prof_call_tree_t* prof_get_call_tree(VALUE self);
42
+ VALUE prof_call_tree_wrap(prof_call_tree_t* call_tree);
43
+ void prof_call_tree_free(prof_call_tree_t* call_tree);
44
+
45
+ void rp_init_call_tree();
46
+
47
+ #endif //__RP_CALL_TREE_H__
@@ -170,7 +170,7 @@ VALUE prof_call_trees_min_depth(VALUE self)
170
170
  prof_call_trees_t* call_trees = prof_get_call_trees(self);
171
171
  for (prof_call_tree_t** p_call_tree = call_trees->start; p_call_tree < call_trees->ptr; p_call_tree++)
172
172
  {
173
- unsigned int call_tree_depth = prof_call_figure_depth(*p_call_tree);
173
+ unsigned int call_tree_depth = prof_call_tree_figure_depth(*p_call_tree);
174
174
  if (call_tree_depth < depth)
175
175
  depth = call_tree_depth;
176
176
  }
@@ -102,10 +102,16 @@ void prof_measurement_mark(void* data)
102
102
  {
103
103
  if (!data) return;
104
104
 
105
- prof_measurement_t* measurement_data = (prof_measurement_t*)data;
105
+ prof_measurement_t* measurement = (prof_measurement_t*)data;
106
106
 
107
- if (measurement_data->object != Qnil)
108
- rb_gc_mark(measurement_data->object);
107
+ if (measurement->object != Qnil)
108
+ rb_gc_mark_movable(measurement->object);
109
+ }
110
+
111
+ void prof_measurement_compact(void* data)
112
+ {
113
+ prof_measurement_t* measurement = (prof_measurement_t*)data;
114
+ measurement->object = rb_gc_location(measurement->object);
109
115
  }
110
116
 
111
117
  void prof_measurement_free(prof_measurement_t* measurement)
@@ -155,6 +161,7 @@ static const rb_data_type_t measurement_type =
155
161
  .dmark = prof_measurement_mark,
156
162
  .dfree = prof_measurement_ruby_gc_free,
157
163
  .dsize = prof_measurement_size,
164
+ .dcompact = prof_measurement_compact
158
165
  },
159
166
  .data = NULL,
160
167
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
@@ -22,31 +22,38 @@ VALUE resolve_klass(VALUE klass, unsigned int* klass_flags)
22
22
  figure out what it is attached to.*/
23
23
  VALUE attached = rb_iv_get(klass, "__attached__");
24
24
 
25
- /* Is this a singleton class acting as a metaclass? */
26
- if (BUILTIN_TYPE(attached) == T_CLASS)
25
+ switch (BUILTIN_TYPE(attached))
27
26
  {
28
- *klass_flags |= kClassSingleton;
29
- result = attached;
30
- }
31
- /* Is this for singleton methods on a module? */
32
- else if (BUILTIN_TYPE(attached) == T_MODULE)
33
- {
34
- *klass_flags |= kModuleSingleton;
35
- result = attached;
36
- }
37
- /* Is this for singleton methods on an object? */
38
- else if (BUILTIN_TYPE(attached) == T_OBJECT)
39
- {
40
- *klass_flags |= kObjectSingleton;
41
- result = rb_class_superclass(klass);
42
- }
43
- /* Ok, this could be other things like an array put onto
44
- a singleton object (yeah, it happens, see the singleton
45
- objects test case). */
46
- else
47
- {
48
- *klass_flags |= kOtherSingleton;
49
- result = klass;
27
+ /* Is this a singleton class acting as a metaclass? */
28
+ case T_CLASS:
29
+ {
30
+ *klass_flags |= kClassSingleton;
31
+ result = attached;
32
+ break;
33
+ }
34
+ /* Is this for singleton methods on a module? */
35
+ case T_MODULE:
36
+ {
37
+ *klass_flags |= kModuleSingleton;
38
+ result = attached;
39
+ break;
40
+ }
41
+ /* Is this for singleton methods on an object? */
42
+ case T_OBJECT:
43
+ {
44
+ *klass_flags |= kObjectSingleton;
45
+ result = rb_class_superclass(klass);
46
+ break;
47
+ }
48
+ /* Ok, this could be other things like an array put onto
49
+ a singleton object (yeah, it happens, see the singleton
50
+ objects test case). */
51
+ default:
52
+ {
53
+ *klass_flags |= kOtherSingleton;
54
+ result = klass;
55
+ break;
56
+ }
50
57
  }
51
58
  }
52
59
  /* Is this an include for a module? If so get the actual
@@ -56,7 +63,7 @@ VALUE resolve_klass(VALUE klass, unsigned int* klass_flags)
56
63
  {
57
64
  unsigned int dummy;
58
65
  *klass_flags |= kModuleIncludee;
59
- result = resolve_klass(RBASIC(klass)->klass, &dummy);
66
+ result = resolve_klass(RBASIC_CLASS(klass), &dummy);
60
67
  }
61
68
  return result;
62
69
  }
@@ -94,7 +101,7 @@ st_data_t method_key(VALUE klass, VALUE msym)
94
101
  }
95
102
  else if (BUILTIN_TYPE(klass) == T_ICLASS)
96
103
  {
97
- resolved_klass = RBASIC(klass)->klass;
104
+ resolved_klass = RBASIC_CLASS(klass);
98
105
  }
99
106
 
100
107
  st_data_t hash = rb_hash_start(0);
@@ -105,39 +112,6 @@ st_data_t method_key(VALUE klass, VALUE msym)
105
112
  return hash;
106
113
  }
107
114
 
108
- /* ====== Allocation Table ====== */
109
- st_table* allocations_table_create()
110
- {
111
- return rb_st_init_numtable();
112
- }
113
-
114
- static int allocations_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
115
- {
116
- prof_allocation_free((prof_allocation_t*)value);
117
- return ST_CONTINUE;
118
- }
119
-
120
- static int prof_method_collect_allocations(st_data_t key, st_data_t value, st_data_t result)
121
- {
122
- prof_allocation_t* allocation = (prof_allocation_t*)value;
123
- VALUE arr = (VALUE)result;
124
- rb_ary_push(arr, prof_allocation_wrap(allocation));
125
- return ST_CONTINUE;
126
- }
127
-
128
- static int prof_method_mark_allocations(st_data_t key, st_data_t value, st_data_t data)
129
- {
130
- prof_allocation_t* allocation = (prof_allocation_t*)value;
131
- prof_allocation_mark(allocation);
132
- return ST_CONTINUE;
133
- }
134
-
135
- void allocations_table_free(st_table* table)
136
- {
137
- rb_st_foreach(table, allocations_table_free_iterator, 0);
138
- rb_st_free_table(table);
139
- }
140
-
141
115
  /* ================ prof_method_t =================*/
142
116
  prof_method_t* prof_get_method(VALUE self)
143
117
  {
@@ -167,7 +141,7 @@ prof_method_t* prof_method_create(VALUE profile, VALUE klass, VALUE msym, VALUE
167
141
  result->measurement = prof_measurement_create();
168
142
 
169
143
  result->call_trees = prof_call_trees_create();
170
- result->allocations_table = allocations_table_create();
144
+ result->allocations_table = prof_allocations_create();
171
145
 
172
146
  result->visits = 0;
173
147
  result->recursive = false;
@@ -180,6 +154,14 @@ prof_method_t* prof_method_create(VALUE profile, VALUE klass, VALUE msym, VALUE
180
154
  return result;
181
155
  }
182
156
 
157
+ prof_method_t* prof_method_copy(prof_method_t* other)
158
+ {
159
+ prof_method_t* result = prof_method_create(other->profile, other->klass, other->method_name, other->source_file, other->source_line);
160
+ result->measurement = prof_measurement_copy(other->measurement);
161
+
162
+ return result;
163
+ }
164
+
183
165
  /* The underlying c structures are freed when the parent profile is freed.
184
166
  However, on shutdown the Ruby GC frees objects in any will-nilly order.
185
167
  That means the ruby thread object wrapping the c thread struct may
@@ -205,7 +187,7 @@ static void prof_method_free(prof_method_t* method)
205
187
  method->object = Qnil;
206
188
  }
207
189
 
208
- allocations_table_free(method->allocations_table);
190
+ prof_allocations_free(method->allocations_table);
209
191
  prof_call_trees_free(method->call_trees);
210
192
  prof_measurement_free(method->measurement);
211
193
  xfree(method);
@@ -223,21 +205,29 @@ void prof_method_mark(void* data)
223
205
  prof_method_t* method = (prof_method_t*)data;
224
206
 
225
207
  if (method->profile != Qnil)
226
- rb_gc_mark(method->profile);
208
+ rb_gc_mark_movable(method->profile);
227
209
 
228
210
  if (method->object != Qnil)
229
- rb_gc_mark(method->object);
211
+ rb_gc_mark_movable(method->object);
230
212
 
231
- rb_gc_mark(method->klass_name);
232
- rb_gc_mark(method->method_name);
213
+ rb_gc_mark_movable(method->klass_name);
214
+ rb_gc_mark_movable(method->method_name);
233
215
  rb_gc_mark(method->source_file);
234
216
 
235
217
  if (method->klass != Qnil)
236
218
  rb_gc_mark(method->klass);
237
219
 
238
220
  prof_measurement_mark(method->measurement);
221
+ prof_allocations_mark(method->allocations_table);
222
+ }
239
223
 
240
- rb_st_foreach(method->allocations_table, prof_method_mark_allocations, 0);
224
+ void prof_method_compact(void* data)
225
+ {
226
+ prof_method_t* method = (prof_method_t*)data;
227
+ method->object = rb_gc_location(method->object);
228
+ method->profile = rb_gc_location(method->profile);
229
+ method->klass_name = rb_gc_location(method->klass_name);
230
+ method->method_name = rb_gc_location(method->method_name);
241
231
  }
242
232
 
243
233
  static VALUE prof_method_allocate(VALUE klass)
@@ -255,6 +245,7 @@ static const rb_data_type_t method_info_type =
255
245
  .dmark = prof_method_mark,
256
246
  .dfree = prof_method_ruby_gc_free,
257
247
  .dsize = prof_method_size,
248
+ .dcompact = prof_method_compact
258
249
  },
259
250
  .data = NULL,
260
251
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
@@ -291,6 +282,30 @@ size_t method_table_insert(st_table* table, st_data_t key, prof_method_t* val)
291
282
  return rb_st_insert(table, (st_data_t)key, (st_data_t)val);
292
283
  }
293
284
 
285
+ static int prof_method_table_merge_internal(st_data_t key, st_data_t value, st_data_t data)
286
+ {
287
+ st_table* self_table = (st_table*)data;
288
+ prof_method_t* other_child = (prof_method_t*)value;
289
+
290
+ prof_method_t* self_child = method_table_lookup(self_table, other_child->key);
291
+ if (self_child)
292
+ {
293
+ prof_measurement_merge_internal(self_child->measurement, other_child->measurement);
294
+ }
295
+ else
296
+ {
297
+ prof_method_t* copy = prof_method_copy(other_child);
298
+ method_table_insert(self_table, copy->key, copy);
299
+ }
300
+
301
+ return ST_CONTINUE;
302
+ }
303
+
304
+ void prof_method_table_merge(st_table* self, st_table* other)
305
+ {
306
+ rb_st_foreach(other, prof_method_table_merge_internal, (st_data_t)self);
307
+ }
308
+
294
309
  prof_method_t* method_table_lookup(st_table* table, st_data_t key)
295
310
  {
296
311
  st_data_t val;
@@ -360,9 +375,7 @@ Returns an array of allocation information.*/
360
375
  static VALUE prof_method_allocations(VALUE self)
361
376
  {
362
377
  prof_method_t* method = prof_get_method(self);
363
- VALUE result = rb_ary_new();
364
- rb_st_foreach(method->allocations_table, prof_method_collect_allocations, result);
365
- return result;
378
+ return prof_allocations_wrap(method->allocations_table);
366
379
  }
367
380
 
368
381
  /* call-seq:
@@ -397,7 +410,7 @@ static VALUE prof_method_line(VALUE self)
397
410
  }
398
411
 
399
412
  /* call-seq:
400
- klass_name -> string
413
+ klass_name -> String
401
414
 
402
415
  Returns the name of this method's class. Singleton classes
403
416
  will have the form <Object::Object>. */
@@ -423,9 +436,9 @@ static VALUE prof_method_klass_flags(VALUE self)
423
436
  }
424
437
 
425
438
  /* call-seq:
426
- method_name -> string
439
+ method_name -> Symbol
427
440
 
428
- Returns the name of this method in the format Object#method. Singletons
441
+ Returns the name of this method in the format Object#method. Singletons
429
442
  methods will be returned in the format <Object::Object>#method.*/
430
443
 
431
444
  static VALUE prof_method_name(VALUE self)
@@ -499,13 +512,7 @@ static VALUE prof_method_load(VALUE self, VALUE data)
499
512
  method_data->measurement = prof_get_measurement(measurement);
500
513
 
501
514
  VALUE allocations = rb_hash_aref(data, ID2SYM(rb_intern("allocations")));
502
- for (int i = 0; i < rb_array_len(allocations); i++)
503
- {
504
- VALUE allocation = rb_ary_entry(allocations, i);
505
- prof_allocation_t* allocation_data = prof_allocation_get(allocation);
506
-
507
- rb_st_insert(method_data->allocations_table, allocation_data->key, (st_data_t)allocation_data);
508
- }
515
+ prof_allocations_unwrap(method_data->allocations_table, allocations);
509
516
  return data;
510
517
  }
511
518
 
@@ -1,62 +1,63 @@
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_METHOD_INFO__
5
- #define __RP_METHOD_INFO__
6
-
7
- #include "ruby_prof.h"
8
- #include "rp_measurement.h"
9
-
10
- extern VALUE cRpMethodInfo;
11
-
12
- // Source relation bit offsets.
13
- enum {
14
- kModuleIncludee = 0x1, // Included in module
15
- kClassSingleton = 0x2, // Singleton of a class
16
- kModuleSingleton = 0x4, // Singleton of a module
17
- kObjectSingleton = 0x8, // Singleton of an object
18
- kOtherSingleton = 0x10 // Singleton of unknown object
19
- };
20
-
21
- // Profiling information for each method.
22
- // Excluded methods have no call_trees, source_klass, or source_file.
23
- typedef struct prof_method_t
24
- {
25
- VALUE profile; // Profile this method is associated with - needed for mark phase
26
- struct prof_call_trees_t* call_trees; // Call infos that call this method
27
- st_table* allocations_table; // Tracks object allocations
28
-
29
- st_data_t key; // Table key
30
- unsigned int klass_flags; // Information about the type of class
31
- VALUE klass; // Resolved klass
32
- VALUE klass_name; // Resolved klass name for this method
33
- VALUE method_name; // Resolved method name for this method
34
-
35
- VALUE object; // Cached ruby object
36
-
37
- bool recursive;
38
- int visits; // Current visits on the stack
39
- VALUE source_file; // Source file
40
- int source_line; // Line number
41
-
42
- prof_measurement_t* measurement; // Stores measurement data for this method
43
- } prof_method_t;
44
-
45
- void rp_init_method_info(void);
46
-
47
- st_data_t method_key(VALUE klass, VALUE msym);
48
-
49
- st_table* method_table_create(void);
50
- prof_method_t* method_table_lookup(st_table* table, st_data_t key);
51
- size_t method_table_insert(st_table* table, st_data_t key, prof_method_t* val);
52
- void method_table_free(st_table* table);
53
- prof_method_t* prof_method_create(VALUE profile, VALUE klass, VALUE msym, VALUE source_file, int source_line);
54
- prof_method_t* prof_get_method(VALUE self);
55
-
56
- VALUE prof_method_wrap(prof_method_t* result);
57
- void prof_method_mark(void* data);
58
-
59
- VALUE resolve_klass(VALUE klass, unsigned int* klass_flags);
60
- VALUE resolve_klass_name(VALUE klass, unsigned int* klass_flags);
61
-
62
- #endif //__RP_METHOD_INFO__
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_METHOD_INFO__
5
+ #define __RP_METHOD_INFO__
6
+
7
+ #include "ruby_prof.h"
8
+ #include "rp_measurement.h"
9
+
10
+ extern VALUE cRpMethodInfo;
11
+
12
+ // Source relation bit offsets.
13
+ enum {
14
+ kModuleIncludee = 0x1, // Included in module
15
+ kClassSingleton = 0x2, // Singleton of a class
16
+ kModuleSingleton = 0x4, // Singleton of a module
17
+ kObjectSingleton = 0x8, // Singleton of an object
18
+ kOtherSingleton = 0x10 // Singleton of unknown object
19
+ };
20
+
21
+ // Profiling information for each method.
22
+ // Excluded methods have no call_trees, source_klass, or source_file.
23
+ typedef struct prof_method_t
24
+ {
25
+ VALUE profile; // Profile this method is associated with - needed for mark phase
26
+ struct prof_call_trees_t* call_trees; // Call infos that call this method
27
+ st_table* allocations_table; // Tracks object allocations
28
+
29
+ st_data_t key; // Table key
30
+ unsigned int klass_flags; // Information about the type of class
31
+ VALUE klass; // Resolved klass
32
+ VALUE klass_name; // Resolved klass name for this method
33
+ VALUE method_name; // Resolved method name for this method
34
+
35
+ VALUE object; // Cached ruby object
36
+
37
+ bool recursive;
38
+ int visits; // Current visits on the stack
39
+ VALUE source_file; // Source file
40
+ int source_line; // Line number
41
+
42
+ prof_measurement_t* measurement; // Stores measurement data for this method
43
+ } prof_method_t;
44
+
45
+ void rp_init_method_info(void);
46
+
47
+ st_data_t method_key(VALUE klass, VALUE msym);
48
+
49
+ st_table* method_table_create(void);
50
+ prof_method_t* method_table_lookup(st_table* table, st_data_t key);
51
+ size_t method_table_insert(st_table* table, st_data_t key, prof_method_t* val);
52
+ void method_table_free(st_table* table);
53
+ void prof_method_table_merge(st_table* self, st_table* other);
54
+ prof_method_t* prof_method_create(VALUE profile, VALUE klass, VALUE msym, VALUE source_file, int source_line);
55
+ prof_method_t* prof_get_method(VALUE self);
56
+
57
+ VALUE prof_method_wrap(prof_method_t* result);
58
+ void prof_method_mark(void* data);
59
+
60
+ VALUE resolve_klass(VALUE klass, unsigned int* klass_flags);
61
+ VALUE resolve_klass_name(VALUE klass, unsigned int* klass_flags);
62
+
63
+ #endif //__RP_METHOD_INFO__