void CompiledCode::add_specialized(int spec_id, executor exec, jit::RuntimeDataHolder* rd) { if(!machine_code_) rubinius::bug("specializing with no backend"); MachineCode* v = machine_code_; // Must happen only on the first specialization if(!v->unspecialized) { if(execute == specialized_executor) { rubinius::bug("cant setup unspecialized from specialized"); } v->unspecialized = execute; } for(int i = 0; i < MachineCode::cMaxSpecializations; i++) { int id = v->specializations[i].class_id; if(id == 0 || id == spec_id) { v->specializations[i].class_id = spec_id; v->specializations[i].execute = exec; v->specializations[i].jit_data = rd; v->set_execute_status(MachineCode::eJIT); execute = specialized_executor; return; } } // No room for the specialization, this is bad. std::cerr << "No room for specialization!\n"; }
void CompiledCode::add_specialized(uint32_t class_id, uint32_t serial_id, executor exec, jit::RuntimeDataHolder* rd) { if(!machine_code_) rubinius::bug("specializing with no backend"); MachineCode* v = machine_code_; for(int i = 0; i < MachineCode::cMaxSpecializations; i++) { uint32_t id = v->specializations[i].class_data.f.class_id; if(id == 0 || id == class_id) { v->specializations[i].class_data.f.class_id = class_id; v->specializations[i].class_data.f.serial_id = serial_id; v->specializations[i].execute = exec; v->specializations[i].jit_data = rd; v->set_execute_status(MachineCode::eJIT); if(primitive()->nil_p()) { execute = specialized_executor; } return; } } // No room for the specialization, this is bad. std::cerr << "No room for specialization!\n"; }
void CompiledCode::add_specialized(STATE, uint32_t class_id, uint32_t serial_id, executor exec, jit::RuntimeDataHolder* rd) { if(!machine_code_) { utilities::logger::error("specializing with no backend"); return; } MachineCode* v = machine_code_; int i; for(i = 0; i < MachineCode::cMaxSpecializations; i++) { uint32_t id = v->specializations[i].class_data.f.class_id; if(id == 0 || id == class_id) break; } /* We have fixed space for specializations. If we exceed this, overwrite * the first one. This should be converted to some sort of LRU cache. */ if(i == MachineCode::cMaxSpecializations) { std::ostringstream msg; msg << "Specialization space exceeded for " << machine_code_->name()->cpp_str(state); utilities::logger::warn(msg.str().c_str()); i = 0; } v->specializations[i].class_data.f.class_id = class_id; v->specializations[i].class_data.f.serial_id = serial_id; v->specializations[i].execute = exec; v->specializations[i].jit_data = rd; v->set_execute_status(MachineCode::eJIT); if(primitive()->nil_p()) { execute = specialized_executor; } }