allocation_tracer 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc70bffa355bef7e53d7dec123a601142634004e
|
4
|
+
data.tar.gz: e3d1ac0a14f14e890491aacb26601d9a4bdb564f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9b6df363aa685702c53a24386a76e6d1ea023e216551a4fe7e30a9df82722457857e84ed94d8ce17cdea3aacaa77c94578330be6350e12c1e68636af8a4939b
|
7
|
+
data.tar.gz: 028466e6747249427b595a0d106891cdbc93add1f4b0ca29e92f4512b47663800413743ad893ebfa90a8645aafafb9afc001aa9f3d5e35fad4fd2ebe151732f1
|
@@ -13,6 +13,8 @@ size_t rb_obj_memsize_of(VALUE obj); /* in gc.c */
|
|
13
13
|
static VALUE rb_mAllocationTracer;
|
14
14
|
|
15
15
|
struct allocation_info {
|
16
|
+
struct allocation_info *next;
|
17
|
+
|
16
18
|
/* all of information don't need marking. */
|
17
19
|
int living;
|
18
20
|
VALUE flags;
|
@@ -20,23 +22,26 @@ struct allocation_info {
|
|
20
22
|
size_t generation;
|
21
23
|
size_t memsize;
|
22
24
|
|
23
|
-
/*
|
25
|
+
/* allocator info */
|
24
26
|
const char *path;
|
25
27
|
unsigned long line;
|
26
|
-
|
27
|
-
struct allocation_info *next;
|
28
28
|
};
|
29
29
|
|
30
|
+
#define MAX_KEY_DATA 4
|
31
|
+
|
30
32
|
#define KEY_PATH (1<<1)
|
31
33
|
#define KEY_LINE (1<<2)
|
32
34
|
#define KEY_TYPE (1<<3)
|
33
35
|
#define KEY_CLASS (1<<4)
|
34
36
|
|
37
|
+
#define MAX_VAL_DATA 6
|
38
|
+
|
35
39
|
#define VAL_COUNT (1<<1)
|
36
|
-
#define
|
37
|
-
#define
|
40
|
+
#define VAL_OLDCOUNT (1<<2)
|
41
|
+
#define VAL_TOTAL_AGE (1<<3)
|
38
42
|
#define VAL_MIN_AGE (1<<4)
|
39
|
-
#define
|
43
|
+
#define VAL_MAX_AGE (1<<5)
|
44
|
+
#define VAL_MEMSIZE (1<<6)
|
40
45
|
|
41
46
|
struct traceobj_arg {
|
42
47
|
int running;
|
@@ -101,12 +106,9 @@ delete_unique_str(st_table *tbl, const char *str)
|
|
101
106
|
}
|
102
107
|
}
|
103
108
|
|
104
|
-
/* file, line, type */
|
105
|
-
#define MAX_KEY_DATA 4
|
106
|
-
|
107
109
|
struct memcmp_key_data {
|
108
110
|
int n;
|
109
|
-
st_data_t data[
|
111
|
+
st_data_t data[MAX_KEY_DATA];
|
110
112
|
};
|
111
113
|
|
112
114
|
static int
|
@@ -218,9 +220,9 @@ newobj_i(VALUE tpval, void *data)
|
|
218
220
|
}
|
219
221
|
|
220
222
|
info->next = NULL;
|
223
|
+
info->flags = RBASIC(obj)->flags;
|
221
224
|
info->living = 1;
|
222
225
|
info->memsize = 0;
|
223
|
-
info->flags = RBASIC(obj)->flags;
|
224
226
|
info->klass = RTEST(klass) ? rb_class_real(klass) : Qnil;
|
225
227
|
info->generation = rb_gc_count();
|
226
228
|
|
@@ -276,10 +278,10 @@ aggregator_i(void *data)
|
|
276
278
|
key = (st_data_t)key_buff;
|
277
279
|
|
278
280
|
/* count, total age, max age, min age */
|
279
|
-
val_buff = ALLOC_N(size_t,
|
280
|
-
val_buff[0] = val_buff[1] = 0;
|
281
|
-
val_buff[
|
282
|
-
val_buff[
|
281
|
+
val_buff = ALLOC_N(size_t, 6);
|
282
|
+
val_buff[0] = val_buff[1] = val_buff[2] = 0;
|
283
|
+
val_buff[3] = val_buff[4] = age;
|
284
|
+
val_buff[5] = 0;
|
283
285
|
|
284
286
|
if (arg->keys & KEY_PATH) keep_unique_str(arg->str_table, info->path);
|
285
287
|
|
@@ -290,10 +292,11 @@ aggregator_i(void *data)
|
|
290
292
|
}
|
291
293
|
|
292
294
|
val_buff[0] += 1;
|
293
|
-
val_buff[1] +=
|
294
|
-
|
295
|
-
if (val_buff[3]
|
296
|
-
val_buff[4]
|
295
|
+
if (info->flags & FL_PROMOTED) val_buff[1] += 1;
|
296
|
+
val_buff[2] += age;
|
297
|
+
if (val_buff[3] > age) val_buff[3] = age; /* min */
|
298
|
+
if (val_buff[4] < age) val_buff[4] = age; /* max */
|
299
|
+
val_buff[5] += info->memsize;
|
297
300
|
|
298
301
|
free_allocation_info(arg, info);
|
299
302
|
info = next_info;
|
@@ -320,6 +323,7 @@ freeobj_i(VALUE tpval, void *data)
|
|
320
323
|
}
|
321
324
|
|
322
325
|
if (st_lookup(arg->object_table, (st_data_t)obj, (st_data_t *)&info)) {
|
326
|
+
info->flags = RBASIC(obj)->flags;
|
323
327
|
info->memsize = rb_obj_memsize_of(obj);
|
324
328
|
move_to_freed_list(arg, info);
|
325
329
|
st_delete(arg->object_table, (st_data_t *)&obj, (st_data_t *)&info);
|
@@ -393,7 +397,10 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
|
|
393
397
|
|
394
398
|
size_t *val_buff = (size_t *)val;
|
395
399
|
struct memcmp_key_data *key_buff = (struct memcmp_key_data *)key;
|
396
|
-
VALUE v = rb_ary_new3(
|
400
|
+
VALUE v = rb_ary_new3(6,
|
401
|
+
INT2FIX(val_buff[0]), INT2FIX(val_buff[1]),
|
402
|
+
INT2FIX(val_buff[2]), INT2FIX(val_buff[3]),
|
403
|
+
INT2FIX(val_buff[4]), INT2FIX(val_buff[5]));
|
397
404
|
VALUE k = rb_ary_new();
|
398
405
|
int i = 0;
|
399
406
|
static VALUE type_symbols[T_MASK] = {0};
|
@@ -445,7 +452,14 @@ aggregate_rest_object_i(st_data_t key, st_data_t val, void *data)
|
|
445
452
|
{
|
446
453
|
struct traceobj_arg *arg = (struct traceobj_arg *)data;
|
447
454
|
struct allocation_info *info = (struct allocation_info *)val;
|
455
|
+
VALUE obj = (VALUE)key;
|
456
|
+
|
457
|
+
if ((info->flags & T_MASK) == (RBASIC(obj)->flags & T_MASK)) {
|
458
|
+
info->flags = RBASIC(obj)->flags;
|
459
|
+
}
|
460
|
+
/* danger operation because obj can be collected. */
|
448
461
|
move_to_freed_list(arg, info);
|
462
|
+
|
449
463
|
return ST_CONTINUE;
|
450
464
|
}
|
451
465
|
|
@@ -553,11 +567,11 @@ allocation_tracer_header(VALUE self)
|
|
553
567
|
if (arg->keys & KEY_CLASS) rb_ary_push(ary, ID2SYM(rb_intern("class")));
|
554
568
|
|
555
569
|
if (arg->vals & VAL_COUNT) rb_ary_push(ary, ID2SYM(rb_intern("count")));
|
570
|
+
if (arg->vals & VAL_OLDCOUNT) rb_ary_push(ary, ID2SYM(rb_intern("old_count")));
|
556
571
|
if (arg->vals & VAL_TOTAL_AGE) rb_ary_push(ary, ID2SYM(rb_intern("total_age")));
|
557
|
-
if (arg->vals & VAL_MAX_AGE) rb_ary_push(ary, ID2SYM(rb_intern("max_age")));
|
558
572
|
if (arg->vals & VAL_MIN_AGE) rb_ary_push(ary, ID2SYM(rb_intern("min_age")));
|
559
|
-
if (arg->vals &
|
560
|
-
|
573
|
+
if (arg->vals & VAL_MAX_AGE) rb_ary_push(ary, ID2SYM(rb_intern("max_age")));
|
574
|
+
if (arg->vals & VAL_MEMSIZE) rb_ary_push(ary, ID2SYM(rb_intern("total_memsize")));
|
561
575
|
return ary;
|
562
576
|
}
|
563
577
|
|
Binary file
|
@@ -11,7 +11,7 @@ describe ObjectSpace::AllocationTracer do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
expect(result.length).to be >= 1
|
14
|
-
expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0, 0]
|
14
|
+
expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0, 0, 0]
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'should run twice' do
|
@@ -19,9 +19,23 @@ describe ObjectSpace::AllocationTracer do
|
|
19
19
|
result = ObjectSpace::AllocationTracer.trace do
|
20
20
|
Object.new
|
21
21
|
end
|
22
|
+
#GC.start
|
23
|
+
# p result
|
24
|
+
expect(result.length).to be >= 1
|
25
|
+
expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0, 0, 0]
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should count old objects' do
|
29
|
+
a = nil
|
30
|
+
line = __LINE__ + 2
|
31
|
+
result = ObjectSpace::AllocationTracer.trace do
|
32
|
+
a = 'x' # it will be old object
|
33
|
+
32.times{GC.start}
|
34
|
+
end
|
22
35
|
|
23
36
|
expect(result.length).to be >= 1
|
24
|
-
|
37
|
+
_, old_count, * = *result[[__FILE__, line]]
|
38
|
+
expect(old_count).to be == 1
|
25
39
|
end
|
26
40
|
|
27
41
|
it 'should acquire allocated memsize' do
|
@@ -32,7 +46,8 @@ describe ObjectSpace::AllocationTracer do
|
|
32
46
|
end
|
33
47
|
|
34
48
|
expect(result.length).to be >= 1
|
35
|
-
|
49
|
+
size = result[[__FILE__, line]][-1]
|
50
|
+
expect(size).to be > 1234 if size > 0
|
36
51
|
end
|
37
52
|
|
38
53
|
describe 'with different setup' do
|
@@ -45,11 +60,11 @@ describe ObjectSpace::AllocationTracer do
|
|
45
60
|
end
|
46
61
|
|
47
62
|
expect(result.length).to be 5
|
48
|
-
expect(result[[__FILE__, line, :T_OBJECT]]).to eq [1, 0, 0, 0, 0]
|
49
|
-
expect(result[[__FILE__, line, :T_ARRAY]]).to eq [1, 0, 0, 0, 0]
|
63
|
+
expect(result[[__FILE__, line, :T_OBJECT]]).to eq [1, 0, 0, 0, 0, 0]
|
64
|
+
expect(result[[__FILE__, line, :T_ARRAY]]).to eq [1, 0, 0, 0, 0, 0]
|
50
65
|
# expect(result[[__FILE__, line + 1, :T_HASH]]).to eq [1, 0, 0, 0, 0]
|
51
|
-
expect(result[[__FILE__, line + 1, :T_OBJECT]]).to eq [1, 0, 0, 0, 0]
|
52
|
-
expect(result[[__FILE__, line + 1, :T_STRING]]).to eq [1, 0, 0, 0, 0]
|
66
|
+
expect(result[[__FILE__, line + 1, :T_OBJECT]]).to eq [1, 0, 0, 0, 0, 0]
|
67
|
+
expect(result[[__FILE__, line + 1, :T_STRING]]).to eq [1, 0, 0, 0, 0, 0]
|
53
68
|
end
|
54
69
|
|
55
70
|
it 'should work with class' do
|
@@ -61,11 +76,11 @@ describe ObjectSpace::AllocationTracer do
|
|
61
76
|
end
|
62
77
|
|
63
78
|
expect(result.length).to be 5
|
64
|
-
expect(result[[__FILE__, line, Object]]).to eq [1, 0, 0, 0, 0]
|
65
|
-
expect(result[[__FILE__, line, Array]]).to eq [1, 0, 0, 0, 0]
|
66
|
-
# expect(result[[__FILE__, line + 1, Hash]]).to eq [1, 0, 0, 0, 0]
|
67
|
-
expect(result[[__FILE__, line + 1, Object]]).to eq [1, 0, 0, 0, 0]
|
68
|
-
expect(result[[__FILE__, line + 1, String]]).to eq [1, 0, 0, 0, 0]
|
79
|
+
expect(result[[__FILE__, line, Object]]).to eq [1, 0, 0, 0, 0, 0]
|
80
|
+
expect(result[[__FILE__, line, Array]]).to eq [1, 0, 0, 0, 0, 0]
|
81
|
+
# expect(result[[__FILE__, line + 1, Hash]]).to eq [1, 0, 0, 0, 0, 0]
|
82
|
+
expect(result[[__FILE__, line + 1, Object]]).to eq [1, 0, 0, 0, 0, 0]
|
83
|
+
expect(result[[__FILE__, line + 1, String]]).to eq [1, 0, 0, 0, 0, 0]
|
69
84
|
end
|
70
85
|
end
|
71
86
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: allocation_tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Sasada
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|