CallFrame* LLVMState::find_candidate(CompiledMethod* start, CallFrame* call_frame) { if(!config_.jit_inline_generic) { return call_frame; } int depth = cInlineMaxDepth; if(!start) { start = call_frame->cm; call_frame = call_frame->previous; depth--; } if(!call_frame || start->backend_method()->total > SMALL_METHOD_SIZE) { return call_frame; } CallFrame* caller = call_frame; while(depth-- > 0) { CompiledMethod* cur = call_frame->cm; VMMethod* vmm = cur->backend_method(); /* if(call_frame->block_p() || vmm->required_args != vmm->total_args // has a splat || vmm->call_count < 200 // not called much || vmm->jitted() // already jitted || vmm->parent() // is a block ) return caller; */ if(vmm->required_args != vmm->total_args // has a splat || vmm->call_count < 200 // not called much || vmm->jitted() // already jitted || !vmm->no_inline_p() // method marked as not inlinable ) return caller; CallFrame* next = call_frame->previous; if(!next|| cur->backend_method()->total > SMALL_METHOD_SIZE) return call_frame; caller = call_frame; call_frame = next; } return caller; }
CallFrame* LLVMState::find_candidate(STATE, CompiledMethod* start, CallFrame* call_frame) { if(!config_.jit_inline_generic) { return call_frame; } int depth = cInlineMaxDepth; if(!start) rubinius::bug("null start"); if(!call_frame) rubinius::bug("null call_frame"); // if(!start) { // start = call_frame->cm; // call_frame = call_frame->previous; // depth--; // } if(debug_search) { std::cout << "> call_count: " << call_frame->cm->backend_method()->call_count << " size: " << call_frame->cm->backend_method()->total << " sends: " << call_frame->cm->backend_method()->inline_cache_count() << std::endl; call_frame->print_backtrace(state, 1); } if(start->backend_method()->total > (size_t)config_.jit_max_method_inline_size) { if(debug_search) { std::cout << "JIT: STOP. reason: trigger method isn't small: " << start->backend_method()->total << " > " << config_.jit_max_method_inline_size << std::endl; } return call_frame; } VMMethod* vmm = start->backend_method(); if(vmm->required_args != vmm->total_args) { if(debug_search) { std::cout << "JIT: STOP. reason: trigger method req_args != total_args" << std::endl; } return call_frame; } if(vmm->no_inline_p()) { if(debug_search) { std::cout << "JIT: STOP. reason: trigger method no_inline_p() = true" << std::endl; } return call_frame; } CallFrame* callee = call_frame; call_frame = call_frame->previous; if(!call_frame) return callee; // Now start looking at callers. while(depth-- > 0) { CompiledMethod* cur = call_frame->cm; if(!cur) { if(debug_search) { std::cout << "JIT: STOP. reason: synthetic CallFrame hit" << std::endl; } return callee; } VMMethod* vmm = cur->backend_method(); if(debug_search) { std::cout << "> call_count: " << vmm->call_count << " size: " << vmm->total << " sends: " << vmm->inline_cache_count() << std::endl; call_frame->print_backtrace(state, 1); } /* if(call_frame->block_p() || vmm->required_args != vmm->total_args // has a splat || vmm->call_count < 200 // not called much || vmm->jitted() // already jitted || vmm->parent() // is a block ) return callee; */ if(vmm->required_args != vmm->total_args) { if(debug_search) { std::cout << "JIT: STOP. reason: req_args != total_args" << std::endl; } return callee; } if(vmm->call_count < config_.jit_call_inline_threshold) { if(debug_search) { std::cout << "JIT: STOP. reason: call_count too small: " << vmm->call_count << " < " << config_.jit_call_inline_threshold << std::endl; } return callee; } if(vmm->jitted()) { if(debug_search) { std::cout << "JIT: STOP. reason: already jitted" << std::endl; } return callee; } if(vmm->no_inline_p()) { if(debug_search) { std::cout << "JIT: STOP. reason: no_inline_p() = true" << std::endl; } return callee; } if(vmm->inline_cache_count() > eMaxInlineSendCount) { if(debug_search) { std::cout << "JIT: STOP. reason: high send count" << std::endl; } return call_frame; } // if(vmm->required_args != vmm->total_args // has a splat // || vmm->call_count < 200 // not called much // || vmm->jitted() // already jitted // || !vmm->no_inline_p() // method marked as not inlineable // ) return callee; CallFrame* prev = call_frame->previous; if(!prev) { if(debug_search) { std::cout << "JIT: STOP. reason: toplevel method" << std::endl; } return call_frame; } // if(cur->backend_method()->total > SMALL_METHOD_SIZE) { // if(debug_search) { // std::cout << "JIT: STOP. reason: big method: " // << cur->backend_method()->total << " > " // << SMALL_METHOD_SIZE // << "\n"; // } // return call_frame; // } // if(!next || cur->backend_method()->total > SMALL_METHOD_SIZE) return call_frame; callee->cm->backend_method()->call_count = 0; callee = call_frame; call_frame = prev; } return callee; }