--- old/src/share/vm/classfile/classLoader.cpp Mon Jul 18 08:07:36 2011 +++ new/src/share/vm/classfile/classLoader.cpp Mon Jul 18 08:07:35 2011 @@ -1350,13 +1350,13 @@ _codecache_sweep_counter = 0; } // Force compilation - CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_initial_compile, + CompileBroker::compile_method(m, InvocationEntryBci, CompilationPolicy::policy()->initial_compile_level(), methodHandle(), 0, "CTW", THREAD); if (HAS_PENDING_EXCEPTION) { clear_pending_exception_if_not_oom(CHECK); tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string()); } - if (TieredCompilation) { + if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) { // Clobber the first compile and force second tier compilation nmethod* nm = m->code(); if (nm != NULL) { --- old/src/share/vm/interpreter/linkResolver.cpp Mon Jul 18 08:07:37 2011 +++ new/src/share/vm/interpreter/linkResolver.cpp Mon Jul 18 08:07:37 2011 @@ -132,7 +132,7 @@ return; } CompileBroker::compile_method(selected_method, InvocationEntryBci, - CompLevel_initial_compile, + CompilationPolicy::policy()->initial_compile_level(), methodHandle(), 0, "must_be_compiled", CHECK); } } --- old/src/share/vm/prims/methodHandles.cpp Mon Jul 18 08:07:38 2011 +++ new/src/share/vm/prims/methodHandles.cpp Mon Jul 18 08:07:38 2011 @@ -1016,7 +1016,7 @@ && CompilationPolicy::can_be_compiled(m)) { // Force compilation CompileBroker::compile_method(m, InvocationEntryBci, - CompLevel_initial_compile, + CompilationPolicy::policy()->initial_compile_level(), methodHandle(), 0, "MethodHandleNatives.getTarget", CHECK_NULL); } @@ -2713,7 +2713,7 @@ && CompilationPolicy::can_be_compiled(m)) { // Force compilation CompileBroker::compile_method(m, InvocationEntryBci, - CompLevel_initial_compile, + CompilationPolicy::policy()->initial_compile_level(), methodHandle(), 0, "StressMethodHandleWalk", CHECK); } --- old/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Jul 18 08:07:39 2011 +++ new/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Jul 18 08:07:39 2011 @@ -189,7 +189,8 @@ task = next_task; } - if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) { + if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile + && is_method_profiled(max_method)) { max_task->set_comp_level(CompLevel_limited_profile); if (PrintTieredEvents) { print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); @@ -321,77 +322,79 @@ */ // 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 AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level, bool disable_feedback) { 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; + if (is_trivial(method)) { + next_level = CompLevel_simple; + } else { + 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, disable_feedback) == 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 (!disable_feedback && 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; + 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 (disable_feedback || (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; } - } 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)) { + 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; } - } else { - next_level = CompLevel_full_optimization; } } + break; } - break; } - return next_level; + return MIN2(next_level, (CompLevel)TieredStopAtLevel); } // 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 = MIN2((CompLevel) method->highest_osr_comp_level(), - common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level)); + common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); 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 @@ -406,13 +409,12 @@ } else { next_level = MAX2(osr_level, next_level); } - return next_level; } // Determine if we should do an OSR compilation of a given method. CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { - CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level); + CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); if (cur_level == CompLevel_none) { // If there is a live OSR method that means that we deopted to the interpreter // for the transition. @@ -460,22 +462,9 @@ if (is_compilation_enabled()) { CompLevel next_osr_level = loop_event(imh(), level); CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level(); - if (next_osr_level == CompLevel_limited_profile) { - next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods. - } - // At the very least compile the OSR version - if (!CompileBroker::compilation_is_in_queue(imh, bci)) { - // Check if there's a method like that already - nmethod* osr_nm = NULL; - if (max_osr_level >= next_osr_level) { - // There is an osr method already with the same - // or greater level, check if it has the bci we need - osr_nm = imh->lookup_osr_nmethod_for(bci, next_osr_level, false); - } - if (osr_nm == NULL) { - compile(imh, bci, next_osr_level, THREAD); - } + if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_osr_level != level) { + compile(imh, bci, next_osr_level, THREAD); } // Use loop event as an opportunity to also check if there's been --- old/src/share/vm/runtime/advancedThresholdPolicy.hpp Mon Jul 18 08:07:40 2011 +++ new/src/share/vm/runtime/advancedThresholdPolicy.hpp Mon Jul 18 08:07:40 2011 @@ -168,7 +168,7 @@ bool call_predicate(int i, int b, CompLevel cur_level); bool loop_predicate(int i, int b, CompLevel cur_level); // Common transition function. Given a predicate determines if a method should transition to another level. - CompLevel common(Predicate p, methodOop method, CompLevel cur_level); + CompLevel common(Predicate p, methodOop method, CompLevel cur_level, bool disable_feedback = false); // Transition functions. // call_event determines if a method should be compiled at a different // level with a regular invocation entry. --- old/src/share/vm/runtime/compilationPolicy.hpp Mon Jul 18 08:07:41 2011 +++ new/src/share/vm/runtime/compilationPolicy.hpp Mon Jul 18 08:07:41 2011 @@ -59,6 +59,8 @@ // Profiling elapsedTimer* accumulated_time() { return &_accumulated_time; } void print_time() PRODUCT_RETURN; + // Return initial compile level that is used with Xcomp + virtual CompLevel initial_compile_level() = 0; virtual int compiler_count(CompLevel comp_level) = 0; // main notification entry, return a pointer to an nmethod if the OSR is required, // returns NULL otherwise. @@ -94,6 +96,7 @@ void reset_counter_for_back_branch_event(methodHandle method); public: NonTieredCompPolicy() : _compiler_count(0) { } + virtual CompLevel initial_compile_level() { return CompLevel_initial_compile; } virtual int compiler_count(CompLevel comp_level); virtual void do_safepoint_work(); virtual void reprofile(ScopeDesc* trap_scope, bool is_osr); --- old/src/share/vm/runtime/javaCalls.cpp Mon Jul 18 08:07:43 2011 +++ new/src/share/vm/runtime/javaCalls.cpp Mon Jul 18 08:07:42 2011 @@ -355,7 +355,7 @@ assert(!thread->is_Compiler_thread(), "cannot compile from the compiler"); if (CompilationPolicy::must_be_compiled(method)) { CompileBroker::compile_method(method, InvocationEntryBci, - CompLevel_initial_compile, + CompilationPolicy::policy()->initial_compile_level(), methodHandle(), 0, "must_be_compiled", CHECK); } --- old/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Jul 18 08:07:44 2011 +++ new/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Jul 18 08:07:43 2011 @@ -206,11 +206,7 @@ // Check if the method can be compiled, change level if necessary void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, TRAPS) { - // Take the given ceiling into the account. - // NOTE: You can set it to 1 to get a pure C1 version. - if ((CompLevel)TieredStopAtLevel < level) { - level = (CompLevel)TieredStopAtLevel; - } + assert(level <= TieredStopAtLevel, "Invalid compilation level"); if (level == CompLevel_none) { return; } @@ -227,10 +223,10 @@ if (bci != InvocationEntryBci && mh->is_not_osr_compilable()) { return; } - if (PrintTieredEvents) { - print_event(COMPILE, mh, mh, bci, level); - } if (!CompileBroker::compilation_is_in_queue(mh, bci)) { + if (PrintTieredEvents) { + print_event(COMPILE, mh, mh, bci, level); + } submit_compile(mh, bci, level, THREAD); } } @@ -288,40 +284,42 @@ // Common transition function. Given a predicate determines if a method should transition to another level. CompLevel SimpleThresholdPolicy::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)) { - next_level = CompLevel_full_profile; - } - break; - case CompLevel_limited_profile: - 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)) { + if (is_trivial(method)) { + next_level = CompLevel_simple; + } else { + 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)) { + next_level = CompLevel_full_profile; + } + break; + case CompLevel_limited_profile: + 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; } - } else { - next_level = CompLevel_full_optimization; } } + break; } - break; } - return next_level; + return MIN2(next_level, (CompLevel)TieredStopAtLevel); } // Determine if a method should be compiled with a normal entry point at a different level. --- old/src/share/vm/runtime/simpleThresholdPolicy.hpp Mon Jul 18 08:07:45 2011 +++ new/src/share/vm/runtime/simpleThresholdPolicy.hpp Mon Jul 18 08:07:45 2011 @@ -98,6 +98,7 @@ if (is_c2_compile(comp_level)) return c2_count(); return 0; } + virtual CompLevel initial_compile_level() { return MIN2((CompLevel)TieredStopAtLevel, CompLevel_initial_compile); } virtual void do_safepoint_work() { } virtual void delay_compilation(methodOop method) { } virtual void disable_compilation(methodOop method) { }