1.1 --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Jul 01 10:35:54 2011 -0700 1.2 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Jul 01 10:37:37 2011 -0700 1.3 @@ -171,7 +171,7 @@ 1.4 // If a method has been stale for some time, remove it from the queue. 1.5 if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { 1.6 if (PrintTieredEvents) { 1.7 - print_event(KILL, method, method, task->osr_bci(), (CompLevel)task->comp_level()); 1.8 + print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); 1.9 } 1.10 CompileTaskWrapper ctw(task); // Frees the task 1.11 compile_queue->remove(task); 1.12 @@ -192,7 +192,7 @@ 1.13 if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) { 1.14 max_task->set_comp_level(CompLevel_limited_profile); 1.15 if (PrintTieredEvents) { 1.16 - print_event(UPDATE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); 1.17 + print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); 1.18 } 1.19 } 1.20 1.21 @@ -259,6 +259,17 @@ 1.22 return false; 1.23 } 1.24 1.25 +// Inlining control: if we're compiling a profiled method with C1 and the callee 1.26 +// is known to have OSRed in a C2 version, don't inline it. 1.27 +bool AdvancedThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) { 1.28 + CompLevel comp_level = (CompLevel)env->comp_level(); 1.29 + if (comp_level == CompLevel_full_profile || 1.30 + comp_level == CompLevel_limited_profile) { 1.31 + return callee->highest_osr_comp_level() == CompLevel_full_optimization; 1.32 + } 1.33 + return false; 1.34 +} 1.35 + 1.36 // Create MDO if necessary. 1.37 void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) { 1.38 if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; 1.39 @@ -420,10 +431,9 @@ 1.40 CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD); 1.41 } 1.42 1.43 - 1.44 // Handle the invocation event. 1.45 void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, 1.46 - CompLevel level, TRAPS) { 1.47 + CompLevel level, nmethod* nm, TRAPS) { 1.48 if (should_create_mdo(mh(), level)) { 1.49 create_mdo(mh, THREAD); 1.50 } 1.51 @@ -438,32 +448,81 @@ 1.52 // Handle the back branch event. Notice that we can compile the method 1.53 // with a regular entry from here. 1.54 void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, 1.55 - int bci, CompLevel level, TRAPS) { 1.56 + int bci, CompLevel level, nmethod* nm, TRAPS) { 1.57 if (should_create_mdo(mh(), level)) { 1.58 create_mdo(mh, THREAD); 1.59 } 1.60 + // Check if MDO should be created for the inlined method 1.61 + if (should_create_mdo(imh(), level)) { 1.62 + create_mdo(imh, THREAD); 1.63 + } 1.64 1.65 - // If the method is already compiling, quickly bail out. 1.66 - if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) { 1.67 - // Use loop event as an opportinity to also check there's been 1.68 - // enough calls. 1.69 - CompLevel cur_level = comp_level(mh()); 1.70 - CompLevel next_level = call_event(mh(), cur_level); 1.71 - CompLevel next_osr_level = loop_event(mh(), level); 1.72 + if (is_compilation_enabled()) { 1.73 + CompLevel next_osr_level = loop_event(imh(), level); 1.74 + CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level(); 1.75 if (next_osr_level == CompLevel_limited_profile) { 1.76 next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods. 1.77 } 1.78 - next_level = MAX2(next_level, 1.79 - next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level); 1.80 - bool is_compiling = false; 1.81 - if (next_level != cur_level) { 1.82 - compile(mh, InvocationEntryBci, next_level, THREAD); 1.83 - is_compiling = true; 1.84 + 1.85 + // At the very least compile the OSR version 1.86 + if (!CompileBroker::compilation_is_in_queue(imh, bci)) { 1.87 + // Check if there's a method like that already 1.88 + nmethod* osr_nm = NULL; 1.89 + if (max_osr_level >= next_osr_level) { 1.90 + // There is an osr method already with the same 1.91 + // or greater level, check if it has the bci we need 1.92 + osr_nm = imh->lookup_osr_nmethod_for(bci, next_osr_level, false); 1.93 + } 1.94 + if (osr_nm == NULL) { 1.95 + compile(imh, bci, next_osr_level, THREAD); 1.96 + } 1.97 } 1.98 1.99 - // Do the OSR version 1.100 - if (!is_compiling && next_osr_level != level) { 1.101 - compile(mh, bci, next_osr_level, THREAD); 1.102 + // Use loop event as an opportunity to also check if there's been 1.103 + // enough calls. 1.104 + CompLevel cur_level, next_level; 1.105 + if (mh() != imh()) { // If there is an enclosing method 1.106 + guarantee(nm != NULL, "Should have nmethod here"); 1.107 + cur_level = comp_level(mh()); 1.108 + next_level = call_event(mh(), cur_level); 1.109 + 1.110 + if (max_osr_level == CompLevel_full_optimization) { 1.111 + // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts 1.112 + bool make_not_entrant = false; 1.113 + if (nm->is_osr_method()) { 1.114 + // This is an osr method, just make it not entrant and recompile later if needed 1.115 + make_not_entrant = true; 1.116 + } else { 1.117 + if (next_level != CompLevel_full_optimization) { 1.118 + // next_level is not full opt, so we need to recompile the 1.119 + // enclosing method without the inlinee 1.120 + cur_level = CompLevel_none; 1.121 + make_not_entrant = true; 1.122 + } 1.123 + } 1.124 + if (make_not_entrant) { 1.125 + if (PrintTieredEvents) { 1.126 + int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci; 1.127 + print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level); 1.128 + } 1.129 + nm->make_not_entrant(); 1.130 + } 1.131 + } 1.132 + if (!CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { 1.133 + // Fix up next_level if necessary to avoid deopts 1.134 + if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) { 1.135 + next_level = CompLevel_full_profile; 1.136 + } 1.137 + if (cur_level != next_level) { 1.138 + compile(mh, InvocationEntryBci, next_level, THREAD); 1.139 + } 1.140 + } 1.141 + } else { 1.142 + cur_level = comp_level(imh()); 1.143 + next_level = call_event(imh(), cur_level); 1.144 + if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) { 1.145 + compile(imh, InvocationEntryBci, next_level, THREAD); 1.146 + } 1.147 } 1.148 } 1.149 }