ruby-prof 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGES +23 -13
  2. data/{README → README.rdoc} +118 -111
  3. data/Rakefile +14 -26
  4. data/bin/ruby-prof +16 -4
  5. data/examples/empty.png +0 -0
  6. data/examples/graph.dot +106 -0
  7. data/examples/graph.png +0 -0
  8. data/examples/minus.png +0 -0
  9. data/examples/multi.flat.txt +23 -0
  10. data/examples/multi.graph.html +906 -0
  11. data/examples/multi.grind.dat +194 -0
  12. data/examples/multi.stack.html +573 -0
  13. data/examples/plus.png +0 -0
  14. data/examples/stack.html +573 -0
  15. data/ext/ruby_prof/extconf.rb +0 -1
  16. data/ext/ruby_prof/measure_allocations.h +6 -6
  17. data/ext/ruby_prof/measure_cpu_time.h +5 -5
  18. data/ext/ruby_prof/measure_gc_runs.h +1 -1
  19. data/ext/ruby_prof/measure_gc_time.h +1 -1
  20. data/ext/ruby_prof/measure_memory.h +4 -4
  21. data/ext/ruby_prof/measure_process_time.h +1 -1
  22. data/ext/ruby_prof/measure_wall_time.h +1 -1
  23. data/ext/ruby_prof/ruby_prof.c +240 -167
  24. data/ext/ruby_prof/ruby_prof.h +12 -10
  25. data/ext/ruby_prof/version.h +3 -3
  26. data/lib/ruby-prof.rb +7 -1
  27. data/lib/ruby-prof/abstract_printer.rb +5 -5
  28. data/lib/ruby-prof/aggregate_call_info.rb +9 -3
  29. data/lib/ruby-prof/call_info.rb +66 -1
  30. data/lib/ruby-prof/call_stack_printer.rb +751 -0
  31. data/lib/ruby-prof/call_tree_printer.rb +2 -2
  32. data/lib/ruby-prof/dot_printer.rb +151 -0
  33. data/lib/ruby-prof/empty.png +0 -0
  34. data/lib/ruby-prof/flat_printer.rb +16 -16
  35. data/lib/ruby-prof/flat_printer_with_line_numbers.rb +13 -13
  36. data/lib/ruby-prof/graph_html_printer.rb +58 -36
  37. data/lib/ruby-prof/graph_printer.rb +30 -30
  38. data/lib/ruby-prof/method_info.rb +24 -4
  39. data/lib/ruby-prof/minus.png +0 -0
  40. data/lib/ruby-prof/multi_printer.rb +54 -0
  41. data/lib/ruby-prof/plus.png +0 -0
  42. data/lib/ruby-prof/rack.rb +28 -0
  43. data/lib/ruby-prof/result.rb +70 -0
  44. data/lib/ruby-prof/symbol_to_proc.rb +1 -1
  45. data/lib/ruby-prof/task.rb +19 -19
  46. data/lib/ruby-prof/test.rb +3 -3
  47. data/lib/ruby_prof.so +0 -0
  48. data/rails/environment/profile.rb +2 -2
  49. data/rails/example/example_test.rb +2 -2
  50. data/rails/profile_test_helper.rb +1 -1
  51. data/test/aggregate_test.rb +21 -6
  52. data/test/basic_test.rb +3 -3
  53. data/test/duplicate_names_test.rb +2 -2
  54. data/test/enumerable_test.rb +2 -2
  55. data/test/exceptions_test.rb +2 -2
  56. data/test/exclude_threads_test.rb +45 -45
  57. data/test/exec_test.rb +2 -2
  58. data/test/line_number_test.rb +11 -11
  59. data/test/measurement_test.rb +4 -3
  60. data/test/method_elimination_test.rb +74 -0
  61. data/test/module_test.rb +7 -7
  62. data/test/multi_printer_test.rb +81 -0
  63. data/test/no_method_class_test.rb +2 -2
  64. data/test/prime.rb +7 -10
  65. data/test/printers_test.rb +57 -47
  66. data/test/recursive_test.rb +23 -62
  67. data/test/singleton_test.rb +3 -2
  68. data/test/stack_printer_test.rb +74 -0
  69. data/test/stack_test.rb +1 -1
  70. data/test/start_stop_test.rb +2 -2
  71. data/test/test_suite.rb +9 -0
  72. data/test/thread_test.rb +17 -17
  73. data/test/unique_call_path_test.rb +4 -4
  74. metadata +29 -8
@@ -39,6 +39,5 @@ def add_define(name, value = nil)
39
39
  end
40
40
  end
41
41
 
42
- add_define 'DEBUG' if $DEBUG
43
42
  add_define("RUBY_VERSION", RUBY_VERSION.gsub('.', ''))
44
43
  create_makefile("ruby_prof")
@@ -1,4 +1,4 @@
1
- /* :nodoc:
1
+ /* :nodoc:
2
2
  * Copyright (C) 2008 Shugo Maeda <shugo@ruby-lang.org>
3
3
  * Charlie Savage <cfis@savagexi.com>
4
4
  * All rights reserved.
@@ -28,17 +28,17 @@
28
28
 
29
29
  #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS)
30
30
  #define MEASURE_ALLOCATIONS 3
31
-
31
+
32
32
  static prof_measure_t
33
33
  measure_allocations()
34
- {
35
- return rb_os_allocated_objects();
34
+ {
35
+ return rb_os_allocated_objects();
36
36
  }
37
37
 
38
38
  static double
39
39
  convert_allocations(prof_measure_t c)
40
- {
41
- return c;
40
+ {
41
+ return c;
42
42
  }
43
43
 
44
44
  /* Document-method: prof_measure_allocations
@@ -1,4 +1,4 @@
1
- /* :nodoc:
1
+ /* :nodoc:
2
2
  * Copyright (C) 2008 Shugo Maeda <shugo@ruby-lang.org>
3
3
  * Charlie Savage <cfis@savagexi.com>
4
4
  * All rights reserved.
@@ -38,7 +38,7 @@ static unsigned LONG_LONG cpu_frequency;
38
38
  static prof_measure_t
39
39
  measure_cpu_time()
40
40
  {
41
- #if defined(__i386__) || defined(__x86_64__)
41
+ #if defined(__i386__) || defined(__x86_64__)
42
42
  uint32_t a, d;
43
43
  __asm__ volatile("rdtsc" : "=a" (a), "=d" (d));
44
44
  return ((uint64_t)d << 32) + a;
@@ -46,7 +46,7 @@ measure_cpu_time()
46
46
  unsigned long long x, y;
47
47
 
48
48
  __asm__ __volatile__ ("\n\
49
- 1: mftbu %1\n\
49
+ 1: mftbu %1\n\
50
50
  mftb %L0\n\
51
51
  mftbu %0\n\
52
52
  cmpw %0,%1\n\
@@ -128,7 +128,7 @@ prof_measure_cpu_time(VALUE self)
128
128
  call-seq:
129
129
  cpu_frequency -> int
130
130
 
131
- Returns the cpu's frequency. This value is needed when
131
+ Returns the cpu's frequency. This value is needed when
132
132
  RubyProf::measure_mode is set to CPU_TIME. */
133
133
  static VALUE
134
134
  prof_get_cpu_frequency(VALUE self)
@@ -140,7 +140,7 @@ prof_get_cpu_frequency(VALUE self)
140
140
  call-seq:
141
141
  cpu_frequency=value -> void
142
142
 
143
- Sets the cpu's frequency. This value is needed when
143
+ Sets the cpu's frequency. This value is needed when
144
144
  RubyProf::measure_mode is set to CPU_TIME. */
145
145
  static VALUE
146
146
  prof_set_cpu_frequency(VALUE self, VALUE val)
@@ -1,4 +1,4 @@
1
- /* :nodoc:
1
+ /* :nodoc:
2
2
  * Copyright (C) 2008 Shugo Maeda <shugo@ruby-lang.org>
3
3
  * Charlie Savage <cfis@savagexi.com>
4
4
  * All rights reserved.
@@ -1,4 +1,4 @@
1
- /* :nodoc:
1
+ /* :nodoc:
2
2
  * Copyright (C) 2008 Shugo Maeda <shugo@ruby-lang.org>
3
3
  * Charlie Savage <cfis@savagexi.com>
4
4
  * All rights reserved.
@@ -1,4 +1,4 @@
1
- /* :nodoc:
1
+ /* :nodoc:
2
2
  * Copyright (C) 2008 Alexander Dymo <adymo@pluron.com>
3
3
  *
4
4
  * All rights reserved.
@@ -28,7 +28,7 @@
28
28
  #if defined(HAVE_RB_GC_ALLOCATED_SIZE)
29
29
  #define MEASURE_MEMORY 4
30
30
  #define TOGGLE_GC_STATS 1
31
-
31
+
32
32
  static prof_measure_t
33
33
  measure_memory()
34
34
  {
@@ -41,8 +41,8 @@ measure_memory()
41
41
 
42
42
  static double
43
43
  convert_memory(prof_measure_t c)
44
- {
45
- return (double) c / 1024;
44
+ {
45
+ return (double) c / 1024;
46
46
  }
47
47
 
48
48
  /* Document-method: prof_measure_memory
@@ -31,7 +31,7 @@
31
31
  static prof_measure_t
32
32
  measure_process_time()
33
33
  {
34
- return clock();
34
+ return clock(); // cpu usage (with poor precision) in linux (TODO), wall time in doze (TODO)
35
35
  }
36
36
 
37
37
  static double
@@ -1,4 +1,4 @@
1
- /* :nodoc:
1
+ /* :nodoc:
2
2
  * Copyright (C) 2008 Shugo Maeda <shugo@ruby-lang.org>
3
3
  * Charlie Savage <cfis@savagexi.com>
4
4
  * All rights reserved.
@@ -29,22 +29,22 @@
29
29
  The main players are:
30
30
 
31
31
  prof_result_t - Its one field, values, contains the overall results
32
- thread_data_t - Stores data about a single thread.
32
+ thread_data_t - Stores data about a single thread.
33
33
  prof_stack_t - The method call stack in a particular thread
34
34
  prof_method_t - Profiling information for each method
35
- prof_call_info_t - Keeps track a method's callers and callees.
35
+ prof_call_info_t - Keeps track a method's callers and callees.
36
36
 
37
37
  The final resulut is a hash table of thread_data_t, keyed on the thread
38
38
  id. Each thread has an hash a table of prof_method_t, keyed on the
39
39
  method id. A hash table is used for quick look up when doing a profile.
40
40
  However, it is exposed to Ruby as an array.
41
-
41
+
42
42
  Each prof_method_t has two hash tables, parent and children, of prof_call_info_t.
43
43
  These objects keep track of a method's callers (who called the method) and its
44
44
  callees (who the method called). These are keyed the method id, but once again,
45
45
  are exposed to Ruby as arrays. Each prof_call_into_t maintains a pointer to the
46
- caller or callee method, thereby making it easy to navigate through the call
47
- hierarchy in ruby - which is very helpful for creating call graphs.
46
+ caller or callee method, thereby making it easy to navigate through the call
47
+ hierarchy in ruby - which is very helpful for creating call graphs.
48
48
  */
49
49
 
50
50
  #include "ruby_prof.h"
@@ -92,7 +92,7 @@ figure_singleton_name(VALUE klass)
92
92
  rb_str_append(result, rb_inspect(super));
93
93
  rb_str_cat2(result, ">");
94
94
  }
95
-
95
+
96
96
  /* Ok, this could be other things like an array made put onto
97
97
  a singleton object (yeah, it happens, see the singleton
98
98
  objects test case). */
@@ -108,7 +108,7 @@ static VALUE
108
108
  klass_name(VALUE klass)
109
109
  {
110
110
  VALUE result = Qnil;
111
-
111
+
112
112
  if (klass == 0 || klass == Qnil)
113
113
  {
114
114
  result = rb_str_new2("Global");
@@ -135,34 +135,27 @@ klass_name(VALUE klass)
135
135
  }
136
136
 
137
137
  static VALUE
138
- method_name(ID mid, int depth)
138
+ method_name(ID mid)
139
139
  {
140
140
  VALUE result;
141
141
 
142
- if (mid == ID_ALLOCATOR)
142
+ if (mid == ID_ALLOCATOR)
143
143
  result = rb_str_new2("allocate");
144
144
  else if (mid == 0)
145
145
  result = rb_str_new2("[No method]");
146
146
  else
147
147
  result = rb_String(ID2SYM(mid));
148
-
149
- if (depth > 0)
150
- {
151
- char buffer[65];
152
- sprintf(buffer, "(d%i)", depth);
153
- rb_str_cat2(result, buffer);
154
- }
155
148
 
156
149
  return result;
157
150
  }
158
151
 
159
152
  static VALUE
160
- full_name(VALUE klass, ID mid, int depth)
153
+ full_name(VALUE klass, ID mid)
161
154
  {
162
155
  VALUE result = klass_name(klass);
163
156
  rb_str_cat2(result, "#");
164
- rb_str_append(result, method_name(mid, depth));
165
-
157
+ rb_str_append(result, method_name(mid));
158
+
166
159
  return result;
167
160
  }
168
161
 
@@ -221,16 +214,14 @@ stack_peek(prof_stack_t *stack)
221
214
  }
222
215
 
223
216
  /* ================ Method Key =================*/
224
- static int
225
- method_table_cmp(prof_method_key_t *key1, prof_method_key_t *key2)
217
+ static int
218
+ method_table_cmp(prof_method_key_t *key1, prof_method_key_t *key2)
226
219
  {
227
- return (key1->klass != key2->klass) ||
228
- (key1->mid != key2->mid) ||
229
- (key1->depth != key2->depth);
220
+ return (key1->klass != key2->klass) || (key1->mid != key2->mid);
230
221
  }
231
222
 
232
- static int
233
- method_table_hash(prof_method_key_t *key)
223
+ static st_index_t
224
+ method_table_hash(prof_method_key_t *key)
234
225
  {
235
226
  return key->key;
236
227
  }
@@ -241,12 +232,11 @@ static struct st_hash_type type_method_hash = {
241
232
  };
242
233
 
243
234
  static void
244
- method_key(prof_method_key_t* key, VALUE klass, ID mid, int depth)
235
+ method_key(prof_method_key_t* key, VALUE klass, ID mid)
245
236
  {
246
237
  key->klass = klass;
247
238
  key->mid = mid;
248
- key->depth = depth;
249
- key->key = (klass << 4) + (mid << 2) + depth;
239
+ key->key = (klass << 4) + (mid << 2);
250
240
  }
251
241
 
252
242
 
@@ -334,7 +324,7 @@ prof_call_info_mark(prof_call_info_t *call_info)
334
324
  static void
335
325
  prof_call_info_free(prof_call_info_t *call_info)
336
326
  {
337
- call_info_table_free(call_info->call_infos);
327
+ call_info_table_free(call_info->call_infos);
338
328
  xfree(call_info);
339
329
  }
340
330
 
@@ -370,7 +360,7 @@ prof_call_info_target(VALUE self)
370
360
  /* Target is a pointer to a method_info - so we have to be careful
371
361
  about the GC. We will wrap the method_info but provide no
372
362
  free method so the underlying object is not freed twice! */
373
-
363
+
374
364
  prof_call_info_t *result = prof_get_call_info_result(self);
375
365
  return prof_method_wrap(result->target);
376
366
  }
@@ -386,6 +376,18 @@ prof_call_info_called(VALUE self)
386
376
  return INT2NUM(result->called);
387
377
  }
388
378
 
379
+ /* call-seq:
380
+ called=n -> n
381
+
382
+ Sets the call count to n. */
383
+ static VALUE
384
+ prof_call_info_set_called(VALUE self, VALUE called)
385
+ {
386
+ prof_call_info_t *result = prof_get_call_info_result(self);
387
+ result->called = NUM2INT(called);
388
+ return called;
389
+ }
390
+
389
391
  /* call-seq:
390
392
  line_no -> int
391
393
 
@@ -408,6 +410,20 @@ prof_call_info_total_time(VALUE self)
408
410
  return rb_float_new(convert_measurement(result->total_time));
409
411
  }
410
412
 
413
+ /* call-seq:
414
+ add_total_time(call_info) -> nil
415
+
416
+ adds total time time from call_info to self. */
417
+ static VALUE
418
+ prof_call_info_add_total_time(VALUE self, VALUE other)
419
+ {
420
+ prof_call_info_t *result = prof_get_call_info_result(self);
421
+ prof_call_info_t *other_info = prof_get_call_info_result(other);
422
+
423
+ result->total_time += other_info->total_time;
424
+ return Qnil;
425
+ }
426
+
411
427
  /* call-seq:
412
428
  self_time -> float
413
429
 
@@ -420,6 +436,20 @@ prof_call_info_self_time(VALUE self)
420
436
  return rb_float_new(convert_measurement(result->self_time));
421
437
  }
422
438
 
439
+ /* call-seq:
440
+ add_self_time(call_info) -> nil
441
+
442
+ adds self time from call_info to self. */
443
+ static VALUE
444
+ prof_call_info_add_self_time(VALUE self, VALUE other)
445
+ {
446
+ prof_call_info_t *result = prof_get_call_info_result(self);
447
+ prof_call_info_t *other_info = prof_get_call_info_result(other);
448
+
449
+ result->self_time += other_info->self_time;
450
+ return Qnil;
451
+ }
452
+
423
453
  /* call-seq:
424
454
  wait_time -> float
425
455
 
@@ -432,6 +462,21 @@ prof_call_info_wait_time(VALUE self)
432
462
  return rb_float_new(convert_measurement(result->wait_time));
433
463
  }
434
464
 
465
+ /* call-seq:
466
+ add_wait_time(call_info) -> nil
467
+
468
+ adds wait time from call_info to self. */
469
+
470
+ static VALUE
471
+ prof_call_info_add_wait_time(VALUE self, VALUE other)
472
+ {
473
+ prof_call_info_t *result = prof_get_call_info_result(self);
474
+ prof_call_info_t *other_info = prof_get_call_info_result(other);
475
+
476
+ result->wait_time += other_info->wait_time;
477
+ return Qnil;
478
+ }
479
+
435
480
  /* call-seq:
436
481
  parent -> call_info
437
482
 
@@ -446,6 +491,21 @@ prof_call_info_parent(VALUE self)
446
491
  return Qnil;
447
492
  }
448
493
 
494
+ /* call-seq:
495
+ parent=new_parent -> new_parent
496
+
497
+ Changes the parent of self to new_parent and returns it.*/
498
+ static VALUE
499
+ prof_call_info_set_parent(VALUE self, VALUE new_parent)
500
+ {
501
+ prof_call_info_t *result = prof_get_call_info_result(self);
502
+ if (new_parent == Qnil)
503
+ result->parent = NULL;
504
+ else
505
+ result->parent = prof_get_call_info_result(new_parent);
506
+ return prof_call_info_parent(self);
507
+ }
508
+
449
509
  static int
450
510
  prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result)
451
511
  {
@@ -458,7 +518,7 @@ prof_call_info_collect_children(st_data_t key, st_data_t value, st_data_t result
458
518
  /* call-seq:
459
519
  children -> hash
460
520
 
461
- Returns an array of call info objects of methods that this method
521
+ Returns an array of call info objects of methods that this method
462
522
  called (ie, children).*/
463
523
  static VALUE
464
524
  prof_call_info_children(VALUE self)
@@ -539,24 +599,22 @@ prof_method_create(prof_method_key_t *key, const char* source_file, int line)
539
599
  prof_method_t *result = ALLOC(prof_method_t);
540
600
  result->object = Qnil;
541
601
  result->key = ALLOC(prof_method_key_t);
542
- method_key(result->key, key->klass, key->mid, key->depth);
602
+ method_key(result->key, key->klass, key->mid);
543
603
 
544
604
  result->call_infos = prof_call_infos_create();
545
605
 
546
- result->active = 0;
547
-
548
- if (source_file != NULL)
606
+ if (source_file != NULL)
549
607
  {
550
- int len = strlen(source_file) + 1;
608
+ size_t len = strlen(source_file) + 1;
551
609
  char *buffer = ALLOC_N(char, len);
552
610
 
553
611
  MEMCPY(buffer, source_file, char, len);
554
612
  result->source_file = buffer;
555
613
  }
556
- else
557
- {
614
+ else
615
+ {
558
616
  result->source_file = source_file;
559
- }
617
+ }
560
618
  result->line = line;
561
619
 
562
620
  return result;
@@ -574,7 +632,7 @@ prof_method_free(prof_method_t *method)
574
632
  {
575
633
  if (method->source_file)
576
634
  {
577
- xfree((char*)method->source_file);
635
+ xfree((char*)method->source_file);
578
636
  }
579
637
 
580
638
  prof_call_infos_free(method->call_infos);
@@ -611,7 +669,7 @@ prof_method_line(VALUE self)
611
669
  /* call-seq:
612
670
  source_file => string
613
671
 
614
- return the source file of the method
672
+ return the source file of the method
615
673
  */
616
674
  static VALUE prof_method_source_file(VALUE self)
617
675
  {
@@ -669,10 +727,10 @@ Returns the name of this method in the format Object#method. Singletons
669
727
  methods will be returned in the format <Object::Object>#method.*/
670
728
 
671
729
  static VALUE
672
- prof_method_name(VALUE self, int depth)
730
+ prof_method_name(VALUE self)
673
731
  {
674
732
  prof_method_t *method = get_prof_method(self);
675
- return method_name(method->key->mid, depth);
733
+ return method_name(method->key->mid);
676
734
  }
677
735
 
678
736
  /* call-seq:
@@ -684,13 +742,13 @@ static VALUE
684
742
  prof_full_name(VALUE self)
685
743
  {
686
744
  prof_method_t *method = get_prof_method(self);
687
- return full_name(method->key->klass, method->key->mid, method->key->depth);
745
+ return full_name(method->key->klass, method->key->mid);
688
746
  }
689
747
 
690
748
  /* call-seq:
691
749
  call_infos -> Array of call_info
692
750
 
693
- Returns an array of call info objects that contain profiling information
751
+ Returns an array of call info objects that contain profiling information
694
752
  about the current method.*/
695
753
  static VALUE
696
754
  prof_method_call_infos(VALUE self)
@@ -702,7 +760,7 @@ prof_method_call_infos(VALUE self)
702
760
  static int
703
761
  collect_methods(st_data_t key, st_data_t value, st_data_t result)
704
762
  {
705
- /* Called for each method stored in a thread's method table.
763
+ /* Called for each method stored in a thread's method table.
706
764
  We want to store the method info information into an array.*/
707
765
  VALUE methods = (VALUE) result;
708
766
  prof_method_t *method = (prof_method_t *) value;
@@ -735,7 +793,7 @@ method_table_lookup(st_table *table, const prof_method_key_t* key)
735
793
  {
736
794
  return (prof_method_t *) val;
737
795
  }
738
- else
796
+ else
739
797
  {
740
798
  return NULL;
741
799
  }
@@ -829,7 +887,7 @@ threads_table_free(st_table *table)
829
887
  static int
830
888
  collect_threads(st_data_t key, st_data_t value, st_data_t result)
831
889
  {
832
- /* Although threads are keyed on an id, that is actually a
890
+ /* Although threads are keyed on an id, that is actually a
833
891
  pointer to the VALUE object of the thread. So its bogus.
834
892
  However, in thread_data is the real thread id stored
835
893
  as an int. */
@@ -841,7 +899,7 @@ collect_threads(st_data_t key, st_data_t value, st_data_t result)
841
899
  /* Now collect an array of all the called methods */
842
900
  st_table* method_table = thread_data->method_table;
843
901
  st_foreach(method_table, collect_methods, methods);
844
-
902
+
845
903
  /* Store the results in the threads hash keyed on the thread id. */
846
904
  rb_hash_aset(threads_hash, thread_data->thread_id, methods);
847
905
 
@@ -850,9 +908,16 @@ collect_threads(st_data_t key, st_data_t value, st_data_t result)
850
908
 
851
909
 
852
910
  /* ================ Profiling =================*/
853
- /* Copied from eval.c */
854
- #ifdef DEBUG
855
- static char *
911
+
912
+ /* support tracing ruby events from ruby-prof. useful for getting at
913
+ what actually happens inside the ruby interpreter (and ruby-prof).
914
+ set environment variable RUBY_PROF_TRACE to filename you want to
915
+ find the trace in.
916
+ */
917
+ static FILE* trace_file = NULL;
918
+
919
+ /* Copied from eval.c (1.8.x) / thread.c (1.9.2) */
920
+ static const char *
856
921
  get_event_name(rb_event_flag_t event)
857
922
  {
858
923
  switch (event) {
@@ -872,43 +937,43 @@ get_event_name(rb_event_flag_t event)
872
937
  return "c-return";
873
938
  case RUBY_EVENT_RAISE:
874
939
  return "raise";
875
-
940
+
876
941
  #ifdef RUBY_VM
877
942
  case RUBY_EVENT_SWITCH:
878
943
  return "thread-interrupt";
879
944
  #endif
880
-
945
+
881
946
  default:
882
947
  return "unknown";
883
948
  }
884
949
  }
885
- #endif
886
950
 
887
- static prof_method_t*
951
+
952
+ static prof_method_t*
888
953
  #ifdef RUBY_VM
889
- get_method(rb_event_flag_t event, VALUE klass, ID mid, int depth, st_table* method_table)
954
+ get_method(rb_event_flag_t event, VALUE klass, ID mid, st_table* method_table)
890
955
  # else
891
- get_method(rb_event_flag_t event, NODE *node, VALUE klass, ID mid, int depth, st_table* method_table)
892
- #endif
956
+ get_method(rb_event_flag_t event, NODE *node, VALUE klass, ID mid, st_table* method_table)
957
+ #endif
893
958
  {
894
959
  prof_method_key_t key;
895
960
  prof_method_t *method = NULL;
896
-
897
- method_key(&key, klass, mid, depth);
961
+
962
+ method_key(&key, klass, mid);
898
963
  method = method_table_lookup(method_table, &key);
899
964
 
900
965
  if (!method)
901
966
  {
902
967
  const char* source_file = rb_sourcefile();
903
968
  int line = rb_sourceline();
904
-
969
+
905
970
  /* Line numbers are not accurate for c method calls */
906
971
  if (event == RUBY_EVENT_C_CALL)
907
972
  {
908
973
  line = 0;
909
974
  source_file = NULL;
910
975
  }
911
-
976
+
912
977
  method = prof_method_create(&key, source_file, line);
913
978
  method_table_insert(method_table, method->key, method);
914
979
  }
@@ -917,18 +982,18 @@ static prof_method_t*
917
982
 
918
983
  static void
919
984
  update_result(prof_measure_t total_time,
920
- prof_frame_t *parent_frame,
985
+ prof_frame_t *parent_frame,
921
986
  prof_frame_t *frame)
922
987
  {
923
988
  prof_measure_t self_time = total_time - frame->child_time - frame->wait_time;
924
989
  prof_call_info_t *call_info = frame->call_info;
925
-
990
+
926
991
  /* Update information about the current method */
927
992
  call_info->called++;
928
993
  call_info->total_time += total_time;
929
994
  call_info->self_time += self_time;
930
995
  call_info->wait_time += frame->wait_time;
931
-
996
+
932
997
  /* Note where the current method was called from */
933
998
  if (parent_frame)
934
999
  call_info->line = parent_frame->line;
@@ -937,31 +1002,31 @@ update_result(prof_measure_t total_time,
937
1002
  static thread_data_t *
938
1003
  switch_thread(VALUE thread_id, prof_measure_t now)
939
1004
  {
940
- prof_frame_t *frame = NULL;
941
- prof_measure_t wait_time = 0;
1005
+ prof_frame_t *frame = NULL;
1006
+ prof_measure_t wait_time = 0;
942
1007
  /* Get new thread information. */
943
1008
  thread_data_t *thread_data = threads_table_lookup(threads_tbl, thread_id);
944
1009
 
945
1010
  /* How long has this thread been waiting? */
946
1011
  wait_time = now - thread_data->last_switch;
947
-
1012
+
948
1013
  thread_data->last_switch = now; // XXXX a test that fails if this is 0
949
1014
 
950
1015
  /* Get the frame at the top of the stack. This may represent
951
1016
  the current method (EVENT_LINE, EVENT_RETURN) or the
952
1017
  previous method (EVENT_CALL).*/
953
1018
  frame = stack_peek(thread_data->stack);
954
-
1019
+
955
1020
  if (frame) {
956
1021
  frame->wait_time += wait_time;
957
1022
  }
958
-
1023
+
959
1024
  /* Save on the last thread the time of the context switch
960
1025
  and reset this thread's last context switch to 0.*/
961
1026
  if (last_thread_data) {
962
- last_thread_data->last_switch = now;
1027
+ last_thread_data->last_switch = now;
963
1028
  }
964
-
1029
+
965
1030
  last_thread_data = thread_data;
966
1031
  return thread_data;
967
1032
  }
@@ -983,20 +1048,17 @@ pop_frame(thread_data_t *thread_data, prof_measure_t now)
983
1048
  /* Calculate the total time this method took */
984
1049
  total_time = now - frame->start_time;
985
1050
 
986
- /* Now deactivate the method */
987
- frame->call_info->target->active = 0;
988
-
989
1051
  parent_frame = stack_peek(thread_data->stack);
990
1052
  if (parent_frame)
991
1053
  {
992
- parent_frame->child_time += total_time;
1054
+ parent_frame->child_time += total_time;
993
1055
  }
994
-
1056
+
995
1057
  update_result(total_time, parent_frame, frame); // only time it's called
996
1058
  return frame;
997
1059
  }
998
1060
 
999
- static int
1061
+ static int
1000
1062
  pop_frames(st_data_t key, st_data_t value, st_data_t now_arg)
1001
1063
  {
1002
1064
  VALUE thread_id = (VALUE)key;
@@ -1011,11 +1073,11 @@ pop_frames(st_data_t key, st_data_t value, st_data_t now_arg)
1011
1073
  while (pop_frame(thread_data, now))
1012
1074
  {
1013
1075
  }
1014
-
1076
+
1015
1077
  return ST_CONTINUE;
1016
1078
  }
1017
1079
 
1018
- static void
1080
+ static void
1019
1081
  prof_pop_threads()
1020
1082
  {
1021
1083
  /* Get current measurement */
@@ -1061,10 +1123,7 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1061
1123
  /* Get current timestamp */
1062
1124
  now = get_measurement();
1063
1125
 
1064
- #ifdef DEBUG
1065
- /* This code is here for debug purposes - uncomment it out
1066
- when debugging to see a print out of exactly what the
1067
- profiler is tracing. */
1126
+ if (trace_file != NULL)
1068
1127
  {
1069
1128
  static VALUE last_thread_id = Qnil;
1070
1129
 
@@ -1075,7 +1134,7 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1075
1134
  const char* source_file = rb_sourcefile();
1076
1135
  unsigned int source_line = rb_sourceline();
1077
1136
 
1078
- char* event_name = get_event_name(event);
1137
+ const char* event_name = get_event_name(event);
1079
1138
 
1080
1139
  if (klass != 0)
1081
1140
  klass = (BUILTIN_TYPE(klass) == T_ICLASS ? RBASIC(klass)->klass : klass);
@@ -1083,17 +1142,16 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1083
1142
  class_name = rb_class2name(klass);
1084
1143
 
1085
1144
  if (last_thread_id != thread_id) {
1086
- printf("\n");
1145
+ fprintf(trace_file, "\n");
1087
1146
  }
1088
-
1089
- printf("%2u:%2ums %-8s %s:%2d %s#%s\n",
1147
+
1148
+ fprintf(trace_file, "%2u:%2ums %-8s %s:%2d %s#%s\n",
1090
1149
  (unsigned int) thread_id, (unsigned int) now, event_name, source_file, source_line, class_name, method_name);
1091
- fflush(stdout);
1092
- last_thread_id = thread_id;
1150
+ /* fflush(trace_file); */
1151
+ last_thread_id = thread_id;
1093
1152
  }
1094
- #endif
1095
-
1096
- /* Special case - skip any methods from the mProf
1153
+
1154
+ /* Special case - skip any methods from the mProf
1097
1155
  module, such as Prof.stop, since they clutter
1098
1156
  the results but aren't important to them results. */
1099
1157
  if (self == mProf) return;
@@ -1101,7 +1159,7 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1101
1159
  /* Get the current thread information. */
1102
1160
  thread = rb_thread_current();
1103
1161
  thread_id = rb_obj_id(thread);
1104
-
1162
+
1105
1163
  # if RUBY_VERSION == 191
1106
1164
  /* ensure that new threads are hooked [sigh] (bug in core) */
1107
1165
  prof_remove_hook();
@@ -1109,43 +1167,43 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1109
1167
  # endif
1110
1168
 
1111
1169
  if (exclude_threads_tbl &&
1112
- st_lookup(exclude_threads_tbl, (st_data_t) thread_id, 0))
1170
+ st_lookup(exclude_threads_tbl, (st_data_t) thread_id, 0))
1113
1171
  {
1114
1172
  return;
1115
- }
1116
-
1117
-
1173
+ }
1174
+
1175
+
1118
1176
  /* Was there a context switch? */
1119
1177
  if (!last_thread_data || last_thread_data->thread_id != thread_id)
1120
1178
  thread_data = switch_thread(thread_id, now);
1121
1179
  else
1122
1180
  thread_data = last_thread_data;
1123
-
1124
-
1181
+
1182
+
1125
1183
  switch (event) {
1126
1184
  case RUBY_EVENT_LINE:
1127
1185
  {
1128
1186
  /* Keep track of the current line number in this method. When
1129
- a new method is called, we know what line number it was
1187
+ a new method is called, we know what line number it was
1130
1188
  called from. */
1131
-
1189
+
1132
1190
  /* Get the current frame for the current thread. */
1133
1191
  frame = stack_peek(thread_data->stack);
1134
1192
 
1135
1193
  if (frame)
1136
1194
  {
1137
- frame->line = rb_sourceline();
1138
-
1195
+ frame->line = rb_sourceline();
1196
+
1139
1197
  # if RUBY_VERSION == 191
1140
1198
  // disabled it causes
1141
1199
  // us to lose valuable frame information...maybe mid comes in wrong sometimes?
1142
1200
  // walk_up_until_right_frame(frame, thread_data, mid, klass, now);
1143
1201
  # endif
1144
-
1202
+
1145
1203
  break;
1146
1204
  }
1147
1205
 
1148
- /* If we get here there was no frame, which means this is
1206
+ /* If we get here there was no frame, which means this is
1149
1207
  the first method seen for this thread, so fall through
1150
1208
  to below to create it. */
1151
1209
  }
@@ -1161,27 +1219,15 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1161
1219
  /* Is this an include for a module? If so get the actual
1162
1220
  module class since we want to combine all profiling
1163
1221
  results for that module. */
1164
-
1222
+
1165
1223
  if (klass != 0)
1166
1224
  klass = (BUILTIN_TYPE(klass) == T_ICLASS ? RBASIC(klass)->klass : klass);
1167
-
1168
- /* Assume this is the first time we have called this method. */
1225
+
1169
1226
  #ifdef RUBY_VM
1170
- method = get_method(event, klass, mid, 0, thread_data->method_table);
1227
+ method = get_method(event, klass, mid, thread_data->method_table);
1171
1228
  #else
1172
- method = get_method(event, node, klass, mid, 0, thread_data->method_table);
1229
+ method = get_method(event, node, klass, mid, thread_data->method_table);
1173
1230
  #endif
1174
- /* Check for a recursive call */
1175
- while (method->active) // it's while because we start at 0 and then inc. to the right recursive depth
1176
- {
1177
- /* Yes, this method is already active somewhere up the stack */
1178
- #ifdef RUBY_VM
1179
- method = get_method(event, klass, mid, method->key->depth + 1, thread_data->method_table);
1180
- #else
1181
- method = get_method(event, node, klass, mid, method->key->depth + 1, thread_data->method_table);
1182
- #endif
1183
- }
1184
- method->active = 1;
1185
1231
 
1186
1232
  if (!frame)
1187
1233
  {
@@ -1211,9 +1257,9 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1211
1257
  }
1212
1258
  case RUBY_EVENT_RETURN:
1213
1259
  case RUBY_EVENT_C_RETURN:
1214
- {
1215
- frame = pop_frame(thread_data, now);
1216
-
1260
+ {
1261
+ frame = pop_frame(thread_data, now);
1262
+
1217
1263
  # if RUBY_VERSION == 191
1218
1264
  // we need to walk up the stack to find the right one [http://redmine.ruby-lang.org/issues/show/2610] (for now)
1219
1265
  // sometimes frames don't have line and source somehow [like blank]
@@ -1221,7 +1267,7 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
1221
1267
  // or maybe we don't have one because we're at the top or something.
1222
1268
  walk_up_until_right_frame(frame, thread_data, mid, klass, now);
1223
1269
  # endif
1224
-
1270
+
1225
1271
  break;
1226
1272
  }
1227
1273
  }
@@ -1240,7 +1286,7 @@ static inline void walk_up_until_right_frame(prof_frame_t *frame, thread_data_t*
1240
1286
  /* ======== ProfResult ============== */
1241
1287
 
1242
1288
  /* Document-class: RubyProf::Result
1243
- The RubyProf::Result class is used to store the results of a
1289
+ The RubyProf::Result class is used to store the results of a
1244
1290
  profiling run. And instace of the class is returned from
1245
1291
  the methods RubyProf#stop and RubyProf#profile.
1246
1292
 
@@ -1296,7 +1342,7 @@ get_prof_result(VALUE obj)
1296
1342
  Returns a hash table keyed on thread ID. For each thread id,
1297
1343
  the hash table stores another hash table that contains profiling
1298
1344
  information for each method called during the threads execution.
1299
- That hash table is keyed on method name and contains
1345
+ That hash table is keyed on method name and contains
1300
1346
  RubyProf::MethodInfo objects. */
1301
1347
  static VALUE
1302
1348
  prof_result_threads(VALUE self)
@@ -1309,12 +1355,12 @@ prof_result_threads(VALUE self)
1309
1355
 
1310
1356
  /* call-seq:
1311
1357
  measure_mode -> measure_mode
1312
-
1358
+
1313
1359
  Returns what ruby-prof is measuring. Valid values include:
1314
-
1360
+
1315
1361
  *RubyProf::PROCESS_TIME - Measure process time. This is default. It is implemented using the clock functions in the C Runtime library.
1316
1362
  *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows
1317
- *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
1363
+ *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
1318
1364
  *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
1319
1365
  *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
1320
1366
  *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
@@ -1327,12 +1373,12 @@ prof_get_measure_mode(VALUE self)
1327
1373
 
1328
1374
  /* call-seq:
1329
1375
  measure_mode=value -> void
1330
-
1376
+
1331
1377
  Specifies what ruby-prof should measure. Valid values include:
1332
-
1378
+
1333
1379
  *RubyProf::PROCESS_TIME - Measure process time. This is default. It is implemented using the clock functions in the C Runtime library.
1334
1380
  *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows
1335
- *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
1381
+ *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
1336
1382
  *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
1337
1383
  *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
1338
1384
  *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
@@ -1340,7 +1386,7 @@ prof_get_measure_mode(VALUE self)
1340
1386
  static VALUE
1341
1387
  prof_set_measure_mode(VALUE self, VALUE val)
1342
1388
  {
1343
- long mode = NUM2LONG(val);
1389
+ int mode = NUM2INT(val);
1344
1390
 
1345
1391
  if (threads_tbl)
1346
1392
  {
@@ -1352,12 +1398,12 @@ prof_set_measure_mode(VALUE self, VALUE val)
1352
1398
  get_measurement = measure_process_time;
1353
1399
  convert_measurement = convert_process_time;
1354
1400
  break;
1355
-
1401
+
1356
1402
  case MEASURE_WALL_TIME:
1357
1403
  get_measurement = measure_wall_time;
1358
1404
  convert_measurement = convert_wall_time;
1359
1405
  break;
1360
-
1406
+
1361
1407
  #if defined(MEASURE_CPU_TIME)
1362
1408
  case MEASURE_CPU_TIME:
1363
1409
  if (cpu_frequency == 0)
@@ -1366,14 +1412,14 @@ prof_set_measure_mode(VALUE self, VALUE val)
1366
1412
  convert_measurement = convert_cpu_time;
1367
1413
  break;
1368
1414
  #endif
1369
-
1415
+
1370
1416
  #if defined(MEASURE_ALLOCATIONS)
1371
1417
  case MEASURE_ALLOCATIONS:
1372
1418
  get_measurement = measure_allocations;
1373
1419
  convert_measurement = convert_allocations;
1374
1420
  break;
1375
1421
  #endif
1376
-
1422
+
1377
1423
  #if defined(MEASURE_MEMORY)
1378
1424
  case MEASURE_MEMORY:
1379
1425
  get_measurement = measure_memory;
@@ -1396,10 +1442,10 @@ prof_set_measure_mode(VALUE self, VALUE val)
1396
1442
  #endif
1397
1443
 
1398
1444
  default:
1399
- rb_raise(rb_eArgError, "invalid mode: %ld", mode);
1445
+ rb_raise(rb_eArgError, "invalid mode: %d", mode);
1400
1446
  break;
1401
1447
  }
1402
-
1448
+
1403
1449
  measure_mode = mode;
1404
1450
  return val;
1405
1451
  }
@@ -1431,12 +1477,12 @@ prof_set_exclude_threads(VALUE self, VALUE threads)
1431
1477
  Check_Type(threads, T_ARRAY);
1432
1478
  exclude_threads_tbl = st_init_numtable();
1433
1479
 
1434
- for (i=0; i < RARRAY_LEN(threads); ++i)
1480
+ for (i=0; i < RARRAY_LEN(threads); ++i)
1435
1481
  {
1436
1482
  VALUE thread = rb_ary_entry(threads, i);
1437
1483
  st_insert(exclude_threads_tbl, (st_data_t) rb_obj_id(thread), 0);
1438
1484
  }
1439
- }
1485
+ }
1440
1486
  return threads;
1441
1487
  }
1442
1488
 
@@ -1448,12 +1494,12 @@ prof_install_hook()
1448
1494
  #ifdef RUBY_VM
1449
1495
  rb_add_event_hook(prof_event_hook,
1450
1496
  RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
1451
- RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1497
+ RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1452
1498
  | RUBY_EVENT_LINE, Qnil); // RUBY_EVENT_SWITCH
1453
1499
  #else
1454
1500
  rb_add_event_hook(prof_event_hook,
1455
1501
  RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
1456
- RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1502
+ RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1457
1503
  | RUBY_EVENT_LINE);
1458
1504
  #endif
1459
1505
 
@@ -1477,7 +1523,7 @@ prof_remove_hook()
1477
1523
 
1478
1524
  /* call-seq:
1479
1525
  running? -> boolean
1480
-
1526
+
1481
1527
  Returns whether a profile is currently running.*/
1482
1528
  static VALUE
1483
1529
  prof_running(VALUE self)
@@ -1490,7 +1536,7 @@ prof_running(VALUE self)
1490
1536
 
1491
1537
  /* call-seq:
1492
1538
  start -> RubyProf
1493
-
1539
+
1494
1540
  Starts recording profile data.*/
1495
1541
  static VALUE
1496
1542
  prof_start(VALUE self)
@@ -1504,9 +1550,21 @@ prof_start(VALUE self)
1504
1550
  last_thread_data = NULL;
1505
1551
  threads_tbl = threads_table_create();
1506
1552
 
1507
- prof_install_hook();
1553
+ /* open trace file if environment wants it */
1554
+ char* trace_file_name = getenv("RUBY_PROF_TRACE");
1555
+ if (trace_file_name != NULL) {
1556
+ if (0==strcmp(trace_file_name, "stdout")) {
1557
+ trace_file = stdout;
1558
+ } else if (0==strcmp(trace_file_name, "stderr")) {
1559
+ trace_file = stderr;
1560
+ } else {
1561
+ trace_file = fopen(trace_file_name, "a");
1562
+ }
1563
+ }
1564
+
1565
+ prof_install_hook();
1508
1566
  return self;
1509
- }
1567
+ }
1510
1568
 
1511
1569
  /* call-seq:
1512
1570
  pause -> RubyProf
@@ -1526,20 +1584,20 @@ prof_pause(VALUE self)
1526
1584
 
1527
1585
  /* call-seq:
1528
1586
  resume {block} -> RubyProf
1529
-
1587
+
1530
1588
  Resumes recording profile data.*/
1531
1589
  static VALUE
1532
1590
  prof_resume(VALUE self)
1533
1591
  {
1534
1592
  if (threads_tbl == NULL)
1535
- {
1593
+ {
1536
1594
  prof_start(self);
1537
1595
  }
1538
1596
  else
1539
- {
1597
+ {
1540
1598
  prof_install_hook();
1541
1599
  }
1542
-
1600
+
1543
1601
  if (rb_block_given_p())
1544
1602
  {
1545
1603
  rb_ensure(rb_yield, self, prof_pause, self);
@@ -1556,7 +1614,14 @@ static VALUE
1556
1614
  prof_stop(VALUE self)
1557
1615
  {
1558
1616
  VALUE result = Qnil;
1559
-
1617
+
1618
+ /* close trace file if open */
1619
+ if (trace_file != NULL) {
1620
+ if (trace_file!=stderr && trace_file!=stdout)
1621
+ fclose(trace_file);
1622
+ trace_file = NULL;
1623
+ }
1624
+
1560
1625
  prof_remove_hook();
1561
1626
 
1562
1627
  prof_pop_threads();
@@ -1564,12 +1629,15 @@ prof_stop(VALUE self)
1564
1629
  /* Create the result */
1565
1630
  result = prof_result_new();
1566
1631
 
1567
- /* Unset the last_thread_data (very important!)
1632
+ /* Unset the last_thread_data (very important!)
1568
1633
  and the threads table */
1569
1634
  last_thread_data = NULL;
1570
1635
  threads_table_free(threads_tbl);
1571
1636
  threads_tbl = NULL;
1572
1637
 
1638
+ /* compute minimality of call_infos */
1639
+ rb_funcall(result, rb_intern("compute_minimality") , 0);
1640
+
1573
1641
  return result;
1574
1642
  }
1575
1643
 
@@ -1581,7 +1649,7 @@ static VALUE
1581
1649
  prof_profile(VALUE self)
1582
1650
  {
1583
1651
  int result;
1584
-
1652
+
1585
1653
  if (!rb_block_given_p())
1586
1654
  {
1587
1655
  rb_raise(rb_eArgError, "A block must be provided to the profile method.");
@@ -1616,21 +1684,21 @@ Returns the cpu time.*/
1616
1684
  call-seq:
1617
1685
  cpu_frequency -> int
1618
1686
 
1619
- Returns the cpu's frequency. This value is needed when
1687
+ Returns the cpu's frequency. This value is needed when
1620
1688
  RubyProf::measure_mode is set to CPU_TIME. */
1621
1689
 
1622
1690
  /* Document-method: cpu_frequency
1623
1691
  call-seq:
1624
1692
  cpu_frequency -> int
1625
1693
 
1626
- Returns the cpu's frequency. This value is needed when
1694
+ Returns the cpu's frequency. This value is needed when
1627
1695
  RubyProf::measure_mode is set to CPU_TIME. */
1628
1696
 
1629
1697
  /* Document-method: cpu_frequency=
1630
1698
  call-seq:
1631
1699
  cpu_frequency = frequency
1632
1700
 
1633
- Sets the cpu's frequency. This value is needed when
1701
+ Sets the cpu's frequency. This value is needed when
1634
1702
  RubyProf::measure_mode is set to CPU_TIME. */
1635
1703
 
1636
1704
  /* Document-method: measure_allocations
@@ -1659,7 +1727,7 @@ Returns the time spent doing garbage collections in microseconds.*/
1659
1727
 
1660
1728
 
1661
1729
  #if defined(_WIN32)
1662
- __declspec(dllexport)
1730
+ __declspec(dllexport)
1663
1731
  #endif
1664
1732
  void
1665
1733
 
@@ -1673,7 +1741,7 @@ Init_ruby_prof()
1673
1741
  rb_define_module_function(mProf, "pause", prof_pause, 0);
1674
1742
  rb_define_module_function(mProf, "running?", prof_running, 0);
1675
1743
  rb_define_module_function(mProf, "profile", prof_profile, 0);
1676
-
1744
+
1677
1745
  rb_define_singleton_method(mProf, "exclude_threads=", prof_set_exclude_threads, 1);
1678
1746
  rb_define_singleton_method(mProf, "measure_mode", prof_get_measure_mode, 0);
1679
1747
  rb_define_singleton_method(mProf, "measure_mode=", prof_set_measure_mode, 1);
@@ -1692,14 +1760,14 @@ Init_ruby_prof()
1692
1760
  rb_define_singleton_method(mProf, "cpu_frequency", prof_get_cpu_frequency, 0); /* in measure_cpu_time.h */
1693
1761
  rb_define_singleton_method(mProf, "cpu_frequency=", prof_set_cpu_frequency, 1); /* in measure_cpu_time.h */
1694
1762
  #endif
1695
-
1763
+
1696
1764
  #ifndef MEASURE_ALLOCATIONS
1697
1765
  rb_define_const(mProf, "ALLOCATIONS", Qnil);
1698
1766
  #else
1699
1767
  rb_define_const(mProf, "ALLOCATIONS", INT2NUM(MEASURE_ALLOCATIONS));
1700
1768
  rb_define_singleton_method(mProf, "measure_allocations", prof_measure_allocations, 0); /* in measure_allocations.h */
1701
1769
  #endif
1702
-
1770
+
1703
1771
  #ifndef MEASURE_MEMORY
1704
1772
  rb_define_const(mProf, "MEMORY", Qnil);
1705
1773
  #else
@@ -1728,13 +1796,13 @@ Init_ruby_prof()
1728
1796
  /* MethodInfo */
1729
1797
  cMethodInfo = rb_define_class_under(mProf, "MethodInfo", rb_cObject);
1730
1798
  rb_undef_method(CLASS_OF(cMethodInfo), "new");
1731
-
1799
+
1732
1800
  rb_define_method(cMethodInfo, "klass", prof_method_klass, 0);
1733
1801
  rb_define_method(cMethodInfo, "klass_name", prof_klass_name, 0);
1734
1802
  rb_define_method(cMethodInfo, "method_name", prof_method_name, 0);
1735
1803
  rb_define_method(cMethodInfo, "full_name", prof_full_name, 0);
1736
1804
  rb_define_method(cMethodInfo, "method_id", prof_method_id, 0);
1737
-
1805
+
1738
1806
  rb_define_method(cMethodInfo, "source_file", prof_method_source_file,0);
1739
1807
  rb_define_method(cMethodInfo, "line", prof_method_line, 0);
1740
1808
 
@@ -1744,11 +1812,16 @@ Init_ruby_prof()
1744
1812
  cCallInfo = rb_define_class_under(mProf, "CallInfo", rb_cObject);
1745
1813
  rb_undef_method(CLASS_OF(cCallInfo), "new");
1746
1814
  rb_define_method(cCallInfo, "parent", prof_call_info_parent, 0);
1815
+ rb_define_method(cCallInfo, "parent=", prof_call_info_set_parent, 1);
1747
1816
  rb_define_method(cCallInfo, "children", prof_call_info_children, 0);
1748
1817
  rb_define_method(cCallInfo, "target", prof_call_info_target, 0);
1749
1818
  rb_define_method(cCallInfo, "called", prof_call_info_called, 0);
1819
+ rb_define_method(cCallInfo, "called=", prof_call_info_set_called, 1);
1750
1820
  rb_define_method(cCallInfo, "total_time", prof_call_info_total_time, 0);
1821
+ rb_define_method(cCallInfo, "add_total_time", prof_call_info_add_total_time, 1);
1751
1822
  rb_define_method(cCallInfo, "self_time", prof_call_info_self_time, 0);
1823
+ rb_define_method(cCallInfo, "add_self_time", prof_call_info_add_self_time, 1);
1752
1824
  rb_define_method(cCallInfo, "wait_time", prof_call_info_wait_time, 0);
1825
+ rb_define_method(cCallInfo, "add_wait_time", prof_call_info_add_wait_time, 1);
1753
1826
  rb_define_method(cCallInfo, "line", prof_call_info_line, 0);
1754
1827
  }