CompiledMethod* LLVMState::find_candidate(CompiledMethod* start, CallFrame* call_frame) { if(!config_.jit_inline_generic) { return find_first_non_block(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 start; } CompiledMethod* caller = start; 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; CallFrame* next = call_frame->previous; if(!next|| cur->backend_method()->total > SMALL_METHOD_SIZE) return cur; caller = cur; call_frame = next; } return caller; }
VMMethod* LLVMState::find_candidate(VMMethod* start, CallFrame* call_frame) { VMMethod* found = start; int depth = 0; bool consider_block_parents = config_.jit_inline_blocks; // No upper call_frames or generic inlining is off, use the start. // With generic inlining off, there is no way to inline back to start, // so we don't both trying. if(!config_.jit_inline_generic) { if(!start) start = call_frame->cm->backend_method(); return find_first_non_block(call_frame); } /* std::cerr << "JIT target search:\n"; if(start) { show_method(this, start); } else { std::cerr << " <primitive>\n"; } */ VMMethod* next = call_frame->cm->backend_method(); VMMethod* parent = 0; while(depth < cInlineMaxDepth) { // show_method(this, next); // Basic requirements if(next->required_args != next->total_args || next->call_count < 200 || next->jitted()) break; // Jump to defining methods of blocks? parent = next->parent(); if(parent) { if(consider_block_parents) { // See if parent is in this call_frame chain properly.. if(CallFrame* pf = validate_block_parent(call_frame, parent)) { depth++; // Method parents are valuable, so always use them if we find them. if(!parent->parent()) { found = parent; } // show_method(this, parent, " parent!"); call_frame = pf; } } else { // We hit a block, just bail. break; } } else { found = next; } call_frame = call_frame->previous; if(!call_frame) break; next = call_frame->cm->backend_method(); depth++; } if(!found && !next->parent()) return next; return found; }