allocation_tracer 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1f129686d0942e7690ff66568f9af7f50f11148
4
- data.tar.gz: fbc17e5b8358996aa55843c8632e15896d14f16d
3
+ metadata.gz: 76c7a52b186ed762bc19644997b2d57e66fbb431
4
+ data.tar.gz: 2b945274f4255f0c06374354a66bde0d0f3bcf13
5
5
  SHA512:
6
- metadata.gz: 886adb15a4f94f3fd9ed2815f9aee9fa524bf48aa853ceafb9bf2ff450a5dcd204ce8b8c483029ba78d1bc81f2124e7bb6662770d253e2aed58262c24a54e8ad
7
- data.tar.gz: 69b0c17158f3f8af672296a4868c609a2f12c0c8b8d10d08b7d2309c6357b35b2b9f843986594c62bfad1549a62aeae12f90e9cfe3db3c299ee59f5001b07b00
6
+ metadata.gz: 518dcab890b67dab01d987ef98a277c7364521777c5c9edef0057543cc34719a369ceec93d81c020dd96700894c0da3aeb582d2b19720e7b3fc5899f26543e18
7
+ data.tar.gz: 6b7792f6f02388a69d4fb21a92b2cb9c94605125db49c14af5821fd5700c5be99b2b892c646300030130b25fad4b320a33bb65f100d50c7fe8ac92e9fee4cd86
@@ -8,6 +8,8 @@
8
8
  #include "ruby/ruby.h"
9
9
  #include "ruby/debug.h"
10
10
 
11
+ size_t rb_obj_memsize_of(VALUE obj); /* in gc.c */
12
+
11
13
  static VALUE rb_mAllocationTracer;
12
14
 
13
15
  struct allocation_info {
@@ -16,6 +18,7 @@ struct allocation_info {
16
18
  VALUE flags;
17
19
  VALUE klass;
18
20
  size_t generation;
21
+ size_t memsize;
19
22
 
20
23
  /* allocation info */
21
24
  const char *path;
@@ -33,6 +36,7 @@ struct allocation_info {
33
36
  #define VAL_TOTAL_AGE (1<<2)
34
37
  #define VAL_MAX_AGE (1<<3)
35
38
  #define VAL_MIN_AGE (1<<4)
39
+ #define VAL_MEMSIZE (1<<5)
36
40
 
37
41
  struct traceobj_arg {
38
42
  int running;
@@ -133,7 +137,7 @@ get_traceobj_arg(void)
133
137
  tmp_trace_arg = ALLOC_N(struct traceobj_arg, 1);
134
138
  tmp_trace_arg->running = 0;
135
139
  tmp_trace_arg->keys = 0;
136
- tmp_trace_arg->vals = VAL_COUNT | VAL_TOTAL_AGE | VAL_MAX_AGE | VAL_MIN_AGE;
140
+ tmp_trace_arg->vals = VAL_COUNT | VAL_TOTAL_AGE | VAL_MAX_AGE | VAL_MIN_AGE | VAL_MEMSIZE;
137
141
  tmp_trace_arg->aggregate_table = st_init_table(&memcmp_hash_type);
138
142
  tmp_trace_arg->object_table = st_init_numtable();
139
143
  tmp_trace_arg->str_table = st_init_strtable();
@@ -199,6 +203,7 @@ newobj_i(VALUE tpval, void *data)
199
203
  VALUE obj = rb_tracearg_object(tparg);
200
204
  VALUE path = rb_tracearg_path(tparg);
201
205
  VALUE line = rb_tracearg_lineno(tparg);
206
+ VALUE klass = RBASIC_CLASS(obj);
202
207
  const char *path_cstr = RTEST(path) ? make_unique_str(arg->str_table, RSTRING_PTR(path), RSTRING_LEN(path)) : NULL;
203
208
 
204
209
  if (st_lookup(arg->object_table, (st_data_t)obj, (st_data_t *)&info)) {
@@ -215,7 +220,7 @@ newobj_i(VALUE tpval, void *data)
215
220
  info->next = NULL;
216
221
  info->living = 1;
217
222
  info->flags = RBASIC(obj)->flags;
218
- info->klass = rb_class_real(RBASIC_CLASS(obj));
223
+ info->klass = RTEST(klass) ? rb_class_real(klass) : Qnil;
219
224
  info->generation = rb_gc_count();
220
225
 
221
226
  info->path = path_cstr;
@@ -240,8 +245,8 @@ aggregator_i(void *data)
240
245
  struct allocation_info *next_info = info->next;
241
246
  st_data_t key, val;
242
247
  struct memcmp_key_data key_data;
243
- int *val_buff;
244
- int age = (int)(gc_count - info->generation);
248
+ size_t *val_buff;
249
+ size_t age = (int)(gc_count - info->generation);
245
250
  int i;
246
251
 
247
252
  i = 0;
@@ -270,22 +275,24 @@ aggregator_i(void *data)
270
275
  key = (st_data_t)key_buff;
271
276
 
272
277
  /* count, total age, max age, min age */
273
- val_buff = ALLOC_N(int, 4);
278
+ val_buff = ALLOC_N(size_t, 5);
274
279
  val_buff[0] = val_buff[1] = 0;
275
280
  val_buff[2] = val_buff[3] = age;
281
+ val_buff[4] = 0;
276
282
 
277
283
  if (arg->keys & KEY_PATH) keep_unique_str(arg->str_table, info->path);
278
284
 
279
285
  st_insert(arg->aggregate_table, (st_data_t)key_buff, (st_data_t)val_buff);
280
286
  }
281
287
  else {
282
- val_buff = (int *)val;
288
+ val_buff = (size_t *)val;
283
289
  }
284
290
 
285
291
  val_buff[0] += 1;
286
292
  val_buff[1] += age;
287
293
  if (val_buff[2] > age) val_buff[2] = age;
288
294
  if (val_buff[3] < age) val_buff[3] = age;
295
+ val_buff[4] += info->memsize;
289
296
 
290
297
  free_allocation_info(arg, info);
291
298
  info = next_info;
@@ -293,8 +300,9 @@ aggregator_i(void *data)
293
300
  }
294
301
 
295
302
  static void
296
- move_to_freed_list(struct traceobj_arg *arg, struct allocation_info *info)
303
+ move_to_freed_list(struct traceobj_arg *arg, VALUE obj, struct allocation_info *info)
297
304
  {
305
+ info->memsize = rb_obj_memsize_of(obj);
298
306
  info->next = arg->freed_allocation_info;
299
307
  arg->freed_allocation_info = info;
300
308
  }
@@ -312,7 +320,7 @@ freeobj_i(VALUE tpval, void *data)
312
320
  }
313
321
 
314
322
  if (st_lookup(arg->object_table, (st_data_t)obj, (st_data_t *)&info)) {
315
- move_to_freed_list(arg, info);
323
+ move_to_freed_list(arg, obj, info);
316
324
  st_delete(arg->object_table, (st_data_t *)&obj, (st_data_t *)&info);
317
325
  }
318
326
  }
@@ -382,9 +390,9 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
382
390
  struct traceobj_arg *arg = aar->arg;
383
391
  VALUE result = aar->result;
384
392
 
385
- int *val_buff = (int *)val;
393
+ size_t *val_buff = (size_t *)val;
386
394
  struct memcmp_key_data *key_buff = (struct memcmp_key_data *)key;
387
- VALUE v = rb_ary_new3(4, INT2FIX(val_buff[0]), INT2FIX(val_buff[1]), INT2FIX(val_buff[2]), INT2FIX(val_buff[3]));
395
+ VALUE v = rb_ary_new3(5, INT2FIX(val_buff[0]), INT2FIX(val_buff[1]), INT2FIX(val_buff[2]), INT2FIX(val_buff[3]), INT2FIX(val_buff[4]));
388
396
  VALUE k = rb_ary_new();
389
397
  int i = 0;
390
398
  static VALUE type_symbols[T_MASK] = {0};
@@ -415,7 +423,7 @@ aggregate_result_i(st_data_t key, st_data_t val, void *data)
415
423
  }
416
424
  if (arg->keys & KEY_CLASS) {
417
425
  VALUE klass = key_buff->data[i++];
418
- if (BUILTIN_TYPE(klass) == T_CLASS) {
426
+ if (RTEST(klass) && BUILTIN_TYPE(klass) == T_CLASS) {
419
427
  klass = rb_class_real(klass);
420
428
  rb_ary_push(k, klass);
421
429
  /* TODO: actually, it is dangerous code because klass can be sweeped */
@@ -436,7 +444,7 @@ aggregate_rest_object_i(st_data_t key, st_data_t val, void *data)
436
444
  {
437
445
  struct traceobj_arg *arg = (struct traceobj_arg *)data;
438
446
  struct allocation_info *info = (struct allocation_info *)val;
439
- move_to_freed_list(arg, info);
447
+ move_to_freed_list(arg, (VALUE)key, info);
440
448
  return ST_CONTINUE;
441
449
  }
442
450
 
@@ -547,6 +555,7 @@ allocation_tracer_header(VALUE self)
547
555
  if (arg->vals & VAL_TOTAL_AGE) rb_ary_push(ary, ID2SYM(rb_intern("total_age")));
548
556
  if (arg->vals & VAL_MAX_AGE) rb_ary_push(ary, ID2SYM(rb_intern("max_age")));
549
557
  if (arg->vals & VAL_MIN_AGE) rb_ary_push(ary, ID2SYM(rb_intern("min_age")));
558
+ if (arg->vals & VAL_MEMSIZE) rb_ary_push(ary, ID2SYM(rb_intern("memsize")));
550
559
 
551
560
  return ary;
552
561
  }
@@ -1,3 +1,3 @@
1
1
  module ObjectSpace::AllocationTracer
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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]
14
+ expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0, 0]
15
15
  end
16
16
 
17
17
  it 'should run twice' do
@@ -21,7 +21,17 @@ describe ObjectSpace::AllocationTracer do
21
21
  end
22
22
 
23
23
  expect(result.length).to be >= 1
24
- expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0]
24
+ expect(result[[__FILE__, line]]).to eq [1, 0, 0, 0, 0]
25
+ end
26
+
27
+ it 'should acquire allocated memsize' do
28
+ line = __LINE__ + 2
29
+ result = ObjectSpace::AllocationTracer.trace do
30
+ a = 'x' * 1234
31
+ end
32
+
33
+ expect(result.length).to be >= 1
34
+ expect(result[[__FILE__, line]][-1]).to be > 1234
25
35
  end
26
36
 
27
37
  describe 'with different setup' do
@@ -34,11 +44,11 @@ describe ObjectSpace::AllocationTracer do
34
44
  end
35
45
 
36
46
  expect(result.length).to be 5
37
- expect(result[[__FILE__, line, :T_OBJECT]]).to eq [1, 0, 0, 0]
38
- expect(result[[__FILE__, line, :T_ARRAY]]).to eq [1, 0, 0, 0]
39
- expect(result[[__FILE__, line + 1, :T_HASH]]).to eq [1, 0, 0, 0]
40
- expect(result[[__FILE__, line + 1, :T_OBJECT]]).to eq [1, 0, 0, 0]
41
- expect(result[[__FILE__, line + 1, :T_STRING]]).to eq [1, 0, 0, 0]
47
+ expect(result[[__FILE__, line, :T_OBJECT]]).to eq [1, 0, 0, 0, 0]
48
+ expect(result[[__FILE__, line, :T_ARRAY]]).to eq [1, 0, 0, 0, 0]
49
+ # expect(result[[__FILE__, line + 1, :T_HASH]]).to eq [1, 0, 0, 0, 0]
50
+ expect(result[[__FILE__, line + 1, :T_OBJECT]]).to eq [1, 0, 0, 0, 0]
51
+ expect(result[[__FILE__, line + 1, :T_STRING]]).to eq [1, 0, 0, 0, 0]
42
52
  end
43
53
 
44
54
  it 'should work with class' do
@@ -50,11 +60,11 @@ describe ObjectSpace::AllocationTracer do
50
60
  end
51
61
 
52
62
  expect(result.length).to be 5
53
- expect(result[[__FILE__, line, Object]]).to eq [1, 0, 0, 0]
54
- expect(result[[__FILE__, line, Array]]).to eq [1, 0, 0, 0]
55
- expect(result[[__FILE__, line + 1, Hash]]).to eq [1, 0, 0, 0]
56
- expect(result[[__FILE__, line + 1, Object]]).to eq [1, 0, 0, 0]
57
- expect(result[[__FILE__, line + 1, String]]).to eq [1, 0, 0, 0]
63
+ expect(result[[__FILE__, line, Object]]).to eq [1, 0, 0, 0, 0]
64
+ expect(result[[__FILE__, line, Array]]).to eq [1, 0, 0, 0, 0]
65
+ # expect(result[[__FILE__, line + 1, Hash]]).to eq [1, 0, 0, 0, 0]
66
+ expect(result[[__FILE__, line + 1, Object]]).to eq [1, 0, 0, 0, 0]
67
+ expect(result[[__FILE__, line + 1, String]]).to eq [1, 0, 0, 0, 0]
58
68
  end
59
69
  end
60
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allocation_tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada