ruby-prof 0.18.0-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES +500 -0
- data/LICENSE +25 -0
- data/README.rdoc +487 -0
- data/Rakefile +113 -0
- data/bin/ruby-prof +345 -0
- data/bin/ruby-prof-check-trace +45 -0
- data/examples/flat.txt +50 -0
- data/examples/graph.dot +84 -0
- data/examples/graph.html +823 -0
- data/examples/graph.txt +139 -0
- data/examples/multi.flat.txt +23 -0
- data/examples/multi.graph.html +760 -0
- data/examples/multi.grind.dat +114 -0
- data/examples/multi.stack.html +547 -0
- data/examples/stack.html +547 -0
- data/ext/ruby_prof/extconf.rb +68 -0
- data/ext/ruby_prof/rp_call_info.c +425 -0
- data/ext/ruby_prof/rp_call_info.h +53 -0
- data/ext/ruby_prof/rp_measure.c +40 -0
- data/ext/ruby_prof/rp_measure.h +45 -0
- data/ext/ruby_prof/rp_measure_allocations.c +76 -0
- data/ext/ruby_prof/rp_measure_cpu_time.c +136 -0
- data/ext/ruby_prof/rp_measure_gc_runs.c +73 -0
- data/ext/ruby_prof/rp_measure_gc_time.c +60 -0
- data/ext/ruby_prof/rp_measure_memory.c +77 -0
- data/ext/ruby_prof/rp_measure_process_time.c +71 -0
- data/ext/ruby_prof/rp_measure_wall_time.c +45 -0
- data/ext/ruby_prof/rp_method.c +630 -0
- data/ext/ruby_prof/rp_method.h +75 -0
- data/ext/ruby_prof/rp_stack.c +173 -0
- data/ext/ruby_prof/rp_stack.h +63 -0
- data/ext/ruby_prof/rp_thread.c +277 -0
- data/ext/ruby_prof/rp_thread.h +27 -0
- data/ext/ruby_prof/ruby_prof.c +794 -0
- data/ext/ruby_prof/ruby_prof.h +60 -0
- data/ext/ruby_prof/vc/ruby_prof.sln +31 -0
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +141 -0
- data/lib/2.6.3/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +68 -0
- data/lib/ruby-prof/aggregate_call_info.rb +76 -0
- data/lib/ruby-prof/assets/call_stack_printer.css.html +117 -0
- data/lib/ruby-prof/assets/call_stack_printer.js.html +385 -0
- data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
- data/lib/ruby-prof/call_info.rb +115 -0
- data/lib/ruby-prof/call_info_visitor.rb +40 -0
- data/lib/ruby-prof/compatibility.rb +179 -0
- data/lib/ruby-prof/method_info.rb +121 -0
- data/lib/ruby-prof/printers/abstract_printer.rb +104 -0
- data/lib/ruby-prof/printers/call_info_printer.rb +41 -0
- data/lib/ruby-prof/printers/call_stack_printer.rb +265 -0
- data/lib/ruby-prof/printers/call_tree_printer.rb +143 -0
- data/lib/ruby-prof/printers/dot_printer.rb +132 -0
- data/lib/ruby-prof/printers/flat_printer.rb +70 -0
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -0
- data/lib/ruby-prof/printers/graph_html_printer.rb +249 -0
- data/lib/ruby-prof/printers/graph_printer.rb +116 -0
- data/lib/ruby-prof/printers/multi_printer.rb +84 -0
- data/lib/ruby-prof/profile.rb +26 -0
- data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -0
- data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -0
- data/lib/ruby-prof/rack.rb +174 -0
- data/lib/ruby-prof/task.rb +147 -0
- data/lib/ruby-prof/thread.rb +35 -0
- data/lib/ruby-prof/version.rb +3 -0
- data/lib/unprof.rb +10 -0
- data/ruby-prof.gemspec +58 -0
- data/test/abstract_printer_test.rb +53 -0
- data/test/aggregate_test.rb +136 -0
- data/test/basic_test.rb +128 -0
- data/test/block_test.rb +74 -0
- data/test/call_info_test.rb +78 -0
- data/test/call_info_visitor_test.rb +31 -0
- data/test/duplicate_names_test.rb +32 -0
- data/test/dynamic_method_test.rb +55 -0
- data/test/enumerable_test.rb +21 -0
- data/test/exceptions_test.rb +24 -0
- data/test/exclude_methods_test.rb +146 -0
- data/test/exclude_threads_test.rb +53 -0
- data/test/fiber_test.rb +79 -0
- data/test/issue137_test.rb +63 -0
- data/test/line_number_test.rb +80 -0
- data/test/measure_allocations_test.rb +26 -0
- data/test/measure_cpu_time_test.rb +212 -0
- data/test/measure_gc_runs_test.rb +32 -0
- data/test/measure_gc_time_test.rb +36 -0
- data/test/measure_memory_test.rb +33 -0
- data/test/measure_process_time_test.rb +61 -0
- data/test/measure_wall_time_test.rb +255 -0
- data/test/method_elimination_test.rb +84 -0
- data/test/module_test.rb +45 -0
- data/test/multi_printer_test.rb +104 -0
- data/test/no_method_class_test.rb +15 -0
- data/test/pause_resume_test.rb +166 -0
- data/test/prime.rb +54 -0
- data/test/printers_test.rb +275 -0
- data/test/printing_recursive_graph_test.rb +127 -0
- data/test/rack_test.rb +157 -0
- data/test/recursive_test.rb +215 -0
- data/test/singleton_test.rb +38 -0
- data/test/stack_printer_test.rb +77 -0
- data/test/stack_test.rb +138 -0
- data/test/start_stop_test.rb +112 -0
- data/test/test_helper.rb +267 -0
- data/test/thread_test.rb +187 -0
- data/test/unique_call_path_test.rb +202 -0
- data/test/yarv_test.rb +55 -0
- metadata +199 -0
data/Rakefile
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rubygems/package_task"
|
4
|
+
require "rake/extensiontask"
|
5
|
+
require "rake/testtask"
|
6
|
+
require "rdoc/task"
|
7
|
+
require "date"
|
8
|
+
require "rake/clean"
|
9
|
+
begin
|
10
|
+
require "bundler/setup"
|
11
|
+
Bundler::GemHelper.install_tasks
|
12
|
+
[:build, :install, :release].each {|t| Rake::Task[t].enhance [:rdoc] }
|
13
|
+
rescue LoadError
|
14
|
+
$stderr.puts "Install bundler to get support for simplified gem publishing"
|
15
|
+
end
|
16
|
+
|
17
|
+
# To release a version of ruby-prof:
|
18
|
+
# * Update lib/ruby-prof/version.rb
|
19
|
+
# * Update CHANGES
|
20
|
+
# * git commit to commit files
|
21
|
+
# * rake clobber to remove extra files
|
22
|
+
# * rake compile to build windows gems
|
23
|
+
# * rake package to create the gems
|
24
|
+
# * Tag the release (git tag 0.10.1)
|
25
|
+
# * Push to ruybgems.org (gem push pkg/<gem files>)
|
26
|
+
# For a ruby only release, just run
|
27
|
+
# * rake release
|
28
|
+
# it will push changes to github, tag the release, build the package and upload it to rubygems.org
|
29
|
+
# and in case you forgot to increment the version number or have uncommitted changes, it will refuse to work
|
30
|
+
|
31
|
+
GEM_NAME = 'ruby-prof'
|
32
|
+
SO_NAME = 'ruby_prof'
|
33
|
+
|
34
|
+
default_spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
35
|
+
|
36
|
+
# specify which versions/builds to cross compile
|
37
|
+
Rake::ExtensionTask.new do |ext|
|
38
|
+
ext.gem_spec = default_spec
|
39
|
+
ext.name = SO_NAME
|
40
|
+
ext.ext_dir = "ext/#{SO_NAME}"
|
41
|
+
ext.lib_dir = "lib/#{RUBY_VERSION}"
|
42
|
+
ext.cross_compile = true
|
43
|
+
ext.cross_platform = ['x86-mswin32-60', 'x86-mingw32-60']
|
44
|
+
end
|
45
|
+
|
46
|
+
# Rake task to build the default package
|
47
|
+
Gem::PackageTask.new(default_spec) do |pkg|
|
48
|
+
pkg.need_tar = true
|
49
|
+
end
|
50
|
+
|
51
|
+
# make sure rdoc has been built when packaging
|
52
|
+
# why do we ship rdoc as part of the gem?
|
53
|
+
Rake::Task[:package].enhance [:rdoc]
|
54
|
+
|
55
|
+
# Setup Windows Gem
|
56
|
+
if RUBY_PLATFORM.match(/win32|mingw32/)
|
57
|
+
# Windows specification
|
58
|
+
win_spec = default_spec.clone
|
59
|
+
win_spec.platform = Gem::Platform::CURRENT
|
60
|
+
win_spec.files += Dir.glob('lib/**/*.so')
|
61
|
+
win_spec.instance_variable_set(:@cache_file, nil) # Hack to work around gem issue
|
62
|
+
|
63
|
+
# Unset extensions
|
64
|
+
win_spec.extensions = nil
|
65
|
+
|
66
|
+
# Rake task to build the windows package
|
67
|
+
Gem::PackageTask.new(win_spec) do |pkg|
|
68
|
+
pkg.need_tar = false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# --------- RDoc Documentation ------
|
73
|
+
desc "Generate rdoc documentation"
|
74
|
+
RDoc::Task.new("rdoc") do |rdoc|
|
75
|
+
rdoc.rdoc_dir = 'doc'
|
76
|
+
rdoc.title = "ruby-prof"
|
77
|
+
# Show source inline with line numbers
|
78
|
+
rdoc.options << "--line-numbers"
|
79
|
+
# Make the readme file the start page for the generated html
|
80
|
+
rdoc.options << '--main' << 'README.rdoc'
|
81
|
+
rdoc.rdoc_files.include('bin/*',
|
82
|
+
'doc/*.rdoc',
|
83
|
+
'examples/flat.txt',
|
84
|
+
'examples/graph.txt',
|
85
|
+
'examples/graph.html',
|
86
|
+
'lib/**/*.rb',
|
87
|
+
'ext/ruby_prof/ruby_prof.c',
|
88
|
+
'ext/ruby_prof/measure_*.h',
|
89
|
+
'README.rdoc',
|
90
|
+
'LICENSE')
|
91
|
+
end
|
92
|
+
|
93
|
+
task :default => :test
|
94
|
+
|
95
|
+
for file in Dir['lib/**/*.{o,so,bundle}']
|
96
|
+
CLEAN.include file
|
97
|
+
end
|
98
|
+
for file in Dir['doc/**/*.{txt,dat,png,html}']
|
99
|
+
CLEAN.include file
|
100
|
+
end
|
101
|
+
CLEAN.reject!{|f| !File.exist?(f)}
|
102
|
+
task :clean do
|
103
|
+
# remove tmp dir contents completely after cleaning
|
104
|
+
FileUtils.rm_rf('tmp/*')
|
105
|
+
end
|
106
|
+
|
107
|
+
desc 'Run the ruby-prof test suite'
|
108
|
+
Rake::TestTask.new do |t|
|
109
|
+
t.libs += %w(lib ext test)
|
110
|
+
t.test_files = Dir['test/**_test.rb']
|
111
|
+
t.verbose = true
|
112
|
+
t.warning = true
|
113
|
+
end
|
data/bin/ruby-prof
ADDED
@@ -0,0 +1,345 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# == Synopsis
|
4
|
+
#
|
5
|
+
# Profiles a Ruby program.
|
6
|
+
#
|
7
|
+
# == Usage
|
8
|
+
#
|
9
|
+
# ruby_prof [options] <script.rb> [--] [script-options]"
|
10
|
+
#
|
11
|
+
# Various options:
|
12
|
+
# run "$ ruby-prof --help" to see them
|
13
|
+
#
|
14
|
+
# See also the readme "reports" section for the various outputs
|
15
|
+
|
16
|
+
# First require ruby-prof
|
17
|
+
require 'rubygems'
|
18
|
+
require 'ruby-prof'
|
19
|
+
|
20
|
+
# Now setup option parser
|
21
|
+
require 'ostruct'
|
22
|
+
require 'optparse'
|
23
|
+
|
24
|
+
module RubyProf
|
25
|
+
class Cmd
|
26
|
+
attr_accessor :options
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
setup_options
|
30
|
+
parse_args
|
31
|
+
|
32
|
+
load_pre_libs
|
33
|
+
load_pre_execs
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_options
|
37
|
+
@options = OpenStruct.new
|
38
|
+
options.printer = RubyProf::FlatPrinter
|
39
|
+
options.min_percent = 0
|
40
|
+
options.file = nil
|
41
|
+
options.replace_prog_name = false
|
42
|
+
options.specialized_instruction = false
|
43
|
+
|
44
|
+
options.pre_libs = Array.new
|
45
|
+
options.pre_execs = Array.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def option_parser
|
49
|
+
OptionParser.new do |opts|
|
50
|
+
opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
|
51
|
+
"Usage: ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]"
|
52
|
+
|
53
|
+
opts.separator ""
|
54
|
+
opts.separator "Options:"
|
55
|
+
|
56
|
+
opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot, :multi],
|
57
|
+
'Select a printer:',
|
58
|
+
' flat - Prints a flat profile as text (default).',
|
59
|
+
' flat_with_line_numbers - same as flat, with line numbers.',
|
60
|
+
' graph - Prints a graph profile as text.',
|
61
|
+
' graph_html - Prints a graph profile as html.',
|
62
|
+
' call_tree - format for KCacheGrind',
|
63
|
+
' call_stack - prints a HTML visualization of the call tree',
|
64
|
+
' dot - Prints a graph profile as a dot file',
|
65
|
+
' multi - Creates several reports in output directory'
|
66
|
+
) do |printer|
|
67
|
+
|
68
|
+
|
69
|
+
case printer
|
70
|
+
when :flat
|
71
|
+
options.printer = RubyProf::FlatPrinter
|
72
|
+
when :flat_with_line_numbers
|
73
|
+
options.printer = RubyProf::FlatPrinterWithLineNumbers
|
74
|
+
when :graph
|
75
|
+
options.printer = RubyProf::GraphPrinter
|
76
|
+
when :graph_html
|
77
|
+
options.printer = RubyProf::GraphHtmlPrinter
|
78
|
+
when :call_tree
|
79
|
+
options.printer = RubyProf::CallTreePrinter
|
80
|
+
when :call_stack
|
81
|
+
options.printer = RubyProf::CallStackPrinter
|
82
|
+
when :dot
|
83
|
+
options.printer = RubyProf::DotPrinter
|
84
|
+
when :multi
|
85
|
+
options.printer = RubyProf::MultiPrinter
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on('-m min_percent', '--min_percent=min_percent', Float,
|
90
|
+
'The minimum percent a method must take before ',
|
91
|
+
' being included in output reports.',
|
92
|
+
' this option is not supported for call tree.') do |min_percent|
|
93
|
+
options.min_percent = min_percent
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on('-f path', '--file=path',
|
97
|
+
'Output results to a file instead of standard out.') do |file|
|
98
|
+
options.file = file
|
99
|
+
options.old_wd = Dir.pwd
|
100
|
+
end
|
101
|
+
|
102
|
+
opts.on('--mode=measure_mode',
|
103
|
+
[:process, :wall, :cpu, :allocations, :memory, :gc_runs, :gc_time],
|
104
|
+
'Select what ruby-prof should measure:',
|
105
|
+
' wall - Wall time (default).',
|
106
|
+
' process - Process time.',
|
107
|
+
' cpu - CPU time (Pentium and PowerPCs only).',
|
108
|
+
' allocations - Object allocations (requires patched Ruby interpreter).',
|
109
|
+
' memory - Allocated memory in KB (requires patched Ruby interpreter).',
|
110
|
+
' gc_runs - Number of garbage collections (requires patched Ruby interpreter).',
|
111
|
+
' gc_time - Time spent in garbage collection (requires patched Ruby interpreter).') do |measure_mode|
|
112
|
+
|
113
|
+
case measure_mode
|
114
|
+
when :wall
|
115
|
+
options.measure_mode = RubyProf::WALL_TIME
|
116
|
+
when :process
|
117
|
+
options.measure_mode = RubyProf::PROCESS_TIME
|
118
|
+
when :cpu
|
119
|
+
options.measure_mode = RubyProf::CPU_TIME
|
120
|
+
when :allocations
|
121
|
+
options.measure_mode = RubyProf::ALLOCATIONS
|
122
|
+
when :memory
|
123
|
+
options.measure_mode = RubyProf::MEMORY
|
124
|
+
when :gc_runs
|
125
|
+
options.measure_mode = RubyProf::GC_RUNS
|
126
|
+
when :gc_time
|
127
|
+
options.measure_mode = RubyProf::GC_TIME
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
opts.on('-s sort_mode', '--sort=sort_mode', [:total, :self, :wait, :child],
|
132
|
+
'Select how ruby-prof results should be sorted:',
|
133
|
+
' total - Total time',
|
134
|
+
' self - Self time',
|
135
|
+
' wait - Wait time',
|
136
|
+
' child - Child time') do |sort_mode|
|
137
|
+
|
138
|
+
options.sort_method = case sort_mode
|
139
|
+
when :total
|
140
|
+
:total_time
|
141
|
+
when :self
|
142
|
+
:self_time
|
143
|
+
when :wait
|
144
|
+
:wait_time
|
145
|
+
when :child
|
146
|
+
:children_time
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
|
151
|
+
options.replace_prog_name = true
|
152
|
+
end
|
153
|
+
|
154
|
+
if defined?(RubyVM)
|
155
|
+
opts.on("--specialized-instruction", "Turn on specified instruction.") do
|
156
|
+
options.specialized_instruction = true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
opts.on_tail("-h", "--help", "Show help message") do
|
161
|
+
puts opts
|
162
|
+
exit
|
163
|
+
end
|
164
|
+
|
165
|
+
opts.on_tail("--version", "Show version #{RubyProf::VERSION}") do
|
166
|
+
puts "ruby_prof " + RubyProf::VERSION
|
167
|
+
exit
|
168
|
+
end
|
169
|
+
|
170
|
+
opts.on("-v","Show version, set $VERBOSE to true, profile script if option given") do
|
171
|
+
puts "ruby version: " + [RUBY_PATCHLEVEL, RUBY_PLATFORM, RUBY_VERSION].join(' ')
|
172
|
+
$VERBOSE = true
|
173
|
+
end
|
174
|
+
|
175
|
+
opts.on("-d", "Set $DEBUG to true") do
|
176
|
+
$DEBUG = true
|
177
|
+
end
|
178
|
+
|
179
|
+
opts.on('-R lib', '--require-noprof lib', 'require a specific library (not profiled)') do |lib|
|
180
|
+
options.pre_libs << lib
|
181
|
+
end
|
182
|
+
|
183
|
+
opts.on('-E code', '--eval-noprof code', 'execute the ruby statements (not profiled)') do |code|
|
184
|
+
options.pre_execs << code
|
185
|
+
end
|
186
|
+
|
187
|
+
opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do|meth|
|
188
|
+
options.eliminate_methods ||= []
|
189
|
+
options.eliminate_methods << Regexp.new(meth)
|
190
|
+
end
|
191
|
+
|
192
|
+
opts.on('-X file', '--exclude-file file', 'exclude methods by regexp listed in file (see method elimination)') do|file|
|
193
|
+
options.eliminate_methods_files ||= []
|
194
|
+
options.eliminate_methods_files << file
|
195
|
+
end
|
196
|
+
|
197
|
+
opts.on('--exclude-common-cycles', 'make common iterators like Integer#times appear inlined') do |meth|
|
198
|
+
options.eliminate_methods ||= []
|
199
|
+
options.eliminate_methods += %w{
|
200
|
+
Integer#times
|
201
|
+
Integer#upto
|
202
|
+
Integer#downto
|
203
|
+
Enumerator#each
|
204
|
+
Enumerator#each_with_index
|
205
|
+
Enumerator#each_with_object
|
206
|
+
|
207
|
+
Array#each
|
208
|
+
Array#each_index
|
209
|
+
Array#reverse_each
|
210
|
+
Array#map
|
211
|
+
|
212
|
+
Hash#each
|
213
|
+
Hash#each_pair
|
214
|
+
Hash#each_key
|
215
|
+
Hash#each_value
|
216
|
+
|
217
|
+
Range#each
|
218
|
+
Enumerable#each_cons
|
219
|
+
Enumerable#each_entry
|
220
|
+
Enumerable#each_slice
|
221
|
+
Enumerable#each_with_index
|
222
|
+
Enumerable#each_with_object
|
223
|
+
Enumerable#reverse_each
|
224
|
+
Enumerable#inject
|
225
|
+
Enumerable#collect
|
226
|
+
Enumerable#reduce
|
227
|
+
}
|
228
|
+
#TODO: may be the whole Enumerable module should be excluded via 'Enumerable#.*', we need feedback on use cases.
|
229
|
+
end
|
230
|
+
|
231
|
+
opts.on('--exclude-common-callbacks', 'make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph') do|meth|
|
232
|
+
options.eliminate_methods ||= []
|
233
|
+
options.eliminate_methods += %w{
|
234
|
+
Method#call
|
235
|
+
Proc#call
|
236
|
+
ActiveSupport::Callbacks::ClassMethods#__run_callback
|
237
|
+
}
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def parse_args
|
243
|
+
# Make sure the user specified at least one file
|
244
|
+
if ARGV.length < 1 and not options.exec
|
245
|
+
puts self.option_parser
|
246
|
+
puts ""
|
247
|
+
puts "Must specify a script to run"
|
248
|
+
exit(-1)
|
249
|
+
end
|
250
|
+
|
251
|
+
self.option_parser.parse! ARGV
|
252
|
+
|
253
|
+
if options.printer.needs_dir?
|
254
|
+
options.file ||= "."
|
255
|
+
options.old_wd ||= Dir.pwd
|
256
|
+
if !File.directory?(options.file)
|
257
|
+
puts "'#{options.file}' is not a directory"
|
258
|
+
puts "#{options.printer} needs an existing directory path to put profiles under."
|
259
|
+
exit(-1)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
|
263
|
+
puts self.option_parser
|
264
|
+
puts e.message
|
265
|
+
exit(-1)
|
266
|
+
end
|
267
|
+
|
268
|
+
def load_pre_libs
|
269
|
+
options.pre_libs.each do |lib|
|
270
|
+
require lib
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def load_pre_execs
|
275
|
+
options.pre_execs.each do |exec|
|
276
|
+
eval(exec)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def run
|
281
|
+
# Get the script we will execute
|
282
|
+
script = ARGV.shift
|
283
|
+
if options.replace_prog_name
|
284
|
+
$0 = File.expand_path(script)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Set VM compile option
|
288
|
+
if defined?(RubyVM)
|
289
|
+
RubyVM::InstructionSequence.compile_option = {
|
290
|
+
:trace_instruction => true,
|
291
|
+
:specialized_instruction => options.specialized_instruction
|
292
|
+
}
|
293
|
+
end
|
294
|
+
|
295
|
+
# Set the measure mode
|
296
|
+
RubyProf.measure_mode = options.measure_mode if options.measure_mode
|
297
|
+
RubyProf.start_script(script)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
# Parse command line options
|
303
|
+
cmd = RubyProf::Cmd.new
|
304
|
+
|
305
|
+
# Install at_exit handler. It is important that we do this
|
306
|
+
# before loading the scripts so our at_exit handler run
|
307
|
+
# *after* any other one that will be installed.
|
308
|
+
|
309
|
+
at_exit {
|
310
|
+
# Stop profiling
|
311
|
+
result = RubyProf.stop
|
312
|
+
|
313
|
+
# Eliminate unwanted methods from call graph
|
314
|
+
if cmd.options.eliminate_methods
|
315
|
+
result.eliminate_methods!(cmd.options.eliminate_methods)
|
316
|
+
end
|
317
|
+
|
318
|
+
if cmd.options.eliminate_methods_files
|
319
|
+
cmd.options.eliminate_methods_files.each {|f| result.eliminate_methods!(f)}
|
320
|
+
end
|
321
|
+
|
322
|
+
# Create a printer
|
323
|
+
printer = cmd.options.printer.new(result)
|
324
|
+
printer_options = {:min_percent => cmd.options.min_percent, :sort_method => cmd.options.sort_method}
|
325
|
+
|
326
|
+
# Get output
|
327
|
+
if cmd.options.file
|
328
|
+
# write it relative to the dir they *started* in, as it's a bit surprising to write it in the dir they end up in.
|
329
|
+
Dir.chdir(cmd.options.old_wd) do
|
330
|
+
if printer.class.needs_dir?
|
331
|
+
printer.print(printer_options.merge(:path => cmd.options.file))
|
332
|
+
else
|
333
|
+
File.open(cmd.options.file, 'w') do |file|
|
334
|
+
printer.print(file, printer_options)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
else
|
339
|
+
# Print out results
|
340
|
+
printer.print(STDOUT, printer_options)
|
341
|
+
end
|
342
|
+
}
|
343
|
+
|
344
|
+
# Now profile some code
|
345
|
+
cmd.run
|