Permalink
Browse files

Add support for JIT'ing primitive fallback code

We setup specializations for code with a primitive just like regular
methods, but don't replace the executor. We use the special
primitive_failed executor to check whether we have jitted versions and
run them. If we would replace the default executor, we would end up with
infinite recursion.
  • Loading branch information...
1 parent 4248d1b commit a116e68f4c9b2fcde03b053cde34a5eb3fb0dd0f @dbussink dbussink committed Feb 26, 2013
Showing with 29 additions and 14 deletions.
  1. +28 −12 vm/builtin/compiledcode.cpp
  2. +1 −2 vm/machine_code.cpp
@@ -153,13 +153,30 @@ namespace rubinius {
Object* CompiledCode::primitive_failed(STATE, CallFrame* call_frame,
Executable* exec, Module* mod, Arguments& args)
{
- if(try_as<CompiledCode>(exec)) {
- return MachineCode::execute(state, call_frame, exec, mod, args);
+ CompiledCode* code = as<CompiledCode>(exec);
+
+ Class* cls = args.recv()->lookup_begin(state);
+ int id = cls->class_id();
+
+ MachineCode* v = code->machine_code();
+
+ executor target = v->unspecialized;
+
+ for(int i = 0; i < MachineCode::cMaxSpecializations; i++) {
+ int c_id = v->specializations[i].class_id;
+ executor x = v->specializations[i].execute;
+
+ if(c_id == id && x != 0) {
+ target = x;
+ break;
+ }
}
- // TODO fix me to raise an exception
- assert(0);
- return cNil;
+ if(target) {
+ return target(state, call_frame, exec, mod, args);
+ } else {
+ return MachineCode::execute(state, call_frame, exec, mod, args);
+ }
}
void CompiledCode::specialize(STATE, TypeInfo* ti) {
@@ -242,7 +259,9 @@ namespace rubinius {
if(machine_code_->specializations[i].class_id > 0) return;
}
- execute = exec;
+ if(primitive()->nil_p()) {
+ execute = exec;
+ }
}
void CompiledCode::add_specialized(int spec_id, executor exec,
@@ -252,11 +271,6 @@ namespace rubinius {
MachineCode* v = machine_code_;
- // Must happen only on the first specialization
- if(!v->unspecialized) {
- v->unspecialized = v->fallback;
- }
-
for(int i = 0; i < MachineCode::cMaxSpecializations; i++) {
int id = v->specializations[i].class_id;
if(id == 0 || id == spec_id) {
@@ -265,7 +279,9 @@ namespace rubinius {
v->specializations[i].jit_data = rd;
v->set_execute_status(MachineCode::eJIT);
- execute = specialized_executor;
+ if(primitive()->nil_p()) {
+ execute = specialized_executor;
+ }
return;
}
}
View
@@ -92,8 +92,7 @@ namespace rubinius {
}
// Disable JIT for large methods
- if(meth->primitive()->nil_p() &&
- !state->shared().config.jit_disabled &&
+ if(!state->shared().config.jit_disabled &&
total < (size_t)state->shared().config.jit_max_method_size) {
call_count = 0;
} else {

0 comments on commit a116e68

Please sign in to comment.