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 +41 -0
- data/README +21 -11
- data/Rakefile +4 -6
- data/bin/ruby-prof +19 -1
- data/ext/extconf.rb +2 -0
- data/ext/extconf.rb.rej +13 -0
- data/ext/measure_memory.h +42 -0
- data/ext/ruby_prof.c +91 -30
- data/lib/ruby-prof.rb +2 -0
- data/lib/ruby-prof/call_tree_printer.rb +11 -4
- data/lib/ruby-prof/call_tree_printer.rb.rej +27 -0
- data/lib/ruby-prof/flat_printer.rb +5 -4
- data/lib/ruby-prof/graph_html_printer.rb +25 -13
- data/test/basic_test.rb +21 -9
- data/test/measure_mode_test.rb +1 -1
- data/test/printers_test.rb +50 -6
- data/test/recursive_test.rb +3 -2
- data/test/test_helper.rb +10 -4
- data/test/thread_test.rb +3 -0
- metadata +51 -42
- data/test/gc.log +0 -599
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
|
-
*
|
9
|
-
|
10
|
-
*
|
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
|
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::
|
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
|
180
|
-
program. This support was
|
181
|
-
|
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.
|
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::
|
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
|
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
data/ext/extconf.rb.rej
ADDED
@@ -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.
|
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
|
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(
|
993
|
+
get_event_name(rb_event_flag_t event)
|
986
994
|
{
|
987
995
|
switch (event) {
|
988
996
|
case RUBY_EVENT_LINE:
|
989
|
-
|
997
|
+
return "line";
|
990
998
|
case RUBY_EVENT_CLASS:
|
991
|
-
|
999
|
+
return "class";
|
992
1000
|
case RUBY_EVENT_END:
|
993
|
-
|
1001
|
+
return "end";
|
994
1002
|
case RUBY_EVENT_CALL:
|
995
|
-
|
1003
|
+
return "call";
|
996
1004
|
case RUBY_EVENT_RETURN:
|
997
|
-
|
1005
|
+
return "return";
|
998
1006
|
case RUBY_EVENT_C_CALL:
|
999
|
-
|
1007
|
+
return "c-call";
|
1000
1008
|
case RUBY_EVENT_C_RETURN:
|
1001
|
-
|
1009
|
+
return "c-return";
|
1002
1010
|
case RUBY_EVENT_RAISE:
|
1003
|
-
|
1011
|
+
return "raise";
|
1004
1012
|
default:
|
1005
|
-
|
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(
|
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 = (
|
1189
|
-
int line = (
|
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 = (
|
1214
|
-
int line = (
|
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 =
|
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
|
-
#
|
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
|
-
#
|
1528
|
-
rb_define_const(mProf, "
|
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);
|