ruby-prof 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,44 @@
1
+ 0.6.0 (2007-02-03)
2
+ ========================
3
+
4
+ ruby-prof 0.6.0 adds support for Ruby 1.9 and memory profiling.
5
+
6
+ Features
7
+ --------
8
+ * Added support for ruby 1.9 (Shugo Maeda)
9
+ * Added support for outputting printer results to a String, Array or IO
10
+ object (Michael Granger)
11
+ * Add new memory profiling mode. Note this mode depends on a
12
+ patched Ruby interpreter (Alexander Dymo)
13
+
14
+ Fixes
15
+ -------
16
+ * Improvements to GraphHtmlPrinter including updated documentation,
17
+ fixes for min_time support, ability to specify templates using
18
+ strings or filenames, and table layout fixes (Makoto Kuwata)
19
+ * Fixes to scaling factor for calltrees so that precision is not lost
20
+ due to the conversion to doubles (Sylvain Joyeux)
21
+ * Changed constant ALLOCATED_OBJECTS to ALLOCATIONS in the C code to
22
+ match the Ruby code (Sylvain Joyeux)
23
+ * Added support for calltree printer to ruby-prof binary script (Sylvain Joyeux)
24
+ * Fix support for the allocator measure mode to extconf.rb (Sylvain Joyeux)
25
+ * Honor measure mode when specified on the command line (Sylvain Joyeux)
26
+ * Sorting of methods by total time was incorrect (Dan Fitch, Charlie Savage)
27
+ * Fix ruby-prof to work with the latest version of GEMS (Alexander Dymo)
28
+ * Always define MEASURE_CPU_TIME and MEASURE_ALLOCATIONS in Ruby code, but
29
+ set their values to nil if the functionality is not available.
30
+
31
+
32
+ 0.5.2 (2007-07-19)
33
+ ========================
34
+
35
+ ruby-prof 0.5.2 is a bug fix release.
36
+
37
+ Fixes
38
+ -------
39
+ * Include missing rails plugin
40
+
41
+
1
42
  0.5.1 (2007-07-18)
2
43
  ========================
3
44
 
data/README CHANGED
@@ -5,13 +5,14 @@
5
5
  ruby-prof is a fast code profiler for Ruby. Its features include:
6
6
 
7
7
  * Speed - it is a C extension and therefore many times faster than the standard Ruby profiler.
8
- * Flat Profiles - similar to the reports generated by the standard Ruby profiler
9
- * Graph profiles - similar to GProf, these show how long a method runs, which methods call it and which methods it calls.
10
- * Call tree profiles - outputs results in the calltree format suitable for the KCacheGrind profiling tool.
8
+ * Modes - Ruby prof can measure a number of different parameters, including
9
+ call times, memory usage and object allocations.
10
+ * Reports - can generate text and cross-referenced html reports
11
+ - Flat Profiles - similar to the reports generated by the standard Ruby profiler
12
+ - Graph profiles - similar to GProf, these show how long a method runs, which methods call it and which methods it calls.
13
+ - Call tree profiles - outputs results in the calltree format suitable for the KCacheGrind profiling tool.
11
14
  * Threads - supports profiling multiple threads simultaneously
12
15
  * Recursive calls - supports profiling recursive method calls
13
- * Reports - can generate both text and cross-referenced html reports
14
- * Output - can output to standard out or to a file
15
16
 
16
17
 
17
18
  == Requirements
@@ -27,13 +28,15 @@ includes an already built extension.
27
28
 
28
29
  == Install
29
30
 
30
- ruby-prof is provided as a RubyGem. To install:
31
+ The easiest way to install ruby-prof is by using Ruby Gems. To install:
31
32
 
32
33
  <tt>gem install ruby-prof</tt>
33
34
 
34
35
  If you are running Windows, make sure to install the Win32 RubyGem which
35
36
  includes a pre-built binary.
36
37
 
38
+ ruby-prof is also available as a tarred gzip archive and zip archive.
39
+
37
40
  == Usage
38
41
 
39
42
  There are three ways of running ruby-prof.
@@ -59,7 +62,7 @@ particular segments of code.
59
62
  result = RubyProf.stop
60
63
 
61
64
  # Print a flat profile to text
62
- printer = RubyProf::TextPrinter.new(result)
65
+ printer = RubyProf::FlatPrinter.new(result)
63
66
  printer.print(STDOUT, 0)
64
67
 
65
68
  Alternatively, you can use a block to tell ruby-prof what
@@ -161,6 +164,7 @@ aspects of a Ruby program. Supported measurements include:
161
164
  * wall time
162
165
  * cpu time
163
166
  * object allocations
167
+ * memory usage
164
168
 
165
169
  Process time measures the time used by a process between any two moments.
166
170
  It is unaffected by other processes concurrently running
@@ -176,18 +180,24 @@ CPU time uses the CPU clock counter to measure time. The returned
176
180
  values are dependent on the correctly setting the CPU's frequency.
177
181
  This mode is only supported on Pentium or PowerPC platforms.
178
182
 
179
- Object allocations report which methods allocate objects in a running
180
- program. This support was generously donated by Sylvain Joyeux.
181
- This mode requires a patched Ruby interpreter. For more
182
- information, see:
183
+ Object allocation reports show how many objects each method in
184
+ a program allocates. This support was added by Sylvain Joyeux
185
+ and requires a patched Ruby interpreter. For more information, see:
183
186
  http://rubyforge.org/tracker/index.php?func=detail&aid=11497&group_id=426&atid=1700
184
187
 
188
+ Memory usage reports show how much memory each method in a program
189
+ uses. This support was added by Alexander Dymo and requires a
190
+ patched Ruby interpreter. For more information, see:
191
+ http://rubyforge.org/tracker/index.php?func=detail&aid=17676&group_id=1814&atid=7062.
192
+
193
+
185
194
  To set the measurement:
186
195
 
187
196
  * RubyProf.measure_mode = RubyProf::PROCESS_TIME
188
197
  * RubyProf.measure_mode = RubyProf::WALL_TIME
189
198
  * RubyProf.measure_mode = RubyProf::CPU_TIME
190
199
  * RubyProf.measure_mode = RubyProf::ALLOCATIONS
200
+ * RubyProf.measure_mode = RubyProf::MEMORY
191
201
 
192
202
  The default value is RubyProf::PROCESS_TIME.
193
203
 
data/Rakefile CHANGED
@@ -1,11 +1,13 @@
1
1
  require 'rubygems'
2
+ require 'date'
2
3
  require 'rake/gempackagetask'
3
4
  require 'rake/rdoctask'
5
+ require 'date'
4
6
 
5
7
  SO_NAME = "ruby_prof.so"
6
8
 
7
9
  # ------- Default Package ----------
8
- RUBY_PROF_VERSION = "0.5.2"
10
+ RUBY_PROF_VERSION = "0.6.0"
9
11
 
10
12
  FILES = FileList[
11
13
  'Rakefile',
@@ -45,7 +47,6 @@ EOF
45
47
  spec.bindir = "bin"
46
48
  spec.executables = ["ruby-prof"]
47
49
  spec.extensions = ["ext/extconf.rb"]
48
- spec.autorequire = "ruby-prof"
49
50
  spec.files = FILES.to_a
50
51
  spec.test_files = Dir["test/test_*.rb"]
51
52
 
@@ -71,7 +72,6 @@ EOF
71
72
 
72
73
  end
73
74
 
74
-
75
75
  # Rake task to build the default package
76
76
  Rake::GemPackageTask.new(default_spec) do |pkg|
77
77
  pkg.need_tar = true
@@ -80,14 +80,12 @@ end
80
80
 
81
81
 
82
82
  # ------- Windows Package ----------
83
-
84
83
  # Windows specification
85
84
  win_spec = default_spec.clone
86
85
  win_spec.extensions = []
87
- win_spec.platform = Gem::Platform::WIN32
86
+ win_spec.platform = Gem::Platform::CURRENT
88
87
  win_spec.files += ["lib/#{SO_NAME}"]
89
88
 
90
-
91
89
  desc "Create Windows Gem"
92
90
  task :create_win32_gem do
93
91
  # Copy the win32 extension built by MingW - easier to install
data/bin/ruby-prof CHANGED
@@ -26,6 +26,7 @@
26
26
  # allocations - Tracks object allocations
27
27
  # (requires a patched Ruby interpreter).
28
28
  # --replace-progname Replace $0 when loading the .rb files.
29
+ # --specialized-instruction Turn on specialized instruction.
29
30
  # -h, --help Show help message
30
31
  # --version Show version
31
32
  #
@@ -43,6 +44,7 @@ options.printer = RubyProf::FlatPrinter
43
44
  options.min_percent = 0
44
45
  options.file = nil
45
46
  options.replace_prog_name = false
47
+ options.specialized_instruction = false
46
48
 
47
49
  opts = OptionParser.new do |opts|
48
50
  opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
@@ -67,6 +69,8 @@ opts = OptionParser.new do |opts|
67
69
  options.printer = RubyProf::GraphPrinter
68
70
  when :graph_html
69
71
  options.printer = RubyProf::GraphHtmlPrinter
72
+ when :call_tree
73
+ options.printer = RubyProf::CallTreePrinter
70
74
  end
71
75
  end
72
76
 
@@ -90,7 +94,7 @@ opts = OptionParser.new do |opts|
90
94
  ' cpu - CPU time (Pentium and PowerPCs only).',
91
95
  ' allocations - Object allocations (requires patched Ruby interpreter).') do |measure_mode|
92
96
 
93
- case mode
97
+ case measure_mode
94
98
  when :process
95
99
  options.measure_mode = RubyProf::PROCESS_TIME
96
100
  when :wall
@@ -105,6 +109,12 @@ opts = OptionParser.new do |opts|
105
109
  opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
106
110
  options.replace_prog_name = true
107
111
  end
112
+
113
+ if defined?(VM)
114
+ opts.on("--specialized-instruction", "Turn on specified instruction.") do
115
+ options.specialized_instruction = true
116
+ end
117
+ end
108
118
 
109
119
  opts.on_tail("-h", "--help", "Show help message") do
110
120
  puts opts
@@ -161,6 +171,14 @@ at_exit {
161
171
  # Now set measure mode
162
172
  RubyProf.measure_mode = options.measure_mode
163
173
 
174
+ # Set VM compile option
175
+ if defined?(VM)
176
+ VM::InstructionSequence.compile_option = {
177
+ :trace_instruction => true,
178
+ :specialized_instruction => options.specialized_instruction
179
+ }
180
+ end
181
+
164
182
  # Get the script we will execute
165
183
  script = ARGV.shift
166
184
  if options.replace_prog_name
data/ext/extconf.rb CHANGED
@@ -16,4 +16,6 @@ else
16
16
  end
17
17
 
18
18
  have_header("sys/times.h")
19
+ have_func("rb_os_allocated_objects")
20
+ have_func("rb_gc_allocated_size")
19
21
  create_makefile("ruby_prof")
@@ -0,0 +1,13 @@
1
+ ***************
2
+ *** 16,20 ****
3
+ end
4
+
5
+ have_header("sys/times.h")
6
+ - create_makefile("ruby_prof")
7
+ - have_func("rb_os_allocated_objects")--- 16,21 ----
8
+ end
9
+
10
+ have_header("sys/times.h")
11
+ + have_func("rb_os_allocated_objects")
12
+ + have_func("rb_gc_allocated_size")
13
+ + create_makefile("ruby_prof")
@@ -0,0 +1,42 @@
1
+ /* :nodoc:
2
+ * Copyright (C) 2008 Alexander Dymo <adymo@pluron.com>
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ * SUCH DAMAGE. */
25
+
26
+
27
+ #if defined(HAVE_RB_GC_ALLOCATED_SIZE)
28
+ #define MEASURE_MEMORY 4
29
+
30
+ static prof_measure_t
31
+ measure_memory()
32
+ {
33
+ return rb_gc_allocated_size();
34
+ }
35
+
36
+ static double
37
+ convert_memory(prof_measure_t c)
38
+ {
39
+ return c / 1024;
40
+ }
41
+
42
+ #endif
data/ext/ruby_prof.c CHANGED
@@ -51,13 +51,18 @@
51
51
  #include <stdio.h>
52
52
 
53
53
  #include <ruby.h>
54
+ #ifndef RUBY_VM
54
55
  #include <node.h>
55
56
  #include <st.h>
57
+ typedef rb_event_t rb_event_flag_t;
58
+ #define rb_sourcefile() (node ? node->nd_file : 0)
59
+ #define rb_sourceline() (node ? nd_line(node) : 0)
60
+ #endif
56
61
 
57
62
 
58
63
  /* ================ Constants =================*/
59
64
  #define INITIAL_STACK_SIZE 8
60
- #define PROF_VERSION "0.5.2"
65
+ #define PROF_VERSION "0.6.0"
61
66
 
62
67
 
63
68
  /* ================ Measurement =================*/
@@ -71,6 +76,7 @@ typedef unsigned long prof_measure_t;
71
76
  #include "measure_wall_time.h"
72
77
  #include "measure_cpu_time.h"
73
78
  #include "measure_allocations.h"
79
+ #include "measure_memory.h"
74
80
 
75
81
  static prof_measure_t (*get_measurement)() = measure_process_time;
76
82
  static double (*convert_measurement)(prof_measure_t) = convert_process_time;
@@ -195,7 +201,11 @@ figure_singleton_name(VALUE klass)
195
201
  /* Make sure to get the super class so that we don't
196
202
  mistakenly grab a T_ICLASS which would lead to
197
203
  unknown method errors. */
204
+ #ifdef RCLASS_SUPER
205
+ VALUE super = rb_class_real(RCLASS_SUPER(klass));
206
+ #else
198
207
  VALUE super = rb_class_real(RCLASS(klass)->super);
208
+ #endif
199
209
  result = rb_str_new2("<Object::");
200
210
  rb_str_append(result, rb_inspect(super));
201
211
  rb_str_cat2(result, ">");
@@ -856,16 +866,14 @@ prof_method_cmp(VALUE self, VALUE other)
856
866
  prof_method_t *x = get_prof_method(self);
857
867
  prof_method_t *y = get_prof_method(other);
858
868
 
859
- if (x->called == 0)
869
+ if (x->called == 0 && y->called == 0)
870
+ return INT2FIX(0);
871
+ else if (x->called == 0)
860
872
  return INT2FIX(1);
861
873
  else if (y->called == 0)
862
874
  return INT2FIX(-1);
863
- else if (x->total_time < y->total_time)
864
- return INT2FIX(-1);
865
- else if (x->total_time == y->total_time)
866
- return INT2FIX(0);
867
875
  else
868
- return INT2FIX(1);
876
+ return rb_dbl_cmp(x->total_time, y->total_time);
869
877
  }
870
878
 
871
879
  static int
@@ -982,27 +990,27 @@ collect_threads(st_data_t key, st_data_t value, st_data_t result)
982
990
  /* ================ Profiling =================*/
983
991
  /* Copied from eval.c */
984
992
  static char *
985
- get_event_name(rb_event_t event)
993
+ get_event_name(rb_event_flag_t event)
986
994
  {
987
995
  switch (event) {
988
996
  case RUBY_EVENT_LINE:
989
- return "line";
997
+ return "line";
990
998
  case RUBY_EVENT_CLASS:
991
- return "class";
999
+ return "class";
992
1000
  case RUBY_EVENT_END:
993
- return "end";
1001
+ return "end";
994
1002
  case RUBY_EVENT_CALL:
995
- return "call";
1003
+ return "call";
996
1004
  case RUBY_EVENT_RETURN:
997
- return "return";
1005
+ return "return";
998
1006
  case RUBY_EVENT_C_CALL:
999
- return "c-call";
1007
+ return "c-call";
1000
1008
  case RUBY_EVENT_C_RETURN:
1001
- return "c-return";
1009
+ return "c-return";
1002
1010
  case RUBY_EVENT_RAISE:
1003
- return "raise";
1011
+ return "raise";
1004
1012
  default:
1005
- return "unknown";
1013
+ return "unknown";
1006
1014
  }
1007
1015
  }
1008
1016
 
@@ -1070,8 +1078,13 @@ update_result(thread_data_t* thread_data,
1070
1078
  }
1071
1079
 
1072
1080
 
1081
+ #ifdef RUBY_VM
1073
1082
  static void
1074
- prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1083
+ prof_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE klass)
1084
+ #else
1085
+ static void
1086
+ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1087
+ #endif
1075
1088
  {
1076
1089
 
1077
1090
  VALUE thread;
@@ -1079,8 +1092,17 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1079
1092
  thread_data_t* thread_data = NULL;
1080
1093
  long thread_id = 0;
1081
1094
  prof_frame_t *frame = NULL;
1082
-
1083
- /*
1095
+ #ifdef RUBY_VM
1096
+
1097
+ if (event != RUBY_EVENT_C_CALL &&
1098
+ event != RUBY_EVENT_C_RETURN) {
1099
+ VALUE thread = rb_thread_current();
1100
+ rb_frame_method_id_and_class(&mid, &klass);
1101
+ }
1102
+ #endif
1103
+ /* This code is here for debug purposes - uncomment it out
1104
+ when debugging to see a print out of exactly what the
1105
+ profiler is tracing.
1084
1106
  {
1085
1107
  st_data_t key = 0;
1086
1108
  static unsigned long last_thread_id = 0;
@@ -1157,8 +1179,12 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1157
1179
  called from. */
1158
1180
  if (frame)
1159
1181
  {
1182
+ #ifdef RUBY_VM
1183
+ frame->line = rb_sourceline();
1184
+ #else
1160
1185
  if (node)
1161
1186
  frame->line = nd_line(node);
1187
+ #endif
1162
1188
  break;
1163
1189
  }
1164
1190
  /* If we get here there was no frame, which means this is
@@ -1185,8 +1211,8 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1185
1211
 
1186
1212
  if (!method)
1187
1213
  {
1188
- const char* source_file = (node ? node->nd_file : 0);
1189
- int line = (node ? nd_line(node) : 0);
1214
+ const char* source_file = rb_sourcefile();
1215
+ int line = rb_sourceline();
1190
1216
 
1191
1217
  /* Line numbers are not accurate for c method calls */
1192
1218
  if (event == RUBY_EVENT_C_CALL)
@@ -1210,8 +1236,8 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1210
1236
 
1211
1237
  if (!method)
1212
1238
  {
1213
- const char* source_file = (node ? node->nd_file : 0);
1214
- int line = (node ? nd_line(node) : 0);
1239
+ const char* source_file = rb_sourcefile();
1240
+ int line = rb_sourceline();
1215
1241
 
1216
1242
  /* Line numbers are not accurate for c method calls */
1217
1243
  if (event == RUBY_EVENT_C_CALL)
@@ -1232,7 +1258,7 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
1232
1258
  frame->start_time = now;
1233
1259
  frame->wait_time = 0;
1234
1260
  frame->child_time = 0;
1235
- frame->line = node ? nd_line(node) : 0;
1261
+ frame->line = rb_sourceline();
1236
1262
 
1237
1263
  break;
1238
1264
  }
@@ -1347,7 +1373,8 @@ prof_result_threads(VALUE self)
1347
1373
  *RubyProf::PROCESS_TIME - Measure process time. This is default. It is implemented using the clock functions in the C Runtime library.
1348
1374
  *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows
1349
1375
  *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
1350
- *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.*/
1376
+ *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
1377
+ *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.*/
1351
1378
  static VALUE
1352
1379
  prof_get_measure_mode(VALUE self)
1353
1380
  {
@@ -1362,7 +1389,8 @@ prof_get_measure_mode(VALUE self)
1362
1389
  *RubyProf::PROCESS_TIME - Measure process time. This is default. It is implemented using the clock functions in the C Runtime library.
1363
1390
  *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows
1364
1391
  *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
1365
- *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.*/
1392
+ *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
1393
+ *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.*/
1366
1394
  static VALUE
1367
1395
  prof_set_measure_mode(VALUE self, VALUE val)
1368
1396
  {
@@ -1400,6 +1428,13 @@ prof_set_measure_mode(VALUE self, VALUE val)
1400
1428
  break;
1401
1429
  #endif
1402
1430
 
1431
+ #if defined(MEASURE_MEMORY)
1432
+ case MEASURE_MEMORY:
1433
+ get_measurement = measure_memory;
1434
+ convert_measurement = convert_memory;
1435
+ break;
1436
+ #endif
1437
+
1403
1438
  default:
1404
1439
  rb_raise(rb_eArgError, "invalid mode: %d", mode);
1405
1440
  break;
@@ -1441,10 +1476,21 @@ prof_start(VALUE self)
1441
1476
  last_thread_data = NULL;
1442
1477
  threads_tbl = threads_table_create();
1443
1478
 
1479
+ #ifdef RUBY_VM
1480
+ rb_add_event_hook(prof_event_hook,
1481
+ RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
1482
+ RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1483
+ | RUBY_EVENT_LINE, Qnil);
1484
+ #else
1444
1485
  rb_add_event_hook(prof_event_hook,
1445
1486
  RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
1446
1487
  RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN
1447
1488
  | RUBY_EVENT_LINE);
1489
+ #endif
1490
+
1491
+ #if defined(MEASURE_MEMORY)
1492
+ rb_gc_enable_stats();
1493
+ #endif
1448
1494
 
1449
1495
  return Qnil;
1450
1496
  }
@@ -1457,6 +1503,10 @@ prof_start(VALUE self)
1457
1503
  static VALUE
1458
1504
  prof_stop(VALUE self)
1459
1505
  {
1506
+ #if defined(MEASURE_MEMORY)
1507
+ rb_gc_disable_stats();
1508
+ #endif
1509
+
1460
1510
  VALUE result = Qnil;
1461
1511
 
1462
1512
  if (threads_tbl == NULL)
@@ -1515,17 +1565,28 @@ Init_ruby_prof()
1515
1565
  rb_define_singleton_method(mProf, "measure_mode", prof_get_measure_mode, 0);
1516
1566
  rb_define_singleton_method(mProf, "measure_mode=", prof_set_measure_mode, 1);
1517
1567
 
1568
+ rb_define_const(mProf, "CLOCKS_PER_SEC", INT2NUM(CLOCKS_PER_SEC));
1518
1569
  rb_define_const(mProf, "PROCESS_TIME", INT2NUM(MEASURE_PROCESS_TIME));
1519
1570
  rb_define_const(mProf, "WALL_TIME", INT2NUM(MEASURE_WALL_TIME));
1520
1571
 
1521
- #if defined(MEASURE_CPU_TIME)
1572
+ #ifndef MEASURE_CPU_TIME
1573
+ rb_define_const(mProf, "CPU_TIME", Qnil);
1574
+ #else
1522
1575
  rb_define_const(mProf, "CPU_TIME", INT2NUM(MEASURE_CPU_TIME));
1523
1576
  rb_define_singleton_method(mProf, "cpu_frequency", prof_get_cpu_frequency, 0); /* in measure_cpu_time.h */
1524
1577
  rb_define_singleton_method(mProf, "cpu_frequency=", prof_set_cpu_frequency, 1); /* in measure_cpu_time.h */
1525
1578
  #endif
1526
1579
 
1527
- #if defined(MEASURE_ALLOCATIONS)
1528
- rb_define_const(mProf, "ALLOCATED_OBJECTS", INT2NUM(MEASURE_ALLOCATIONS));
1580
+ #ifndef MEASURE_ALLOCATIONS
1581
+ rb_define_const(mProf, "ALLOCATIONS", Qnil);
1582
+ #else
1583
+ rb_define_const(mProf, "ALLOCATIONS", INT2NUM(MEASURE_ALLOCATIONS));
1584
+ #endif
1585
+
1586
+ #ifndef MEASURE_MEMORY
1587
+ rb_define_const(mProf, "MEMORY", Qnil);
1588
+ #else
1589
+ rb_define_const(mProf, "MEMORY", INT2NUM(MEASURE_MEMORY));
1529
1590
  #endif
1530
1591
 
1531
1592
  cResult = rb_define_class_under(mProf, "Result", rb_cObject);