ruby-prof 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +523 -0
  3. data/LICENSE +25 -0
  4. data/README.rdoc +5 -0
  5. data/Rakefile +110 -0
  6. data/bin/ruby-prof +380 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +36 -0
  9. data/ext/ruby_prof/rp_allocation.c +292 -0
  10. data/ext/ruby_prof/rp_allocation.h +31 -0
  11. data/ext/ruby_prof/rp_call_info.c +283 -0
  12. data/ext/ruby_prof/rp_call_info.h +35 -0
  13. data/ext/ruby_prof/rp_measure_allocations.c +52 -0
  14. data/ext/ruby_prof/rp_measure_memory.c +42 -0
  15. data/ext/ruby_prof/rp_measure_process_time.c +63 -0
  16. data/ext/ruby_prof/rp_measure_wall_time.c +62 -0
  17. data/ext/ruby_prof/rp_measurement.c +236 -0
  18. data/ext/ruby_prof/rp_measurement.h +49 -0
  19. data/ext/ruby_prof/rp_method.c +642 -0
  20. data/ext/ruby_prof/rp_method.h +70 -0
  21. data/ext/ruby_prof/rp_profile.c +881 -0
  22. data/ext/ruby_prof/rp_profile.h +36 -0
  23. data/ext/ruby_prof/rp_stack.c +196 -0
  24. data/ext/ruby_prof/rp_stack.h +56 -0
  25. data/ext/ruby_prof/rp_thread.c +338 -0
  26. data/ext/ruby_prof/rp_thread.h +36 -0
  27. data/ext/ruby_prof/ruby_prof.c +48 -0
  28. data/ext/ruby_prof/ruby_prof.h +17 -0
  29. data/ext/ruby_prof/vc/ruby_prof.sln +31 -0
  30. data/ext/ruby_prof/vc/ruby_prof.vcxproj +143 -0
  31. data/lib/ruby-prof.rb +53 -0
  32. data/lib/ruby-prof/assets/call_stack_printer.css.html +117 -0
  33. data/lib/ruby-prof/assets/call_stack_printer.js.html +385 -0
  34. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  35. data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
  36. data/lib/ruby-prof/call_info.rb +57 -0
  37. data/lib/ruby-prof/call_info_visitor.rb +38 -0
  38. data/lib/ruby-prof/compatibility.rb +109 -0
  39. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  40. data/lib/ruby-prof/measurement.rb +14 -0
  41. data/lib/ruby-prof/method_info.rb +90 -0
  42. data/lib/ruby-prof/printers/abstract_printer.rb +118 -0
  43. data/lib/ruby-prof/printers/call_info_printer.rb +51 -0
  44. data/lib/ruby-prof/printers/call_stack_printer.rb +269 -0
  45. data/lib/ruby-prof/printers/call_tree_printer.rb +151 -0
  46. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  47. data/lib/ruby-prof/printers/flat_printer.rb +52 -0
  48. data/lib/ruby-prof/printers/graph_html_printer.rb +64 -0
  49. data/lib/ruby-prof/printers/graph_printer.rb +114 -0
  50. data/lib/ruby-prof/printers/multi_printer.rb +127 -0
  51. data/lib/ruby-prof/profile.rb +33 -0
  52. data/lib/ruby-prof/rack.rb +171 -0
  53. data/lib/ruby-prof/task.rb +147 -0
  54. data/lib/ruby-prof/thread.rb +35 -0
  55. data/lib/ruby-prof/version.rb +3 -0
  56. data/lib/unprof.rb +10 -0
  57. data/ruby-prof.gemspec +58 -0
  58. data/test/abstract_printer_test.rb +26 -0
  59. data/test/alias_test.rb +129 -0
  60. data/test/basic_test.rb +129 -0
  61. data/test/call_info_visitor_test.rb +31 -0
  62. data/test/duplicate_names_test.rb +32 -0
  63. data/test/dynamic_method_test.rb +53 -0
  64. data/test/enumerable_test.rb +21 -0
  65. data/test/exceptions_test.rb +24 -0
  66. data/test/exclude_methods_test.rb +146 -0
  67. data/test/exclude_threads_test.rb +53 -0
  68. data/test/line_number_test.rb +161 -0
  69. data/test/marshal_test.rb +119 -0
  70. data/test/measure_allocations.rb +30 -0
  71. data/test/measure_allocations_test.rb +385 -0
  72. data/test/measure_allocations_trace_test.rb +385 -0
  73. data/test/measure_memory_trace_test.rb +756 -0
  74. data/test/measure_process_time_test.rb +849 -0
  75. data/test/measure_times.rb +54 -0
  76. data/test/measure_wall_time_test.rb +459 -0
  77. data/test/multi_printer_test.rb +71 -0
  78. data/test/no_method_class_test.rb +15 -0
  79. data/test/parser_timings.rb +24 -0
  80. data/test/pause_resume_test.rb +166 -0
  81. data/test/prime.rb +56 -0
  82. data/test/printer_call_tree_test.rb +31 -0
  83. data/test/printer_flat_test.rb +68 -0
  84. data/test/printer_graph_html_test.rb +60 -0
  85. data/test/printer_graph_test.rb +41 -0
  86. data/test/printers_test.rb +141 -0
  87. data/test/printing_recursive_graph_test.rb +81 -0
  88. data/test/rack_test.rb +157 -0
  89. data/test/recursive_test.rb +210 -0
  90. data/test/singleton_test.rb +38 -0
  91. data/test/stack_printer_test.rb +64 -0
  92. data/test/start_stop_test.rb +109 -0
  93. data/test/test_helper.rb +24 -0
  94. data/test/thread_test.rb +144 -0
  95. data/test/unique_call_path_test.rb +190 -0
  96. data/test/yarv_test.rb +56 -0
  97. metadata +189 -0
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (C) 2005 - 2019 Shugo Maeda <shugo@ruby-lang.org>, Charlie Savage <cfis@savagexi.com> and
2
+ Stefan Kaes <skaes@railsepxress.de>
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
+
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+ = ruby-prof
2
+
3
+ {<img src="https://travis-ci.org/ruby-prof/ruby-prof.png?branch=master" alt="Build Status" />}[https://travis-ci.org/ruby-prof/ruby-prof]
4
+
5
+ For an overview of ruby-prof please see https://ruby-prof.github.io
@@ -0,0 +1,110 @@
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-mingw32', 'x64-mingw32']
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
+ 'lib/**/*.rb',
84
+ 'ext/ruby_prof/*.c',
85
+ 'ext/ruby_prof/*.h',
86
+ 'README.rdoc',
87
+ 'LICENSE')
88
+ end
89
+
90
+ task :default => :test
91
+
92
+ for file in Dir['lib/**/*.{o,so,bundle}']
93
+ CLEAN.include file
94
+ end
95
+ for file in Dir['doc/**/*.{txt,dat,png,html}']
96
+ CLEAN.include file
97
+ end
98
+ CLEAN.reject!{|f| !File.exist?(f)}
99
+ task :clean do
100
+ # remove tmp dir contents completely after cleaning
101
+ FileUtils.rm_rf('tmp/*')
102
+ end
103
+
104
+ desc 'Run the ruby-prof test suite'
105
+ Rake::TestTask.new do |t|
106
+ t.libs += %w(lib ext test)
107
+ t.test_files = Dir['test/**_test.rb']
108
+ t.verbose = true
109
+ t.warning = true
110
+ end
@@ -0,0 +1,380 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ # First require ruby-prof
4
+ require 'rubygems'
5
+ require 'ruby-prof'
6
+
7
+ # Now setup option parser
8
+ require 'ostruct'
9
+ require 'optparse'
10
+
11
+ module RubyProf
12
+ # == Synopsis
13
+ #
14
+ # Profiles a Ruby program.
15
+ #
16
+ # == Usage
17
+ #
18
+ # ruby_prof [options] <script.rb> [--] [script-options]
19
+ #
20
+ # Options:
21
+ # -p, --printer=printer Select a printer:
22
+ # flat - Prints a flat profile as text (default).
23
+ # graph - Prints a graph profile as text.
24
+ # graph_html - Prints a graph profile as html.
25
+ # call_tree - format for KCacheGrind
26
+ # call_stack - prints a HTML visualization of the call tree
27
+ # dot - Prints a graph profile as a dot file
28
+ # multi - Creates several reports in output directory
29
+ #
30
+ # -m, --min_percent=min_percent The minimum percent a method must take before
31
+ # being included in output reports. This option is not supported for call tree reports.
32
+ #
33
+ # -f, --file=path Output results to a file instead of standard out.
34
+ #
35
+ # --mode=measure_mode Select what ruby-prof should measure:
36
+ # wall - Wall time (default)
37
+ # process - Process time
38
+ # allocations - Object allocations
39
+ # memory - Allocated memory
40
+ #
41
+ # -s, --sort=sort_mode Select how ruby-prof results should be sorted:
42
+ # total - Total time
43
+ # self - Self time
44
+ # wait - Wait time
45
+ # child - Child time
46
+ #
47
+ # --replace-progname Replace $0 when loading the .rb files.
48
+ #
49
+ # --specialized-instruction Turn on specified instruction.
50
+ #
51
+ # -v Show version, set $VERBOSE to true, profile script if option given
52
+ #
53
+ # -d Set $DEBUG to true
54
+ #
55
+ # -R, --require-noprof lib Require a specific library (not profiled)
56
+ #
57
+ # -E, --eval-noprof code Execute the ruby statements (not profiled)
58
+ #
59
+ # -x, --exclude regexp Exclude methods by regexp (see method elimination)
60
+ #
61
+ # -X, --exclude-file file Exclude methods by regexp listed in file (see method elimination)
62
+ #
63
+ # --exclude-common-cycles Make common iterators like Integer#times appear inlined
64
+ #
65
+ # --exclude-common-callbacks Make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph
66
+ #
67
+ # -h, --help Show help message
68
+ #
69
+ # --version Show version
70
+ #
71
+ #
72
+ class Cmd
73
+ # :enddoc:
74
+ attr_accessor :options
75
+
76
+ def initialize
77
+ setup_options
78
+ parse_args
79
+
80
+ load_pre_libs
81
+ load_pre_execs
82
+ end
83
+
84
+ def setup_options
85
+ @options = OpenStruct.new
86
+ options.printer = RubyProf::FlatPrinter
87
+ options.min_percent = 0
88
+ options.file = nil
89
+ options.replace_prog_name = false
90
+ options.specialized_instruction = false
91
+
92
+ options.pre_libs = Array.new
93
+ options.pre_execs = Array.new
94
+ end
95
+
96
+ def option_parser
97
+ OptionParser.new do |opts|
98
+ opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
99
+ "Usage: ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]"
100
+
101
+ opts.separator ""
102
+ opts.separator "Options:"
103
+
104
+ opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot, :multi],
105
+ 'Select a printer:',
106
+ ' flat - Prints a flat profile as text (default).',
107
+ ' graph - Prints a graph profile as text.',
108
+ ' graph_html - Prints a graph profile as html.',
109
+ ' call_tree - format for KCacheGrind',
110
+ ' call_stack - prints a HTML visualization of the call tree',
111
+ ' dot - Prints a graph profile as a dot file',
112
+ ' multi - Creates several reports in output directory'
113
+ ) do |printer|
114
+
115
+ case printer
116
+ when :flat
117
+ options.printer = RubyProf::FlatPrinter
118
+ when :graph
119
+ options.printer = RubyProf::GraphPrinter
120
+ when :graph_html
121
+ options.printer = RubyProf::GraphHtmlPrinter
122
+ when :call_tree
123
+ options.printer = RubyProf::CallTreePrinter
124
+ when :call_stack
125
+ options.printer = RubyProf::CallStackPrinter
126
+ when :dot
127
+ options.printer = RubyProf::DotPrinter
128
+ when :multi
129
+ options.printer = RubyProf::MultiPrinter
130
+ end
131
+ end
132
+
133
+ opts.on('-m min_percent', '--min_percent=min_percent', Float,
134
+ 'The minimum percent a method must take before ',
135
+ ' being included in output reports.',
136
+ ' This option is not supported for call tree.') do |min_percent|
137
+ options.min_percent = min_percent
138
+ end
139
+
140
+ opts.on('-f path', '--file=path',
141
+ 'Output results to a file instead of standard out.') do |file|
142
+ options.file = file
143
+ options.old_wd = Dir.pwd
144
+ end
145
+
146
+ opts.on('--mode=measure_mode',
147
+ [:process, :wall, :allocations, :memory],
148
+ 'Select what ruby-prof should measure:',
149
+ ' wall - Wall time (default).',
150
+ ' process - Process time.',
151
+ ' allocations - Object allocations (requires patched Ruby interpreter).',
152
+ ' memory - Allocated memory in KB (requires patched Ruby interpreter).') do |measure_mode|
153
+
154
+ case measure_mode
155
+ when :wall
156
+ options.measure_mode = RubyProf::WALL_TIME
157
+ when :process
158
+ options.measure_mode = RubyProf::PROCESS_TIME
159
+ when :allocations
160
+ options.measure_mode = RubyProf::ALLOCATIONS
161
+ when :memory
162
+ options.measure_mode = RubyProf::MEMORY
163
+ end
164
+ end
165
+
166
+ opts.on('-s sort_mode', '--sort=sort_mode', [:total, :self, :wait, :child],
167
+ 'Select how ruby-prof results should be sorted:',
168
+ ' total - Total time',
169
+ ' self - Self time',
170
+ ' wait - Wait time',
171
+ ' child - Child time') do |sort_mode|
172
+
173
+ options.sort_method = case sort_mode
174
+ when :total
175
+ :total_time
176
+ when :self
177
+ :self_time
178
+ when :wait
179
+ :wait_time
180
+ when :child
181
+ :children_time
182
+ end
183
+ end
184
+
185
+ opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
186
+ options.replace_prog_name = true
187
+ end
188
+
189
+ if defined?(RubyVM)
190
+ opts.on("--specialized-instruction", "Turn on specified instruction.") do
191
+ options.specialized_instruction = true
192
+ end
193
+ end
194
+
195
+ opts.on_tail("-h", "--help", "Show help message") do
196
+ puts opts
197
+ exit
198
+ end
199
+
200
+ opts.on_tail("--version", "Show version #{RubyProf::VERSION}") do
201
+ puts "ruby_prof " + RubyProf::VERSION
202
+ exit
203
+ end
204
+
205
+ opts.on("-v","Show version, set $VERBOSE to true, profile script if option given") do
206
+ puts "ruby version: " + [RUBY_PATCHLEVEL, RUBY_PLATFORM, RUBY_VERSION].join(' ')
207
+ $VERBOSE = true
208
+ end
209
+
210
+ opts.on("-d", "Set $DEBUG to true") do
211
+ $DEBUG = true
212
+ end
213
+
214
+ opts.on('-R lib', '--require-noprof lib', 'require a specific library (not profiled)') do |lib|
215
+ options.pre_libs << lib
216
+ end
217
+
218
+ opts.on('-E code', '--eval-noprof code', 'execute the ruby statements (not profiled)') do |code|
219
+ options.pre_execs << code
220
+ end
221
+
222
+ opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do |meth|
223
+ options.eliminate_methods ||= []
224
+ options.eliminate_methods << Regexp.new(meth)
225
+ end
226
+
227
+ opts.on('-X file', '--exclude-file file', 'exclude methods by regexp listed in file (see method elimination)') do|file|
228
+ options.eliminate_methods_files ||= []
229
+ options.eliminate_methods_files << file
230
+ end
231
+
232
+ opts.on('--exclude-common-cycles', 'make common iterators like Integer#times appear inlined') do |meth|
233
+ options.eliminate_methods ||= []
234
+ options.eliminate_methods += %w{
235
+ Integer#times
236
+ Integer#upto
237
+ Integer#downto
238
+ Enumerator#each
239
+ Enumerator#each_with_index
240
+ Enumerator#each_with_object
241
+
242
+ Array#each
243
+ Array#each_index
244
+ Array#reverse_each
245
+ Array#map
246
+
247
+ Hash#each
248
+ Hash#each_pair
249
+ Hash#each_key
250
+ Hash#each_value
251
+
252
+ Range#each
253
+ Enumerable#each_cons
254
+ Enumerable#each_entry
255
+ Enumerable#each_slice
256
+ Enumerable#each_with_index
257
+ Enumerable#each_with_object
258
+ Enumerable#reverse_each
259
+ Enumerable#inject
260
+ Enumerable#collect
261
+ Enumerable#reduce
262
+ }
263
+ #TODO: may be the whole Enumerable module should be excluded via 'Enumerable#.*', we need feedback on use cases.
264
+ end
265
+
266
+ opts.on('--exclude-common-callbacks', 'make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph') do|meth|
267
+ options.eliminate_methods ||= []
268
+ options.eliminate_methods += %w{
269
+ Method#call
270
+ Proc#call
271
+ ActiveSupport::Callbacks::ClassMethods#__run_callback
272
+ }
273
+ end
274
+ end
275
+ end
276
+
277
+ def parse_args
278
+ # Make sure the user specified at least one file
279
+ if ARGV.length < 1 and not options.exec
280
+ puts self.option_parser
281
+ puts ""
282
+ puts "Must specify a script to run"
283
+ exit(-1)
284
+ end
285
+
286
+ self.option_parser.parse! ARGV
287
+
288
+ if options.printer.needs_dir?
289
+ options.file ||= "."
290
+ options.old_wd ||= Dir.pwd
291
+ if !File.directory?(options.file)
292
+ puts "'#{options.file}' is not a directory"
293
+ puts "#{options.printer} needs an existing directory path to put profiles under."
294
+ exit(-1)
295
+ end
296
+ end
297
+ rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
298
+ puts self.option_parser
299
+ puts e.message
300
+ exit(-1)
301
+ end
302
+
303
+ def load_pre_libs
304
+ options.pre_libs.each do |lib|
305
+ require lib
306
+ end
307
+ end
308
+
309
+ def load_pre_execs
310
+ options.pre_execs.each do |exec|
311
+ eval(exec)
312
+ end
313
+ end
314
+
315
+ def run
316
+ # Get the script we will execute
317
+ script = ARGV.shift
318
+ if options.replace_prog_name
319
+ $0 = File.expand_path(script)
320
+ end
321
+
322
+ # Set VM compile option
323
+ if defined?(RubyVM)
324
+ RubyVM::InstructionSequence.compile_option = {
325
+ :trace_instruction => true,
326
+ :specialized_instruction => options.specialized_instruction
327
+ }
328
+ end
329
+
330
+ # Set the measure mode
331
+ RubyProf.measure_mode = options.measure_mode if options.measure_mode
332
+ RubyProf.start_script(script)
333
+ end
334
+ end
335
+ end
336
+
337
+ # Parse command line options
338
+ cmd = RubyProf::Cmd.new
339
+
340
+ # Install at_exit handler. It is important that we do this
341
+ # before loading the scripts so our at_exit handler run
342
+ # *after* any other one that will be installed.
343
+
344
+ at_exit {
345
+ # Stop profiling
346
+ result = RubyProf.stop
347
+
348
+ # Eliminate unwanted methods from call graph
349
+ if cmd.options.eliminate_methods
350
+ result.eliminate_methods!(cmd.options.eliminate_methods)
351
+ end
352
+
353
+ if cmd.options.eliminate_methods_files
354
+ cmd.options.eliminate_methods_files.each {|f| result.eliminate_methods!(f)}
355
+ end
356
+
357
+ # Create a printer
358
+ printer = cmd.options.printer.new(result)
359
+ printer_options = {:min_percent => cmd.options.min_percent, :sort_method => cmd.options.sort_method}
360
+
361
+ # Get output
362
+ if cmd.options.file
363
+ # 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.
364
+ Dir.chdir(cmd.options.old_wd) do
365
+ if printer.class.needs_dir?
366
+ printer.print(printer_options.merge(:path => cmd.options.file))
367
+ else
368
+ File.open(cmd.options.file, 'w') do |file|
369
+ printer.print(file, printer_options)
370
+ end
371
+ end
372
+ end
373
+ else
374
+ # Print out results
375
+ printer.print(STDOUT, printer_options)
376
+ end
377
+ }
378
+
379
+ # Now profile some code
380
+ cmd.run