JVMState* WarmCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { Compile* C = Compile::current(); if (C->log() != NULL) { C->log()->elem("warm_call bci='%d'", jvms->bci()); } jvms = _if_cold->generate(jvms, parent_parser); if (jvms != NULL) { Node* m = jvms->map()->control(); if (m->is_CatchProj()) m = m->in(0); else m = C->top(); if (m->is_Catch()) m = m->in(0); else m = C->top(); if (m->is_Proj()) m = m->in(0); else m = C->top(); if (m->is_CallJava()) { _call_info->set_call(m->as_Call()); _call_info->set_hot_cg(_if_hot); #ifndef PRODUCT if (PrintOpto || PrintOptoInlining) { tty->print_cr("Queueing for warm inlining at bci %d:", jvms->bci()); tty->print("WCI: "); _call_info->print(); } #endif _call_info->set_heat(_call_info->compute_heat()); C->set_warm_calls(_call_info->insert_into(C->warm_calls())); } } return jvms; }
//------------------------------ok_to_inline----------------------------------- WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci, bool& should_delay) { assert(callee_method != NULL, "caller checks for optimized virtual!"); assert(!should_delay, "should be initialized to false"); #ifdef ASSERT // Make sure the incoming jvms has the same information content as me. // This means that we can eventually make this whole class AllStatic. if (jvms->caller() == NULL) { assert(_caller_jvms == NULL, "redundant instance state"); } else { assert(_caller_jvms->same_calls_as(jvms->caller()), "redundant instance state"); } assert(_method == jvms->method(), "redundant instance state"); #endif int caller_bci = jvms->bci(); ciMethod* caller_method = jvms->method(); // Do some initial checks. if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { set_msg("failed initial checks"); print_inlining(callee_method, caller_bci, caller_method, false /* !success */); return NULL; } // Do some parse checks. set_msg(check_can_parse(callee_method)); if (msg() != NULL) { print_inlining(callee_method, caller_bci, caller_method, false /* !success */); return NULL; } // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); bool success = try_to_inline(callee_method, caller_method, caller_bci, jvms, profile, &wci, should_delay); #ifndef PRODUCT if (InlineWarmCalls && (PrintOpto || C->print_inlining())) { bool cold = wci.is_cold(); bool hot = !cold && wci.is_hot(); bool old_cold = !success; if (old_cold != cold || (Verbose || WizardMode)) { if (msg() == NULL) { set_msg("OK"); } tty->print(" OldInlining= %4s : %s\n WCI=", old_cold ? "cold" : "hot", msg()); wci.print(); } } #endif if (success) { wci = *(WarmCallInfo::always_hot()); } else { wci = *(WarmCallInfo::always_cold()); } if (!InlineWarmCalls) { if (!wci.is_cold() && !wci.is_hot()) { // Do not inline the warm calls. wci = *(WarmCallInfo::always_cold()); } } if (!wci.is_cold()) { // Inline! if (msg() == NULL) { set_msg("inline (hot)"); } print_inlining(callee_method, caller_bci, caller_method, true /* success */); build_inline_tree_for_callee(callee_method, jvms, caller_bci); if (InlineWarmCalls && !wci.is_hot()) { return new (C) WarmCallInfo(wci); // copy to heap } return WarmCallInfo::always_hot(); } // Do not inline if (msg() == NULL) { set_msg("too cold to inline"); } print_inlining(callee_method, caller_bci, caller_method, false /* !success */ ); return NULL; }