Permalink
Browse files

Convert configuration variables to a Ruby data dsl

  • Loading branch information...
1 parent 037dd28 commit 3fd589419ae518990a1698a7d61346b07152589e @evanphx evanphx committed Aug 24, 2011
View
@@ -33,7 +33,7 @@ end
require config_rb
BUILD_CONFIG = Rubinius::BUILD_CONFIG
-unless BUILD_CONFIG[:config_version] == 137
+unless BUILD_CONFIG[:config_version] == 138
STDERR.puts "Your configuration is outdated, please run ./configure first"
exit 1
end
View
@@ -111,7 +111,7 @@ class Configure
@libversion = "2.0"
@version = "#{@libversion}.0dev"
@release_date = "yyyy-mm-dd"
- @config_version = 137
+ @config_version = 138
# TODO: add conditionals for platforms
if RbConfig::CONFIG["build_os"] =~ /darwin/
@@ -963,6 +963,7 @@ module Rubinius
:bsd => #{@bsd},
:linux => #{@linux},
:version_list => #{@version_list.inspect},
+ :default_version => "#{@default_version}",
:vendor_zlib => #{@vendor_zlib},
}
end
View
@@ -455,6 +455,16 @@ def options(argv=ARGV)
handle_simple_options(argv)
end
+ if Rubinius::Config['help']
+ STDOUT.puts "Rubinius configuration variables:"
+ STDOUT.puts " These variables are normally set via -X and read via Rubinius::Config[var]."
+ STDOUT.puts
+
+ require 'rubinius/configuration'
+ Rubinius::ConfigurationVariables.instance.show_help(STDOUT)
+ exit 0
+ end
+
if str = Rubinius::Config['tool.require']
begin
require str
@@ -0,0 +1,138 @@
+require 'rubinius/build_config'
+require 'rubinius/configuration_variables'
+
+Rubinius::ConfigurationVariables.define do |c|
+
+ possible = Rubinius::BUILD_CONFIG[:version_list].map { |x| [x, x.to_i] }
+
+ c.vm_variable "version", :radio,
+ :possible => possible,
+ :default => Rubinius::BUILD_CONFIG[:default_version],
+ :description => "Which version of ruby should we run"
+
+ c.section "gc" do |s|
+ s.vm_variable "bytes", 3145728,
+ "The number of bytes the young generation of the GC should use"
+
+ s.vm_variable "large_object", (50 * 1024),
+ "The size (in bytes) of the large object threshold"
+
+ s.vm_variable "lifetime", 3,
+ "How many young GC cycles an object lives before promotion"
+
+ s.vm_variable "autotune", true,
+ "Set whether or not the GC should adjust itself for performance"
+
+ s.vm_variable "show", :bool,
+ "Display information whenever the GC runs"
+
+ s.vm_variable "immix.debug", :bool,
+ "Print out collection stats when the Immix collector finishes"
+
+ s.vm_variable "honor_start", false,
+ "Control whether or not GC.start is honored when called"
+
+ s.vm_variable "autopack", true,
+ "Set whether or not objects should be backed tightly in memory"
+
+ s.vm_variable "marksweep_threshold", (10 * 1024 * 1024),
+ "The number of bytes allocated before the marksweep GC region is collected"
+
+ s.vm_variable "malloc_threshold", 104857600,
+ "How many bytes allocated by C extensions til the GC is run"
+ end
+
+ c.section "jit" do |s|
+ s.vm_variable "dump_code", 0,
+ "1 == show simple IR, 2 == show optimized IR, 4 == show machine code"
+
+ s.vm_variable "call_til_compile", 4000,
+ "How many times a method is called before the JIT is run on it"
+
+ s.vm_variable "max_method_size", 2048,
+ "The max size of a method that will be JIT"
+
+ s.vm_variable "show", false,
+ :as => "jit_show_compiling",
+ :description => "Print out a status message when the JIT is operating"
+
+
+ s.vm_variable "profile", false,
+ "The JIT will emit code to be sure JITd methods can be profile"
+
+ s.section "inline" do |i|
+ i.vm_variable "generic", true, "Have the JIT inline generic methods"
+
+ i.vm_variable "debug", false,
+ "Have the JIT print out information about inlining"
+
+ i.vm_variable "blocks", true,
+ "Have the JIT try and inline methods and their literal blocks"
+ end
+
+ s.vm_variable "log", :string,
+ "Send JIT debugging output to this file rather than stdout"
+
+ s.vm_variable "debug", false,
+ "Have the JIT print debugging information"
+
+ s.vm_variable "sync", false,
+ "Wait for the JIT to finish compiling each method"
+
+ s.vm_variable "uncommon.print", false,
+ "Print out information on when methods are deoptimized due to uncommon traps"
+
+ s.vm_variable "removal.print", false,
+ "Print out whenever the JIT is removing unused code"
+
+ s.vm_variable "check_debugging", false,
+ "Allow JITd methods to deoptimize if there is a debugging request"
+
+ s.vm_variable "type.optz", false,
+ "Enable optimizations based on type flow"
+ end
+
+ c.section "agent" do |s|
+ s.vm_variable "port", 0,
+ "Start the QueryAgent on a TCP port. Default port is a random port"
+
+ s.vm_variable "verbose", false,
+ "Whether or not the query agent should print out status to stderr"
+
+ s.vm_variable "tmpdir", :string,
+ "Where to store files used to discover running query agents"
+
+ end
+
+ c.vm_variable "tool", :string,
+ :as => "tool_to_load",
+ :description => "Load a VM tool from a shared library"
+
+ c.vm_variable "capi.global_flush", false,
+ "Flush all CAPI handles at CAPI call boundaries"
+
+ c.vm_variable "int", false,
+ :as => "jit_disabled",
+ :description => "Force the JIT to never turn on"
+
+ c.vm_variable "config.print", 0,
+ :as => "print_config",
+ :description => "blank or 1 == names and values, 2 == description as well"
+
+ c.vm_variable "ic.stats", false,
+ "Print out stats about the InlineCaches before exiting"
+
+ c.vm_variable "profile", false,
+ "Configure the system to profile ruby code"
+
+ c.vm_variable "profiler.threshold", 1000000,
+ "The mininum number of nanoseconds a profiler node must have to be reported"
+
+ c.vm_variable "vm.crash_report_path", :string,
+ :as => "report_path",
+ :description => "Set a custom path to write crash reports"
+
+ c.vm_variable "thread.debug", false,
+ "Print threading notices when they occur"
+end
+
@@ -0,0 +1,192 @@
+module Rubinius
+class ConfigurationVariables
+ def self.define
+ obj = new
+ yield obj.root
+ @instance = obj
+ end
+
+ def self.instance
+ @instance
+ end
+
+ def initialize
+ @root = Section.new(self, nil)
+ @variables = []
+ end
+
+ attr_reader :root, :variables
+
+ def write_vm_variables(io)
+ @variables.each do |v|
+ if decl = v.declaration
+ io.puts decl
+ end
+ end
+
+ io.puts "Configuration() :"
+ all = @variables.map { |v| v.initializer }.compact
+
+ io.puts all.join",\n"
+ io.puts "{"
+
+ @variables.each do |v|
+ if des = v.setup
+ io.puts des
+ end
+ end
+
+ io.puts "}"
+ end
+
+ def show_help(io)
+ max = @variables.map { |v| v.name.size }.max
+
+ @variables.each do |v|
+ width = v.name.size
+ io.puts "#{' ' * (max - width)}#{v.name}: #{v.description}"
+
+ if s = v.value_info
+ io.puts "#{' ' * max} #{s}"
+ end
+
+ end
+ end
+
+ class Variable
+ def initialize(name, vm=true)
+ @name = name
+ @default = nil
+ @type = nil
+ @vm = vm
+ @description = nil
+ @options = nil
+
+ if vm
+ @vm_name = name.gsub(".","_")
+ else
+ @vm_name = nil
+ end
+ end
+
+ attr_reader :name
+ attr_accessor :default, :type, :description, :vm_name, :options
+
+ def value_info
+ if @type == "config::Radio"
+ possible = @options[:possible]
+ default = @options[:default]
+
+ "default: #{default}, possible: #{possible.map { |x| x[0] }.join(", ")}"
+ elsif @default
+ "default: #{@default}"
+ else
+ nil
+ end
+ end
+
+ def declaration
+ return nil unless @vm
+ raise "No type set for #{@name}" unless @type
+ raise "No vm name set for #{@name}" unless @vm_name
+
+ "#{@type} #{@vm_name};"
+ end
+
+ def initializer
+ return nil unless @vm
+
+ if @default
+ "#{@vm_name}(this, \"#{@name}\", #{@default.inspect})"
+ else
+ "#{@vm_name}(this, \"#{@name}\")"
+ end
+ end
+
+ def setup
+ return nil unless @vm
+
+ str = "#{@vm_name}.set_description(#{@description.inspect});"
+
+ if @type == "config::Radio"
+ possible = @options[:possible]
+ unless possible
+ raise "Radio type requires the :possible key"
+ end
+
+ default = @options[:default] || possible.first
+
+ possible.each do |k,v|
+ if k == default
+ str << "\n#{@vm_name}.add(#{k.inspect}, #{v.inspect}, true);"
+ else
+ str << "\n#{@vm_name}.add(#{k.inspect}, #{v.inspect});"
+ end
+ end
+ end
+
+ str
+ end
+ end
+
+ class Section
+ def initialize(config, prefix)
+ @config = config
+ @prefix = prefix
+ end
+
+ def section(name)
+ s = Section.new @config, full_name(name)
+ yield s
+ end
+
+ def full_name(name)
+ return name unless @prefix
+ "#{@prefix}.#{name}"
+ end
+
+ def vm_variable(name, default, options=nil)
+ var = Variable.new full_name(name)
+
+ case default
+ when Fixnum
+ var.default = default
+ var.type = "config::Integer"
+ when :integer
+ var.type = "config::Integer"
+
+ when String
+ var.default = default
+ var.type = "config::String"
+ when :string
+ var.type = "config::String"
+
+ when true, false
+ var.default = default
+ var.type = "config::Bool"
+ when :bool
+ var.type = "config::Bool"
+
+ when Array
+ var.default = default
+ var.type = "config::Radio"
+ when :radio
+ var.type = "config::Radio"
+ end
+
+ case options
+ when String
+ var.description = options
+ when Hash
+ var.options = options
+
+ var.description = options[:description]
+ var.vm_name = options[:as] if options[:as]
+ end
+
+ @config.variables << var
+ end
+
+ end
+end
+end
View
@@ -40,6 +40,7 @@ TYPE_GEN = %w[ vm/gen/includes.hpp
vm/gen/primitives_glue.gen.cpp ]
GENERATED = %W[ vm/gen/revision.h
+ vm/gen/config_variables.h
#{encoding_database} ] + TYPE_GEN + INSN_GEN
# Files are in order based on dependencies. For example,
@@ -205,6 +206,10 @@ task 'vm/gen/revision.h' do |t|
end
end
+task 'vm/gen/config_variables.h' => 'lib/rubinius/configuration.rb' do
+ ruby 'vm/codegen/config_vars.rb', 'vm/gen/config_variables.h'
+end
+
require 'projects/daedalus/daedalus'
if jobs = ENV['JOBS']
Oops, something went wrong.

0 comments on commit 3fd5894

Please sign in to comment.