void LLVMState::compile_callframe(STATE, GCToken gct, CompiledCode* start, CallFrame* call_frame, int primitive) { // TODO: Fix compile policy checks if(!start->keywords()->nil_p()) { metrics().m.jit_metrics.methods_failed++; return; } if(debug_search) { std::cout << std::endl << "JIT: triggered: " << enclosure_name(start) << "#" << symbol_debug_str(start->name()) << std::endl; } CallFrame* candidate = find_candidate(state, start, call_frame); if(!candidate || candidate->jitted_p() || candidate->inline_method_p()) { if(config().jit_show_compiling) { llvm::outs() << "[[[ JIT error finding call frame " << enclosure_name(start) << "#" << symbol_debug_str(start->name()); if(!candidate) { llvm::outs() << " no candidate"; } else { if(candidate->jitted_p()) { llvm::outs() << " candidate is jitted"; } if(candidate->inline_method_p()) { llvm::outs() << " candidate is inlined"; } } llvm::outs() << " ]]]\n"; } return; } if(debug_search) { std::cout << "! "; candidate->print_backtrace(state, 1); } if(candidate->compiled_code->machine_code()->call_count <= 1) { if(!start || start->machine_code()->jitted_p()) return; // Ignore it. compile this one. candidate = call_frame; } if(candidate->block_p()) { compile_soon(state, gct, candidate->compiled_code, call_frame, candidate->self()->direct_class(state), candidate->block_env(), true); } else { if(candidate->compiled_code->can_specialize_p()) { compile_soon(state, gct, candidate->compiled_code, call_frame, candidate->self()->direct_class(state)); } else { compile_soon(state, gct, candidate->compiled_code, call_frame, NULL); } } }
void LLVMState::compile_callframe(STATE, CompiledMethod* start, CallFrame* call_frame, int primitive) { if(debug_search) { std::cout << std::endl << "JIT: triggered: " << enclosure_name(start) << "#" << symbol_debug_str(start->name()) << std::endl; } // if(config().jit_inline_debug) { // if(start) { // std::cout << "JIT: target search from " // << symbol_debug_str(start->name()) << "\n"; // } else { // std::cout << "JIT: target search from primitive\n"; // } // } CallFrame* candidate = find_candidate(state, start, call_frame); if(!candidate || candidate->jitted_p() || candidate->inline_method_p()) { if(debug_search) { std::cout << "JIT: invalid candidate returned" << std::endl; } return; } if(debug_search) { std::cout << "! "; candidate->print_backtrace(state, 1); } if(start && candidate->cm != start) { start->backend_method()->call_count = 0; } if(candidate->cm->backend_method()->call_count <= 1) { if(!start || start->backend_method()->jitted()) return; // Ignore it. compile this one. candidate = call_frame; } if(candidate->block_p()) { compile_soon(state, candidate->cm, candidate->block_env(), true); } else { if(candidate->cm->can_specialize_p()) { compile_soon(state, candidate->cm, candidate->self()->class_object(state)); } else { compile_soon(state, candidate->cm, cNil); } } }
virtual void read(Output& output) { GlobalLock::LockGuard guard(shared_.global_lock()); output.ok("value"); output.e().write_tuple(shared_.call_frame_locations().size()); for(CallFrameLocationList::iterator i = shared_.call_frame_locations().begin(); i != shared_.call_frame_locations().end(); i++) { CallFrame* loc = *(*i); std::ostringstream ss; loc->print_backtrace(state_, ss); output.e().write_binary(ss.str().c_str()); } }
bool QueryAgent::process_commands(int client) { bert::IOReader reader(client); bert::Decoder<bert::IOReader> decoder(reader); bert::IOWriter writer(client); bert::Encoder<bert::IOWriter> encoder(writer); int ver = decoder.read_version(); if(ver != 131) return false; bert::Value* val = decoder.next_value(); if(!val || reader.eof_p()) return false; encoder.write_version(); if(val->type() == bert::Tuple) { bert::Value* cmd = val->get_element(0); if(cmd->equal_atom("uname")) { struct utsname name; if(uname(&name)) { encoder.write_atom("error"); return true; } else { encoder.write_tuple(5); encoder.write_binary(name.sysname); encoder.write_binary(name.nodename); encoder.write_binary(name.release); encoder.write_binary(name.version); encoder.write_binary(name.machine); return true; } } else if(cmd->equal_atom("set_config")) { if(val->elements()->size() == 3) { bert::Value* key = val->get_element(1); bert::Value* value = val->get_element(2); if(key->type() == bert::Binary && value->type() == bert::Binary) { if(shared_.config.import(key->string(), value->string())) { encoder.write_atom("ok"); } else { encoder.write_atom("unknown_key"); } return true; } } encoder.write_atom("error"); return true; } else if(cmd->equal_atom("get_config")) { if(val->elements()->size() == 2) { bert::Value* key = val->get_element(1); if(key->type() == bert::Binary) { if(config::ConfigItem* item = shared_.config.find(key->string())) { std::stringstream ss; item->print_value(ss); encoder.write_tuple(2); encoder.write_atom("ok"); if(config::Integer* i = dynamic_cast<config::Integer*>(item)) { encoder.write_integer(i->value); } else { encoder.write_binary(ss.str().c_str()); } } else { encoder.write_atom("unknown_key"); } return true; } } encoder.write_atom("error"); return true; } else if(cmd->equal_atom("backtrace")) { if(verbose_) { std::cerr << "[QA: Gathering backtraces, pausing threads]\n"; } encoder.write_tuple(2); encoder.write_atom("ok"); { GlobalLock::LockGuard guard(shared_.global_lock()); encoder.write_tuple(shared_.call_frame_locations().size()); for(CallFrameLocationList::iterator i = shared_.call_frame_locations().begin(); i != shared_.call_frame_locations().end(); i++) { CallFrame* loc = *(*i); std::ostringstream ss; loc->print_backtrace(state_, ss); encoder.write_binary(ss.str().c_str()); } } if(verbose_) { std::cerr << "[QA: Threads restarted]\n"; } } return true; } else if(val->equal_atom("close")) { encoder.write_atom("bye"); return false; } encoder.write_atom("unknown"); return true; }