#!/usr/bin/env ruby require 'rubygems' require 'optparse' require 'cast_off' this = File.expand_path(__FILE__) step = nil verbose = false clear = false deoptimize = false threshold = 100 name = nil opt = OptionParser.new(<<-EOS, 32, ' ') CastOff is a performance improvement tool for Ruby1.9.3. Usage: CastOff [options] [programfile] [arguments] EOS opt.separator("\n Options:") opt.on('--verbose', <<-EOS.strip) {|v| verbose = true } Show compilation progress and internal information. EOS opt.on('--deoptimize', <<-EOS.strip) {|v| deoptimize = true } Enable deoptimization. EOS opt.on('--threshold=COUNT', <<-EOS.strip, Integer) {|v| threshold = v } Compile method which is executed more than COUNT. Default value is 100. EOS opt.on('--name=NAME', <<-EOS.strip, String) {|v| name = v } Name compiled methods NAME. This name is used for search of compiled methods. If you don't use this option, CastOff uses File.basename([programfile]) as name. EOS opt.on('--clear', <<-EOS.strip) {|v| clear = true } Clear profile information and delete compiled methods. If you want to clear profile information and compiled methods of target name "foo", you should execute following command. $CastOff --clear --name=foo EOS opt.on('--run', <<-EOS.strip) {|v| step = 'run' } Execute [programfile] with compiled methods. EOS opt.on('--step-1', <<-EOS.strip) {|v| step = '1' } First step of compilation. On this step, CastOff decides compilation target methods. EOS opt.on('--step-2', <<-EOS.strip) {|v| step = '2' } Second step of compilation. On this step, CastOff collects profile information and compiles methods. EOS opt.on_tail('-h', "--help", "Show this help.") do puts opt exit end opt.on_tail("--version", "Show version number.") do puts Gem.loaded_specs['cast_off'].version.to_s exit end opt.order!(ARGV) args = ARGV.join(" ") script = ARGV.shift || '' name = File.basename(script) unless name if clear if name.empty? STDERR.puts(<<-EOS) Invalid arguments. You should pass target name to CastOff. If you want to clear profile information and compiled methods of target name "foo", you should execute following command. $CastOff --clear --name=foo EOS exit(1) end CastOff.program_name = name CastOff.clear() exit(0) end unless File.exist?(script) if script.empty? STDERR.puts("Invalid arguments. You should pass [programname] to CastOff.") else STDERR.puts("#{script} is not exist.") end exit(1) end configuration = <<-EOS CastOff.program_name = #{name.inspect} CastOff.skip_configuration_check(true) CastOff.deoptimize(#{deoptimize}) CastOff.use_default_configuration() EOS eval(configuration, binding) CastOff.compilation_threshold = threshold CastOff.program_name = name CastOff.verbose(verbose) case step when nil STDERR.puts("-------------------------------- compilation start, threshold = #{threshold}, name = #{name}: #{args} --------------------------------") 2.times{|i| system("#{this} --step-#{i + 1} --threshold=#{threshold} --name=#{name} #{deoptimize ? '--deoptimize' : ''} #{verbose ? '--verbose' : ''} #{args}")} when '1' STDERR.puts("-------------------------------- step 1 --------------------------------") CastOff.development(true) CastOff.use_base_configuration(false) CastOff.autocompile() when '2' STDERR.puts("-------------------------------- step 2 --------------------------------") CastOff.development(true) CastOff.use_base_configuration(false) CastOff.autoload() #fin = Object.new #ObjectSpace.define_finalizer(fin){ at_exit{ CastOff.development(false) CastOff.use_base_configuration(true) # step 3 CastOff.load(true) msg = <<-EOS ---------------------------------------------------------------------------------------- Compilation finished successfully. Please add following lines to #{script}. require 'cast_off' #{configuration.chomp} CastOff.autoload() ---------------------------------------------------------------------------------------- EOS STDERR.puts(msg) } when 'run' CastOff.autoload() else raise("should not be reached") end load script if step