ruby-prof 1.5.0-x64-mingw-ucrt → 1.6.1-x64-mingw-ucrt
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 +13 -0
- data/ext/ruby_prof/rp_allocation.c +136 -81
- data/ext/ruby_prof/rp_allocation.h +8 -6
- data/ext/ruby_prof/rp_call_tree.c +8 -1
- data/ext/ruby_prof/rp_measurement.c +10 -3
- data/ext/ruby_prof/rp_method.c +51 -76
- data/ext/ruby_prof/rp_profile.c +62 -77
- data/ext/ruby_prof/rp_profile.h +1 -0
- data/ext/ruby_prof/rp_thread.c +14 -4
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +1 -1
- data/lib/3.1/ruby_prof.so +0 -0
- data/lib/3.2/ruby_prof.so +0 -0
- data/lib/ruby-prof/compatibility.rb +14 -0
- data/lib/ruby-prof/printers/abstract_printer.rb +1 -1
- data/lib/ruby-prof/printers/call_tree_printer.rb +1 -1
- data/lib/ruby-prof/printers/multi_printer.rb +17 -17
- data/lib/ruby-prof/profile.rb +5 -5
- data/lib/ruby-prof/rack.rb +31 -21
- data/lib/ruby-prof/version.rb +1 -1
- data/test/abstract_printer_test.rb +1 -0
- data/test/alias_test.rb +6 -11
- data/test/call_tree_visitor_test.rb +1 -6
- data/test/call_trees_test.rb +2 -2
- data/test/{basic_test.rb → compatibility_test.rb} +8 -2
- data/test/duplicate_names_test.rb +1 -1
- data/test/dynamic_method_test.rb +1 -6
- data/test/enumerable_test.rb +1 -1
- data/test/exceptions_test.rb +2 -2
- data/test/exclude_methods_test.rb +3 -8
- data/test/exclude_threads_test.rb +4 -9
- data/test/fiber_test.rb +4 -9
- data/test/gc_test.rb +2 -1
- data/test/inverse_call_tree_test.rb +33 -34
- data/test/line_number_test.rb +1 -1
- data/test/marshal_test.rb +3 -3
- data/test/measure_allocations_test.rb +8 -17
- data/test/measure_memory_test.rb +3 -12
- data/test/measure_process_time_test.rb +29 -34
- data/test/measure_wall_time_test.rb +176 -181
- data/test/multi_printer_test.rb +0 -5
- data/test/no_method_class_test.rb +1 -1
- data/test/pause_resume_test.rb +12 -16
- data/test/printer_call_stack_test.rb +2 -2
- data/test/printer_call_tree_test.rb +2 -2
- data/test/printer_flat_test.rb +1 -1
- data/test/printer_graph_html_test.rb +2 -2
- data/test/printer_graph_test.rb +2 -2
- data/test/printers_test.rb +14 -20
- data/test/printing_recursive_graph_test.rb +2 -2
- data/test/recursive_test.rb +2 -7
- data/test/singleton_test.rb +1 -1
- data/test/stack_printer_test.rb +5 -8
- data/test/start_stop_test.rb +11 -14
- data/test/thread_test.rb +13 -15
- data/test/unique_call_path_test.rb +4 -4
- data/test/yarv_test.rb +3 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b366b0cde0e477d0b06b95b8bcb7f2d0c8747216b9cc8fcdf2c202e89a3106d6
|
4
|
+
data.tar.gz: 21239104377ef6a1479c4110dcd4cd2e2b086d75cd577a3531102799f19b8061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aa08fee0a9d16b9276867db6f7465286cae2d118738ff20e78bca8eae764bf9a6657bf93678b0f3430f2998c11117022e6bd6d732d29021bc4fb3b5e6f34615
|
7
|
+
data.tar.gz: b34eb2eb7e9bfb6567292ead8d625a3fd71533d3d2ed87be0798ab9e4e5def42a86768b02605f64048b25fbc90c2b736c5b1c4add494900c8250bfcf480e728d
|
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
1.6.1 (2023-02-21)
|
2
|
+
=====================
|
3
|
+
* Fix loading C extension for MacOS (Charlie Savage)
|
4
|
+
|
5
|
+
1.6.0 (2023-02-20)
|
6
|
+
=====================
|
7
|
+
* Add support for Ruby's compacting garbage collector (Charlie Savage)
|
8
|
+
* Add rbs signature files (Charlie Savage)
|
9
|
+
* Update rack adapter used for profiling Rails to include latest ruby-prof features (Charlie Savage)
|
10
|
+
* Add warnings for deprecated methods (Charlie Savage)
|
11
|
+
* Update tests to not use deprecated methods (Charlie Savage)
|
12
|
+
* Improve tests on OSX (Charlie Savage)
|
13
|
+
|
1
14
|
1.5.0 (2023-02-06)
|
2
15
|
=====================
|
3
16
|
* Add new Profile#merge! method that merges results for threads/fibers that share the same root method (Charlie Savage)
|
@@ -2,32 +2,11 @@
|
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "rp_allocation.h"
|
5
|
+
#include "rp_method.h"
|
5
6
|
|
6
7
|
VALUE cRpAllocation;
|
7
8
|
|
8
|
-
|
9
|
-
{
|
10
|
-
prof_allocation_t* result = NULL;
|
11
|
-
st_data_t value;
|
12
|
-
if (rb_st_lookup(table, key, &value))
|
13
|
-
{
|
14
|
-
result = (prof_allocation_t*)value;
|
15
|
-
}
|
16
|
-
|
17
|
-
return result;
|
18
|
-
}
|
19
|
-
|
20
|
-
void allocations_table_insert(st_table* table, st_data_t key, prof_allocation_t* allocation)
|
21
|
-
{
|
22
|
-
rb_st_insert(table, (st_data_t)key, (st_data_t)allocation);
|
23
|
-
}
|
24
|
-
|
25
|
-
st_data_t allocations_key(VALUE klass, int source_line)
|
26
|
-
{
|
27
|
-
return (klass << 4) + source_line;
|
28
|
-
}
|
29
|
-
|
30
|
-
/* ====== prof_allocation_t ====== */
|
9
|
+
// ------ prof_allocation_t ------
|
31
10
|
prof_allocation_t* prof_allocation_create(void)
|
32
11
|
{
|
33
12
|
prof_allocation_t* result = ALLOC(prof_allocation_t);
|
@@ -43,48 +22,17 @@ prof_allocation_t* prof_allocation_create(void)
|
|
43
22
|
return result;
|
44
23
|
}
|
45
24
|
|
46
|
-
prof_allocation_t*
|
25
|
+
prof_allocation_t* prof_allocation_get(VALUE self)
|
47
26
|
{
|
48
27
|
/* Can't use Data_Get_Struct because that triggers the event hook
|
49
28
|
ending up in endless recursion. */
|
50
29
|
prof_allocation_t* result = RTYPEDDATA_DATA(self);
|
51
|
-
|
52
30
|
if (!result)
|
53
31
|
rb_raise(rb_eRuntimeError, "This RubyProf::Allocation instance has already been freed, likely because its profile has been freed.");
|
54
32
|
|
55
33
|
return result;
|
56
34
|
}
|
57
35
|
|
58
|
-
prof_allocation_t* prof_allocate_increment(prof_method_t* method, rb_trace_arg_t* trace_arg)
|
59
|
-
{
|
60
|
-
VALUE object = rb_tracearg_object(trace_arg);
|
61
|
-
if (BUILTIN_TYPE(object) == T_IMEMO)
|
62
|
-
return NULL;
|
63
|
-
|
64
|
-
VALUE klass = rb_obj_class(object);
|
65
|
-
|
66
|
-
int source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
|
67
|
-
st_data_t key = allocations_key(klass, source_line);
|
68
|
-
|
69
|
-
prof_allocation_t* allocation = allocations_table_lookup(method->allocations_table, key);
|
70
|
-
if (!allocation)
|
71
|
-
{
|
72
|
-
allocation = prof_allocation_create();
|
73
|
-
allocation->source_line = source_line;
|
74
|
-
allocation->source_file = rb_tracearg_path(trace_arg);
|
75
|
-
allocation->klass_flags = 0;
|
76
|
-
allocation->klass = resolve_klass(klass, &allocation->klass_flags);
|
77
|
-
|
78
|
-
allocation->key = key;
|
79
|
-
allocations_table_insert(method->allocations_table, key, allocation);
|
80
|
-
}
|
81
|
-
|
82
|
-
allocation->count++;
|
83
|
-
allocation->memory += rb_obj_memsize_of(object);
|
84
|
-
|
85
|
-
return allocation;
|
86
|
-
}
|
87
|
-
|
88
36
|
static void prof_allocation_ruby_gc_free(void* data)
|
89
37
|
{
|
90
38
|
if (data)
|
@@ -118,30 +66,39 @@ void prof_allocation_mark(void* data)
|
|
118
66
|
|
119
67
|
prof_allocation_t* allocation = (prof_allocation_t*)data;
|
120
68
|
if (allocation->object != Qnil)
|
121
|
-
|
69
|
+
rb_gc_mark_movable(allocation->object);
|
122
70
|
|
123
71
|
if (allocation->klass != Qnil)
|
124
|
-
|
72
|
+
rb_gc_mark_movable(allocation->klass);
|
125
73
|
|
126
74
|
if (allocation->klass_name != Qnil)
|
127
|
-
|
75
|
+
rb_gc_mark_movable(allocation->klass_name);
|
128
76
|
|
129
77
|
if (allocation->source_file != Qnil)
|
130
78
|
rb_gc_mark(allocation->source_file);
|
131
79
|
}
|
132
80
|
|
133
|
-
|
81
|
+
void prof_allocation_compact(void* data)
|
134
82
|
{
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
83
|
+
prof_allocation_t* allocation = (prof_allocation_t*)data;
|
84
|
+
allocation->object = rb_gc_location(allocation->object);
|
85
|
+
allocation->klass = rb_gc_location(allocation->klass);
|
86
|
+
allocation->klass_name = rb_gc_location(allocation->klass_name);
|
87
|
+
}
|
88
|
+
|
89
|
+
static const rb_data_type_t allocation_type =
|
90
|
+
{
|
91
|
+
.wrap_struct_name = "Allocation",
|
92
|
+
.function =
|
93
|
+
{
|
94
|
+
.dmark = prof_allocation_mark,
|
95
|
+
.dfree = prof_allocation_ruby_gc_free,
|
96
|
+
.dsize = prof_allocation_size,
|
97
|
+
.dcompact = prof_allocation_compact
|
98
|
+
},
|
99
|
+
.data = NULL,
|
100
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
101
|
+
};
|
145
102
|
|
146
103
|
VALUE prof_allocation_wrap(prof_allocation_t* allocation)
|
147
104
|
{
|
@@ -152,24 +109,122 @@ VALUE prof_allocation_wrap(prof_allocation_t* allocation)
|
|
152
109
|
return allocation->object;
|
153
110
|
}
|
154
111
|
|
155
|
-
|
112
|
+
/* ====== Allocation Table ====== */
|
113
|
+
st_table* prof_allocations_create()
|
156
114
|
{
|
157
|
-
|
158
|
-
allocation->object = prof_allocation_wrap(allocation);
|
159
|
-
return allocation->object;
|
115
|
+
return rb_st_init_numtable();
|
160
116
|
}
|
161
117
|
|
162
|
-
|
118
|
+
static int allocations_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
|
163
119
|
{
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
120
|
+
prof_allocation_free((prof_allocation_t*)value);
|
121
|
+
return ST_CONTINUE;
|
122
|
+
}
|
123
|
+
|
124
|
+
st_data_t allocations_key(VALUE klass, int source_line)
|
125
|
+
{
|
126
|
+
return (klass << 4) + source_line;
|
127
|
+
}
|
128
|
+
|
129
|
+
static int prof_allocations_collect(st_data_t key, st_data_t value, st_data_t result)
|
130
|
+
{
|
131
|
+
prof_allocation_t* allocation = (prof_allocation_t*)value;
|
132
|
+
VALUE arr = (VALUE)result;
|
133
|
+
rb_ary_push(arr, prof_allocation_wrap(allocation));
|
134
|
+
return ST_CONTINUE;
|
135
|
+
}
|
136
|
+
|
137
|
+
static int prof_allocations_mark_each(st_data_t key, st_data_t value, st_data_t data)
|
138
|
+
{
|
139
|
+
prof_allocation_t* allocation = (prof_allocation_t*)value;
|
140
|
+
prof_allocation_mark(allocation);
|
141
|
+
return ST_CONTINUE;
|
142
|
+
}
|
143
|
+
|
144
|
+
void prof_allocations_mark(st_table* allocations_table)
|
145
|
+
{
|
146
|
+
rb_st_foreach(allocations_table, prof_allocations_mark_each, 0);
|
147
|
+
}
|
148
|
+
|
149
|
+
void prof_allocations_free(st_table* table)
|
150
|
+
{
|
151
|
+
rb_st_foreach(table, allocations_table_free_iterator, 0);
|
152
|
+
rb_st_free_table(table);
|
153
|
+
}
|
154
|
+
|
155
|
+
prof_allocation_t* allocations_table_lookup(st_table* table, st_data_t key)
|
156
|
+
{
|
157
|
+
prof_allocation_t* result = NULL;
|
158
|
+
st_data_t value;
|
159
|
+
if (rb_st_lookup(table, key, &value))
|
160
|
+
{
|
161
|
+
result = (prof_allocation_t*)value;
|
162
|
+
}
|
169
163
|
|
170
164
|
return result;
|
171
165
|
}
|
172
166
|
|
167
|
+
void allocations_table_insert(st_table* table, st_data_t key, prof_allocation_t* allocation)
|
168
|
+
{
|
169
|
+
rb_st_insert(table, (st_data_t)key, (st_data_t)allocation);
|
170
|
+
}
|
171
|
+
|
172
|
+
prof_allocation_t* prof_allocate_increment(st_table* allocations_table, rb_trace_arg_t* trace_arg)
|
173
|
+
{
|
174
|
+
VALUE object = rb_tracearg_object(trace_arg);
|
175
|
+
if (BUILTIN_TYPE(object) == T_IMEMO)
|
176
|
+
return NULL;
|
177
|
+
|
178
|
+
VALUE klass = rb_obj_class(object);
|
179
|
+
|
180
|
+
int source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
|
181
|
+
st_data_t key = allocations_key(klass, source_line);
|
182
|
+
|
183
|
+
prof_allocation_t* allocation = allocations_table_lookup(allocations_table, key);
|
184
|
+
if (!allocation)
|
185
|
+
{
|
186
|
+
allocation = prof_allocation_create();
|
187
|
+
allocation->source_line = source_line;
|
188
|
+
allocation->source_file = rb_tracearg_path(trace_arg);
|
189
|
+
allocation->klass_flags = 0;
|
190
|
+
allocation->klass = resolve_klass(klass, &allocation->klass_flags);
|
191
|
+
|
192
|
+
allocation->key = key;
|
193
|
+
allocations_table_insert(allocations_table, key, allocation);
|
194
|
+
}
|
195
|
+
|
196
|
+
allocation->count++;
|
197
|
+
allocation->memory += rb_obj_memsize_of(object);
|
198
|
+
|
199
|
+
return allocation;
|
200
|
+
}
|
201
|
+
|
202
|
+
// Returns an array of allocations
|
203
|
+
VALUE prof_allocations_wrap(st_table* allocations_table)
|
204
|
+
{
|
205
|
+
VALUE result = rb_ary_new();
|
206
|
+
rb_st_foreach(allocations_table, prof_allocations_collect, result);
|
207
|
+
return result;
|
208
|
+
}
|
209
|
+
|
210
|
+
void prof_allocations_unwrap(st_table* allocations_table, VALUE allocations)
|
211
|
+
{
|
212
|
+
for (int i = 0; i < rb_array_len(allocations); i++)
|
213
|
+
{
|
214
|
+
VALUE allocation = rb_ary_entry(allocations, i);
|
215
|
+
prof_allocation_t* allocation_data = prof_allocation_get(allocation);
|
216
|
+
rb_st_insert(allocations_table, allocation_data->key, (st_data_t)allocation_data);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
/* ====== prof_allocation_t ====== */
|
221
|
+
static VALUE prof_allocation_allocate(VALUE klass)
|
222
|
+
{
|
223
|
+
prof_allocation_t* allocation = prof_allocation_create();
|
224
|
+
allocation->object = prof_allocation_wrap(allocation);
|
225
|
+
return allocation->object;
|
226
|
+
}
|
227
|
+
|
173
228
|
/* call-seq:
|
174
229
|
klass -> Class
|
175
230
|
|
@@ -238,7 +293,7 @@ static VALUE prof_allocation_memory(VALUE self)
|
|
238
293
|
/* :nodoc: */
|
239
294
|
static VALUE prof_allocation_dump(VALUE self)
|
240
295
|
{
|
241
|
-
prof_allocation_t* allocation =
|
296
|
+
prof_allocation_t* allocation = prof_allocation_get(self);
|
242
297
|
|
243
298
|
VALUE result = rb_hash_new();
|
244
299
|
|
@@ -256,7 +311,7 @@ static VALUE prof_allocation_dump(VALUE self)
|
|
256
311
|
/* :nodoc: */
|
257
312
|
static VALUE prof_allocation_load(VALUE self, VALUE data)
|
258
313
|
{
|
259
|
-
prof_allocation_t* allocation =
|
314
|
+
prof_allocation_t* allocation = prof_allocation_get(self);
|
260
315
|
allocation->object = self;
|
261
316
|
|
262
317
|
allocation->key = RB_NUM2ULL(rb_hash_aref(data, ID2SYM(rb_intern("key"))));
|
@@ -5,7 +5,6 @@
|
|
5
5
|
#define _RP_ALLOCATION_
|
6
6
|
|
7
7
|
#include "ruby_prof.h"
|
8
|
-
#include "rp_method.h"
|
9
8
|
|
10
9
|
typedef struct prof_allocation_t
|
11
10
|
{
|
@@ -20,12 +19,15 @@ typedef struct prof_allocation_t
|
|
20
19
|
VALUE object; /* Cache to wrapped object */
|
21
20
|
} prof_allocation_t;
|
22
21
|
|
22
|
+
// Allocation (prof_allocation_t*)
|
23
23
|
void rp_init_allocation(void);
|
24
|
-
|
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);
|
24
|
+
prof_allocation_t* prof_allocate_increment(st_table* allocations_table, rb_trace_arg_t* trace_arg);
|
29
25
|
|
26
|
+
// Allocations (st_table*)
|
27
|
+
st_table* prof_allocations_create(void);
|
28
|
+
VALUE prof_allocations_wrap(st_table* allocations_table);
|
29
|
+
void prof_allocations_unwrap(st_table* allocations_table, VALUE allocations);
|
30
|
+
void prof_allocations_mark(st_table* allocations_table);
|
31
|
+
void prof_allocations_free(st_table* table);
|
30
32
|
|
31
33
|
#endif //_RP_ALLOCATION_
|
@@ -54,7 +54,7 @@ void prof_call_tree_mark(void* data)
|
|
54
54
|
prof_call_tree_t* call_tree = (prof_call_tree_t*)data;
|
55
55
|
|
56
56
|
if (call_tree->object != Qnil)
|
57
|
-
|
57
|
+
rb_gc_mark_movable(call_tree->object);
|
58
58
|
|
59
59
|
if (call_tree->source_file != Qnil)
|
60
60
|
rb_gc_mark(call_tree->source_file);
|
@@ -68,6 +68,12 @@ void prof_call_tree_mark(void* data)
|
|
68
68
|
rb_st_foreach(call_tree->children, prof_call_tree_mark_children, 0);
|
69
69
|
}
|
70
70
|
|
71
|
+
void prof_call_tree_compact(void* data)
|
72
|
+
{
|
73
|
+
prof_call_tree_t* call_tree = (prof_call_tree_t*)data;
|
74
|
+
call_tree->object = rb_gc_location(call_tree->object);
|
75
|
+
}
|
76
|
+
|
71
77
|
static int prof_call_tree_free_children(st_data_t key, st_data_t value, st_data_t data)
|
72
78
|
{
|
73
79
|
prof_call_tree_t* call_tree = (prof_call_tree_t*)value;
|
@@ -130,6 +136,7 @@ static const rb_data_type_t call_tree_type =
|
|
130
136
|
.dmark = prof_call_tree_mark,
|
131
137
|
.dfree = prof_call_tree_ruby_gc_free,
|
132
138
|
.dsize = prof_call_tree_size,
|
139
|
+
.dcompact = prof_call_tree_compact
|
133
140
|
},
|
134
141
|
.data = NULL,
|
135
142
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
@@ -102,10 +102,16 @@ void prof_measurement_mark(void* data)
|
|
102
102
|
{
|
103
103
|
if (!data) return;
|
104
104
|
|
105
|
-
prof_measurement_t*
|
105
|
+
prof_measurement_t* measurement = (prof_measurement_t*)data;
|
106
106
|
|
107
|
-
if (
|
108
|
-
|
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
|
data/ext/ruby_prof/rp_method.c
CHANGED
@@ -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
|
-
|
26
|
-
if (BUILTIN_TYPE(attached) == T_CLASS)
|
25
|
+
switch (BUILTIN_TYPE(attached))
|
27
26
|
{
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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(
|
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 =
|
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 =
|
144
|
+
result->allocations_table = prof_allocations_create();
|
171
145
|
|
172
146
|
result->visits = 0;
|
173
147
|
result->recursive = false;
|
@@ -205,7 +179,7 @@ static void prof_method_free(prof_method_t* method)
|
|
205
179
|
method->object = Qnil;
|
206
180
|
}
|
207
181
|
|
208
|
-
|
182
|
+
prof_allocations_free(method->allocations_table);
|
209
183
|
prof_call_trees_free(method->call_trees);
|
210
184
|
prof_measurement_free(method->measurement);
|
211
185
|
xfree(method);
|
@@ -223,21 +197,29 @@ void prof_method_mark(void* data)
|
|
223
197
|
prof_method_t* method = (prof_method_t*)data;
|
224
198
|
|
225
199
|
if (method->profile != Qnil)
|
226
|
-
|
200
|
+
rb_gc_mark_movable(method->profile);
|
227
201
|
|
228
202
|
if (method->object != Qnil)
|
229
|
-
|
203
|
+
rb_gc_mark_movable(method->object);
|
230
204
|
|
231
|
-
|
232
|
-
|
205
|
+
rb_gc_mark_movable(method->klass_name);
|
206
|
+
rb_gc_mark_movable(method->method_name);
|
233
207
|
rb_gc_mark(method->source_file);
|
234
208
|
|
235
209
|
if (method->klass != Qnil)
|
236
210
|
rb_gc_mark(method->klass);
|
237
211
|
|
238
212
|
prof_measurement_mark(method->measurement);
|
213
|
+
prof_allocations_mark(method->allocations_table);
|
214
|
+
}
|
239
215
|
|
240
|
-
|
216
|
+
void prof_method_compact(void* data)
|
217
|
+
{
|
218
|
+
prof_method_t* method = (prof_method_t*)data;
|
219
|
+
method->object = rb_gc_location(method->object);
|
220
|
+
method->profile = rb_gc_location(method->profile);
|
221
|
+
method->klass_name = rb_gc_location(method->klass_name);
|
222
|
+
method->method_name = rb_gc_location(method->method_name);
|
241
223
|
}
|
242
224
|
|
243
225
|
static VALUE prof_method_allocate(VALUE klass)
|
@@ -255,6 +237,7 @@ static const rb_data_type_t method_info_type =
|
|
255
237
|
.dmark = prof_method_mark,
|
256
238
|
.dfree = prof_method_ruby_gc_free,
|
257
239
|
.dsize = prof_method_size,
|
240
|
+
.dcompact = prof_method_compact
|
258
241
|
},
|
259
242
|
.data = NULL,
|
260
243
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
@@ -360,9 +343,7 @@ Returns an array of allocation information.*/
|
|
360
343
|
static VALUE prof_method_allocations(VALUE self)
|
361
344
|
{
|
362
345
|
prof_method_t* method = prof_get_method(self);
|
363
|
-
|
364
|
-
rb_st_foreach(method->allocations_table, prof_method_collect_allocations, result);
|
365
|
-
return result;
|
346
|
+
return prof_allocations_wrap(method->allocations_table);
|
366
347
|
}
|
367
348
|
|
368
349
|
/* call-seq:
|
@@ -499,13 +480,7 @@ static VALUE prof_method_load(VALUE self, VALUE data)
|
|
499
480
|
method_data->measurement = prof_get_measurement(measurement);
|
500
481
|
|
501
482
|
VALUE allocations = rb_hash_aref(data, ID2SYM(rb_intern("allocations")));
|
502
|
-
|
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
|
-
}
|
483
|
+
prof_allocations_unwrap(method_data->allocations_table, allocations);
|
509
484
|
return data;
|
510
485
|
}
|
511
486
|
|