ruby-prof 0.5.2 → 0.6.0
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.
- 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);
|