Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add cli switch to enable jit

-X switches are added directly to the internal configuration.

-Xrbx.jit enables the jit if it's supported by the platform
-Xrbx.dyni enables the dynamic interpreter if it's supported
  • Loading branch information...
commit 6c31ab682a04a7b7a7f1c0c83390fe907439daad 1 parent cc3779e
Evan Phoenix authored
View
5 kernel/bootstrap/vm.rb
@@ -4,6 +4,11 @@ def self.stats
raise PrimitiveFailure, "primitive failed"
end
+ def self.jit_info
+ Ruby.primitive :vm_jit_info
+ raise PrimitiveFailure, "primitive failed"
+ end
+
def self.start_profiler
Ruby.primitive :vm_start_profiler
raise PrimitiveFailure, "unable to start profiler"
View
8 kernel/loader.rb
@@ -125,6 +125,8 @@
puts "[Interpreter type: #{Rubinius::INTERPRETER}]"
if jit = Rubinius::JIT
puts "[JIT enabled: #{jit}]"
+ else
+ puts "[JIT disabled]"
end
when "-w"
# do nothing (HACK)
@@ -365,5 +367,11 @@
puts "[Saved profiling data to '#{profile}']"
end
+if Rubinius::RUBY_CONFIG['rbx.jit_stats']
+ stats = Rubinius::VM.jit_info
+ puts "JIT time spent: #{stats[0] / 1000000}ms"
+ puts " JITed methods: #{stats[1]}"
+end
+
Process.exit(code || 0)
View
14 vm/builtin/system.cpp
@@ -131,6 +131,8 @@ namespace rubinius {
if(ent->is_number()) {
return Fixnum::from(atoi(ent->value.c_str()));
+ } else if(ent->is_true()) {
+ return Qtrue;
}
return String::create(state, ent->value.c_str());
@@ -185,4 +187,16 @@ namespace rubinius {
return Qnil;
}
+ Object* System::vm_jit_info(STATE) {
+ if(!state->config.jit_enabled) {
+ return Qnil;
+ }
+
+ Array* ary = Array::create(state, 2);
+ ary->set(state, 0, Integer::from(state, state->jit_timing));
+ ary->set(state, 1, Integer::from(state, state->jitted_methods));
+
+ return ary;
+ }
+
}
View
6 vm/builtin/system.hpp
@@ -131,6 +131,12 @@ namespace rubinius {
// Ruby.primitive :vm_write_error
static Object* vm_write_error(STATE, String* str);
+ /**
+ * Returns information about how the JIT is working.
+ */
+ // Ruby.primitive :vm_jit_info
+ static Object* vm_jit_info(STATE);
+
public: /* Type info */
View
21 vm/config.h
@@ -1,5 +1,18 @@
-// Define to use the new dynamic interpreter
-// #define USE_DYNAMIC_INTERPRETER
+#ifndef RBX_CONFIG
+#define RBX_CONFIG
-// Define to use the usage based JIT (experimental)
-// #define USE_USAGE_JIT
+#include "detection.hpp"
+
+// Currently, these are only support on x86-32
+
+#ifdef IS_X8632
+
+// Add support for the new dynamic interpreter
+#define USE_DYNAMIC_INTERPRETER
+
+// Add support for the usage based JIT (experimental)
+#define USE_USAGE_JIT
+
+#endif
+
+#endif
View
21 vm/config_parser.cpp
@@ -31,14 +31,14 @@ namespace rubinius {
char* var = strdup(line);
char* equals = strstr(var, "=");
+ // Just the variable name means true, as in enable
if(!equals) {
- free(var);
- return NULL;
+ equals = "true";
+ } else {
+ /* Split the string. */
+ *equals++ = 0;
}
- /* Split the string. */
- *equals++ = 0;
-
Entry* entry = new ConfigParser::Entry();
entry->variable = std::string(trim_str(var));
@@ -49,6 +49,13 @@ namespace rubinius {
return entry;
}
+ void ConfigParser::import_line(const char* line) {
+ ConfigParser::Entry* entry = parse_line(line);
+ if(entry) {
+ variables[entry->variable] = entry;
+ }
+ }
+
void ConfigParser::import_stream(std::istream& stream) {
while(!stream.eof()) {
std::string line;
@@ -80,6 +87,10 @@ namespace rubinius {
return rubinius::is_number(value.c_str());
}
+ bool ConfigParser::Entry::is_true() {
+ return value == "true";
+ }
+
bool ConfigParser::Entry::in_section(std::string prefix) {
return variable.find(prefix) == 0;
}
View
2  vm/config_parser.hpp
@@ -12,6 +12,7 @@ namespace rubinius {
std::string value;
bool is_number();
+ bool is_true();
bool in_section(std::string prefix);
};
@@ -23,6 +24,7 @@ namespace rubinius {
virtual ~ConfigParser();
Entry* parse_line(const char* line);
+ void import_line(const char* line);
void import_stream(std::istream&);
Entry* find(std::string variable);
EntryList* get_section(std::string prefix);
View
8 vm/detection.hpp
@@ -23,6 +23,14 @@
#define IS_X86
#endif
+#if defined(_LP64) || defined(__LP64__) || defined(__x86_64__) || defined(__amd64__)
+#define IS_X8664
+
+#elif defined(IS_X86)
+#define IS_X8632
+
+#endif
+
/** CONFIGURE */
#ifndef OS_X_ANCIENT
View
4 vm/drivers/cli.cpp
@@ -36,7 +36,7 @@ static void load_runtime_kernel(Environment& env, std::string root) {
int main(int argc, char** argv) {
Environment env;
- env.load_argv(argc, argv);
+ env.load_config_argv(argc, argv);
try {
const char* runtime = getenv("RBX_RUNTIME");
@@ -55,6 +55,8 @@ int main(int argc, char** argv) {
std::string root = std::string(runtime);
env.load_platform_conf(root);
+ env.boot_vm();
+ env.load_argv(argc, argv);
load_runtime_kernel(env, std::string(root));
View
32 vm/environment.cpp
@@ -24,7 +24,7 @@
namespace rubinius {
Environment::Environment() {
- state = new VM();
+ state = new VM(VM::default_bytes, false);
TaskProbe* probe = TaskProbe::create(state);
state->probe.set(probe->parse_env(NULL) ? probe : (TaskProbe*)Qnil);
}
@@ -37,12 +37,34 @@ namespace rubinius {
state->setup_preemption();
}
+ void Environment::load_config_argv(int argc, char** argv) {
+ for(int i=1; i < argc; i++) {
+ char* arg = argv[i];
+ if(strncmp(arg, "-X", 2) == 0) {
+ state->user_config->import_line(arg + 2);
+ continue;
+ }
+
+ if(arg[0] != '-' || strcmp(arg, "--") == 0) return;
+ }
+ }
+
void Environment::load_argv(int argc, char** argv) {
+ bool process_xflags = true;
state->set_const("ARG0", String::create(state, argv[0]));
Array* ary = Array::create(state, argc - 1);
- for(int i = 0; i < argc - 1; i++) {
- ary->set(state, i, String::create(state, argv[i + 1])->taint());
+ int which_arg = 0;
+ for(int i=1; i < argc; i++) {
+ char* arg = argv[i];
+
+ if(arg[0] != '-' || strcmp(arg, "--") == 0) {
+ process_xflags = false;
+ }
+
+ if(!process_xflags || strncmp(arg, "-X", 2) != 0) {
+ ary->set(state, which_arg++, String::create(state, arg)->taint());
+ }
}
state->set_const("ARGV", ary);
@@ -78,6 +100,10 @@ namespace rubinius {
state->user_config->import_stream(stream);
}
+ void Environment::boot_vm() {
+ state->boot();
+ }
+
void Environment::run_file(std::string file) {
if(!state->probe->nil_p()) state->probe->load_runtime(state, file);
View
2  vm/environment.hpp
@@ -15,11 +15,13 @@ namespace rubinius {
Environment();
~Environment();
+ void load_config_argv(int argc, char** argv);
void load_argv(int argc, char** argv);
void load_directory(std::string dir);
void load_platform_conf(std::string dir);
void run_file(std::string path);
void enable_preemption();
+ void boot_vm();
};
}
View
12 vm/ontology.cpp
@@ -393,13 +393,21 @@ namespace rubinius {
}
#ifdef USE_DYNAMIC_INTERPRETER
- G(rubinius)->set_const(state, "INTERPRETER", symbol("dynamic"));
+ if(config.dynamic_interpreter_enabled) {
+ G(rubinius)->set_const(state, "INTERPRETER", symbol("dynamic"));
+ } else {
+ G(rubinius)->set_const(state, "INTERPRETER", symbol("static"));
+ }
#else
G(rubinius)->set_const(state, "INTERPRETER", symbol("static"));
#endif
#ifdef USE_USAGE_JIT
- G(rubinius)->set_const(state, "JIT", symbol("usage"));
+ if(config.jit_enabled) {
+ G(rubinius)->set_const(state, "JIT", symbol("usage"));
+ } else {
+ G(rubinius)->set_const(state, "JIT", Qfalse);
+ }
#else
G(rubinius)->set_const(state, "JIT", Qfalse);
#endif
View
2  vm/test/test_config.hpp
@@ -17,8 +17,6 @@ class TestConfig : public CxxTest::TestSuite {
void test_parse_line() {
ConfigParser cfg;
- TS_ASSERT(!cfg.parse_line("blah"));
-
ConfigParser::Entry* e = cfg.parse_line("rbx.blah = 8");
TS_ASSERT_EQUALS(std::string("rbx.blah"), e->variable);
TS_ASSERT_EQUALS(std::string("8"), e->value);
View
41 vm/vm.cpp
@@ -17,6 +17,7 @@
#include "builtin/taskprobe.hpp"
#include "config_parser.hpp"
+#include "config.h"
#include <iostream>
#include <signal.h>
@@ -28,7 +29,7 @@
#define GO(whatever) globals.whatever
namespace rubinius {
- VM::VM(size_t bytes)
+ VM::VM(size_t bytes, bool boot)
: current_mark(NULL)
, reuse_llvm(true)
, jit_timing(0)
@@ -36,6 +37,8 @@ namespace rubinius {
, use_safe_position(false)
{
config.compile_up_front = false;
+ config.jit_enabled = false;
+ config.dynamic_interpreter_enabled = false;
VM::register_state(this);
@@ -44,6 +47,32 @@ namespace rubinius {
om = new ObjectMemory(this, bytes);
probe.set(Qnil, &globals.roots);
+ if(boot) this->boot();
+ }
+
+ VM::~VM() {
+ delete user_config;
+ delete om;
+ delete signal_events;
+ delete global_cache;
+#ifdef ENABLE_LLVM
+ if(!reuse_llvm) llvm_cleanup();
+#endif
+ }
+
+ void VM::boot() {
+#ifdef USE_USAGE_JIT
+ if(user_config->find("rbx.jit")) {
+ config.jit_enabled = true;
+ }
+#endif
+
+#ifdef USE_DYNAMIC_INTERPRETER
+ if(user_config->find("rbx.dyni")) {
+ config.dynamic_interpreter_enabled = true;
+ }
+#endif
+
MethodContext::initialize_cache(this);
TypeInfo::auto_learn_fields(this);
@@ -73,16 +102,6 @@ namespace rubinius {
interrupts.enable_preempt = false;
}
- VM::~VM() {
- delete user_config;
- delete om;
- delete signal_events;
- delete global_cache;
-#ifdef ENABLE_LLVM
- if(!reuse_llvm) llvm_cleanup();
-#endif
- }
-
// HACK so not thread safe or anything!
static VM* __state = NULL;
View
7 vm/vm.hpp
@@ -35,6 +35,8 @@ namespace rubinius {
struct Configuration {
bool compile_up_front;
+ bool jit_enabled;
+ bool dynamic_interpreter_enabled;
};
struct Interrupts {
@@ -109,9 +111,12 @@ namespace rubinius {
/* Inline methods */
/* Prototypes */
- VM(size_t bytes = default_bytes);
+ VM(size_t bytes = default_bytes, bool boot_now = true);
~VM();
+ // Initialize the basic objects and the execution machinery
+ void boot();
+
// Returns the current VM state object.
static VM* current_state();
View
6 vm/vmmethod.cpp
@@ -36,13 +36,11 @@ namespace rubinius {
void VMMethod::init(STATE) {
#ifdef USE_DYNAMIC_INTERPRETER
- if(getenv("DISABLE_DYN")) {
- // std::cout << "[dynamic interpreter disabled]\n";
+ if(!state->config.dynamic_interpreter_enabled) {
dynamic_interpreter = NULL;
standard_interpreter = interpreter;
return;
}
- // std::cout << "[Using dynamic interpreter]\n";
if(dynamic_interpreter == NULL) {
uint8_t* buffer = new uint8_t[1024 * 1024 * 1024];
@@ -136,7 +134,7 @@ namespace rubinius {
#ifdef USE_USAGE_JIT
// Disable JIT for large methods
- if(total < JIT_MAX_METHOD_SIZE) {
+ if(state->config.jit_enabled && total < JIT_MAX_METHOD_SIZE) {
call_count = 0;
} else {
call_count = -1;
Please sign in to comment.
Something went wrong with that request. Please try again.