allocation_tracer 0.0.2 → 0.0.3

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: 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