void collect_profiled_methods(methodOop m) { methodHandle mh(Thread::current(), m); if ((m->method_data() != NULL) && (PrintMethodData || CompilerOracle::should_print(mh))) { collected_profiled_methods->push(m); } }
// Is method profiled enough? bool AdvancedThresholdPolicy::is_method_profiled(methodOop method) { methodDataOop mdo = method->method_data(); if (mdo != NULL) { int i = mdo->invocation_count_delta(); int b = mdo->backedge_count_delta(); return call_predicate_helper<CompLevel_full_profile>(i, b, 1); } return false; }
// Simple methods are as good being compiled with C1 as C2. // Determine if a given method is such a case. bool SimpleThresholdPolicy::is_trivial(methodOop method) { if (method->is_accessor()) return true; if (method->code() != NULL) { methodDataOop mdo = method->method_data(); if (mdo != NULL && mdo->num_loops() == 0 && (method->code_size() < 5 || (mdo->num_blocks() < 4) && (method->code_size() < 15))) { return !mdo->would_profile(); } } return false; }
bool NonTieredCompPolicy::is_mature(methodOop method) { methodDataOop mdo = method->method_data(); assert(mdo != NULL, "Should be"); uint current = mdo->mileage_of(method); uint initial = mdo->creation_mileage(); if (current < initial) return true; // some sort of overflow uint target; if (ProfileMaturityPercentage <= 0) target = (uint) -ProfileMaturityPercentage; // absolute value else target = (uint)( (ProfileMaturityPercentage * CompileThreshold) / 100 ); return (current >= initial + target); }
// Determine if a method should be compiled with a normal entry point at a different level. CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { CompLevel osr_level = (CompLevel) method->highest_osr_comp_level(); CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); // If OSR method level is greater than the regular method level, the levels should be // equalized by raising the regular method level in order to avoid OSRs during each // invocation of the method. if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { methodDataOop mdo = method->method_data(); guarantee(mdo != NULL, "MDO should not be NULL"); if (mdo->invocation_count() >= 1) { next_level = CompLevel_full_optimization; } } else { next_level = MAX2(osr_level, next_level); } return next_level; }
// Common transition function. Given a predicate determines if a method should transition to another level. CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) { if (is_trivial(method)) return CompLevel_simple; CompLevel next_level = cur_level; int i = method->invocation_count(); int b = method->backedge_count(); switch(cur_level) { case CompLevel_none: // If we were at full profile level, would we switch to full opt? if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) { next_level = CompLevel_full_optimization; } else if ((this->*p)(i, b, cur_level)) { // C1-generated fully profiled code is about 30% slower than the limited profile // code that has only invocation and backedge counters. The observation is that // if C2 queue is large enough we can spend too much time in the fully profiled code // while waiting for C2 to pick the method from the queue. To alleviate this problem // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long // we choose to compile a limited profiled version and then recompile with full profiling // when the load on C2 goes down. if (CompileBroker::queue_size(CompLevel_full_optimization) > Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { next_level = CompLevel_limited_profile; } else { next_level = CompLevel_full_profile; } } break; case CompLevel_limited_profile: if (is_method_profiled(method)) { // Special case: we got here because this method was fully profiled in the interpreter. next_level = CompLevel_full_optimization; } else { methodDataOop mdo = method->method_data(); if (mdo != NULL) { if (mdo->would_profile()) { if (CompileBroker::queue_size(CompLevel_full_optimization) <= Tier3DelayOff * compiler_count(CompLevel_full_optimization) && (this->*p)(i, b, cur_level)) { next_level = CompLevel_full_profile; } } else { next_level = CompLevel_full_optimization; } } } break; case CompLevel_full_profile: { methodDataOop mdo = method->method_data(); if (mdo != NULL) { if (mdo->would_profile()) { int mdo_i = mdo->invocation_count_delta(); int mdo_b = mdo->backedge_count_delta(); if ((this->*p)(mdo_i, mdo_b, cur_level)) { next_level = CompLevel_full_optimization; } } else { next_level = CompLevel_full_optimization; } } } break; } return next_level; }