1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/compilationPolicy.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,448 @@ 1.4 +/* 1.5 + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_compilationPolicy.cpp.incl" 1.30 + 1.31 +CompilationPolicy* CompilationPolicy::_policy; 1.32 +elapsedTimer CompilationPolicy::_accumulated_time; 1.33 +bool CompilationPolicy::_in_vm_startup; 1.34 + 1.35 +// Determine compilation policy based on command line argument 1.36 +void compilationPolicy_init() { 1.37 + CompilationPolicy::set_in_vm_startup(DelayCompilationDuringStartup); 1.38 + 1.39 + switch(CompilationPolicyChoice) { 1.40 + case 0: 1.41 + CompilationPolicy::set_policy(new SimpleCompPolicy()); 1.42 + break; 1.43 + 1.44 + case 1: 1.45 +#ifdef COMPILER2 1.46 + CompilationPolicy::set_policy(new StackWalkCompPolicy()); 1.47 +#else 1.48 + Unimplemented(); 1.49 +#endif 1.50 + break; 1.51 + 1.52 + default: 1.53 + fatal("CompilationPolicyChoice must be in the range: [0-1]"); 1.54 + } 1.55 +} 1.56 + 1.57 +void CompilationPolicy::completed_vm_startup() { 1.58 + if (TraceCompilationPolicy) { 1.59 + tty->print("CompilationPolicy: completed vm startup.\n"); 1.60 + } 1.61 + _in_vm_startup = false; 1.62 +} 1.63 + 1.64 +// Returns true if m must be compiled before executing it 1.65 +// This is intended to force compiles for methods (usually for 1.66 +// debugging) that would otherwise be interpreted for some reason. 1.67 +bool CompilationPolicy::mustBeCompiled(methodHandle m) { 1.68 + if (m->has_compiled_code()) return false; // already compiled 1.69 + if (!canBeCompiled(m)) return false; 1.70 + 1.71 + return !UseInterpreter || // must compile all methods 1.72 + (UseCompiler && AlwaysCompileLoopMethods && m->has_loops()); // eagerly compile loop methods 1.73 +} 1.74 + 1.75 +// Returns true if m is allowed to be compiled 1.76 +bool CompilationPolicy::canBeCompiled(methodHandle m) { 1.77 + if (m->is_abstract()) return false; 1.78 + if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false; 1.79 + 1.80 + return !m->is_not_compilable(); 1.81 +} 1.82 + 1.83 +#ifndef PRODUCT 1.84 +void CompilationPolicy::print_time() { 1.85 + tty->print_cr ("Accumulated compilationPolicy times:"); 1.86 + tty->print_cr ("---------------------------"); 1.87 + tty->print_cr (" Total: %3.3f sec.", _accumulated_time.seconds()); 1.88 +} 1.89 + 1.90 +static void trace_osr_completion(nmethod* osr_nm) { 1.91 + if (TraceOnStackReplacement) { 1.92 + if (osr_nm == NULL) tty->print_cr("compilation failed"); 1.93 + else tty->print_cr("nmethod " INTPTR_FORMAT, osr_nm); 1.94 + } 1.95 +} 1.96 +#endif // !PRODUCT 1.97 + 1.98 +void CompilationPolicy::reset_counter_for_invocation_event(methodHandle m) { 1.99 + // Make sure invocation and backedge counter doesn't overflow again right away 1.100 + // as would be the case for native methods. 1.101 + 1.102 + // BUT also make sure the method doesn't look like it was never executed. 1.103 + // Set carry bit and reduce counter's value to min(count, CompileThreshold/2). 1.104 + m->invocation_counter()->set_carry(); 1.105 + m->backedge_counter()->set_carry(); 1.106 + 1.107 + assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed"); 1.108 +} 1.109 + 1.110 +void CompilationPolicy::reset_counter_for_back_branch_event(methodHandle m) { 1.111 + // Delay next back-branch event but pump up invocation counter to triger 1.112 + // whole method compilation. 1.113 + InvocationCounter* i = m->invocation_counter(); 1.114 + InvocationCounter* b = m->backedge_counter(); 1.115 + 1.116 + // Don't set invocation_counter's value too low otherwise the method will 1.117 + // look like immature (ic < ~5300) which prevents the inlining based on 1.118 + // the type profiling. 1.119 + i->set(i->state(), CompileThreshold); 1.120 + // Don't reset counter too low - it is used to check if OSR method is ready. 1.121 + b->set(b->state(), CompileThreshold / 2); 1.122 +} 1.123 + 1.124 +// SimpleCompPolicy - compile current method 1.125 + 1.126 +void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) { 1.127 + assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); 1.128 + 1.129 + int hot_count = m->invocation_count(); 1.130 + reset_counter_for_invocation_event(m); 1.131 + const char* comment = "count"; 1.132 + 1.133 + if (!delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler) { 1.134 + nmethod* nm = m->code(); 1.135 + if (nm == NULL ) { 1.136 + const char* comment = "count"; 1.137 + CompileBroker::compile_method(m, InvocationEntryBci, 1.138 + m, hot_count, comment, CHECK); 1.139 + } else { 1.140 +#ifdef TIERED 1.141 + 1.142 + if (nm->is_compiled_by_c1()) { 1.143 + const char* comment = "tier1 overflow"; 1.144 + CompileBroker::compile_method(m, InvocationEntryBci, 1.145 + m, hot_count, comment, CHECK); 1.146 + } 1.147 +#endif // TIERED 1.148 + } 1.149 + } 1.150 +} 1.151 + 1.152 +void SimpleCompPolicy::method_back_branch_event(methodHandle m, int branch_bci, int loop_top_bci, TRAPS) { 1.153 + assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); 1.154 + 1.155 + int hot_count = m->backedge_count(); 1.156 + const char* comment = "backedge_count"; 1.157 + 1.158 + if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m)) { 1.159 + CompileBroker::compile_method(m, loop_top_bci, m, hot_count, comment, CHECK); 1.160 + 1.161 + NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(loop_top_bci));) 1.162 + } 1.163 +} 1.164 + 1.165 +int SimpleCompPolicy::compilation_level(methodHandle m, int branch_bci) 1.166 +{ 1.167 +#ifdef TIERED 1.168 + if (!TieredCompilation) { 1.169 + return CompLevel_highest_tier; 1.170 + } 1.171 + if (/* m()->tier1_compile_done() && */ 1.172 + // QQQ HACK FIX ME set tier1_compile_done!! 1.173 + !m()->is_native()) { 1.174 + // Grab the nmethod so it doesn't go away while it's being queried 1.175 + nmethod* code = m()->code(); 1.176 + if (code != NULL && code->is_compiled_by_c1()) { 1.177 + return CompLevel_highest_tier; 1.178 + } 1.179 + } 1.180 + return CompLevel_fast_compile; 1.181 +#else 1.182 + return CompLevel_highest_tier; 1.183 +#endif // TIERED 1.184 +} 1.185 + 1.186 +// StackWalkCompPolicy - walk up stack to find a suitable method to compile 1.187 + 1.188 +#ifdef COMPILER2 1.189 +const char* StackWalkCompPolicy::_msg = NULL; 1.190 + 1.191 + 1.192 +// Consider m for compilation 1.193 +void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) { 1.194 + assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); 1.195 + 1.196 + int hot_count = m->invocation_count(); 1.197 + reset_counter_for_invocation_event(m); 1.198 + const char* comment = "count"; 1.199 + 1.200 + if (m->code() == NULL && !delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler) { 1.201 + ResourceMark rm(THREAD); 1.202 + JavaThread *thread = (JavaThread*)THREAD; 1.203 + frame fr = thread->last_frame(); 1.204 + assert(fr.is_interpreted_frame(), "must be interpreted"); 1.205 + assert(fr.interpreter_frame_method() == m(), "bad method"); 1.206 + 1.207 + if (TraceCompilationPolicy) { 1.208 + tty->print("method invocation trigger: "); 1.209 + m->print_short_name(tty); 1.210 + tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)m(), m->code_size()); 1.211 + } 1.212 + RegisterMap reg_map(thread, false); 1.213 + javaVFrame* triggerVF = thread->last_java_vframe(®_map); 1.214 + // triggerVF is the frame that triggered its counter 1.215 + RFrame* first = new InterpretedRFrame(triggerVF->fr(), thread, m); 1.216 + 1.217 + if (first->top_method()->code() != NULL) { 1.218 + // called obsolete method/nmethod -- no need to recompile 1.219 + if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, first->top_method()->code()); 1.220 + } else if (compilation_level(m, InvocationEntryBci) == CompLevel_fast_compile) { 1.221 + // Tier1 compilation policy avaoids stack walking. 1.222 + CompileBroker::compile_method(m, InvocationEntryBci, 1.223 + m, hot_count, comment, CHECK); 1.224 + } else { 1.225 + if (TimeCompilationPolicy) accumulated_time()->start(); 1.226 + GrowableArray<RFrame*>* stack = new GrowableArray<RFrame*>(50); 1.227 + stack->push(first); 1.228 + RFrame* top = findTopInlinableFrame(stack); 1.229 + if (TimeCompilationPolicy) accumulated_time()->stop(); 1.230 + assert(top != NULL, "findTopInlinableFrame returned null"); 1.231 + if (TraceCompilationPolicy) top->print(); 1.232 + CompileBroker::compile_method(top->top_method(), InvocationEntryBci, 1.233 + m, hot_count, comment, CHECK); 1.234 + } 1.235 + } 1.236 +} 1.237 + 1.238 +void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int branch_bci, int loop_top_bci, TRAPS) { 1.239 + assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); 1.240 + 1.241 + int hot_count = m->backedge_count(); 1.242 + const char* comment = "backedge_count"; 1.243 + 1.244 + if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m)) { 1.245 + CompileBroker::compile_method(m, loop_top_bci, m, hot_count, comment, CHECK); 1.246 + 1.247 + NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(loop_top_bci));) 1.248 + } 1.249 +} 1.250 + 1.251 +int StackWalkCompPolicy::compilation_level(methodHandle m, int osr_bci) 1.252 +{ 1.253 + int comp_level = CompLevel_full_optimization; 1.254 + if (TieredCompilation && osr_bci == InvocationEntryBci) { 1.255 + if (CompileTheWorld) { 1.256 + // Under CTW, the first compile is tier1, the second tier2 1.257 + if (m->highest_tier_compile() == CompLevel_none) { 1.258 + comp_level = CompLevel_fast_compile; 1.259 + } 1.260 + } else if (!m->has_osr_nmethod()) { 1.261 + // Before tier1 is done, use invocation_count + backedge_count to 1.262 + // compare against the threshold. After that, the counters may/will 1.263 + // be reset, so rely on the straight interpreter_invocation_count. 1.264 + if (m->highest_tier_compile() == CompLevel_initial_compile) { 1.265 + if (m->interpreter_invocation_count() < Tier2CompileThreshold) { 1.266 + comp_level = CompLevel_fast_compile; 1.267 + } 1.268 + } else if (m->invocation_count() + m->backedge_count() < 1.269 + Tier2CompileThreshold) { 1.270 + comp_level = CompLevel_fast_compile; 1.271 + } 1.272 + } 1.273 + 1.274 + } 1.275 + return comp_level; 1.276 +} 1.277 + 1.278 + 1.279 +RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack) { 1.280 + // go up the stack until finding a frame that (probably) won't be inlined 1.281 + // into its caller 1.282 + RFrame* current = stack->at(0); // current choice for stopping 1.283 + assert( current && !current->is_compiled(), "" ); 1.284 + const char* msg = NULL; 1.285 + 1.286 + while (1) { 1.287 + 1.288 + // before going up the stack further, check if doing so would get us into 1.289 + // compiled code 1.290 + RFrame* next = senderOf(current, stack); 1.291 + if( !next ) // No next frame up the stack? 1.292 + break; // Then compile with current frame 1.293 + 1.294 + methodHandle m = current->top_method(); 1.295 + methodHandle next_m = next->top_method(); 1.296 + 1.297 + if (TraceCompilationPolicy && Verbose) { 1.298 + tty->print("[caller: "); 1.299 + next_m->print_short_name(tty); 1.300 + tty->print("] "); 1.301 + } 1.302 + 1.303 + if( !Inline ) { // Inlining turned off 1.304 + msg = "Inlining turned off"; 1.305 + break; 1.306 + } 1.307 + if (next_m->is_not_compilable()) { // Did fail to compile this before/ 1.308 + msg = "caller not compilable"; 1.309 + break; 1.310 + } 1.311 + if (next->num() > MaxRecompilationSearchLength) { 1.312 + // don't go up too high when searching for recompilees 1.313 + msg = "don't go up any further: > MaxRecompilationSearchLength"; 1.314 + break; 1.315 + } 1.316 + if (next->distance() > MaxInterpretedSearchLength) { 1.317 + // don't go up too high when searching for recompilees 1.318 + msg = "don't go up any further: next > MaxInterpretedSearchLength"; 1.319 + break; 1.320 + } 1.321 + // Compiled frame above already decided not to inline; 1.322 + // do not recompile him. 1.323 + if (next->is_compiled()) { 1.324 + msg = "not going up into optimized code"; 1.325 + break; 1.326 + } 1.327 + 1.328 + // Interpreted frame above us was already compiled. Do not force 1.329 + // a recompile, although if the frame above us runs long enough an 1.330 + // OSR might still happen. 1.331 + if( current->is_interpreted() && next_m->has_compiled_code() ) { 1.332 + msg = "not going up -- already compiled caller"; 1.333 + break; 1.334 + } 1.335 + 1.336 + // Compute how frequent this call site is. We have current method 'm'. 1.337 + // We know next method 'next_m' is interpreted. Find the call site and 1.338 + // check the various invocation counts. 1.339 + int invcnt = 0; // Caller counts 1.340 + if (ProfileInterpreter) { 1.341 + invcnt = next_m->interpreter_invocation_count(); 1.342 + } 1.343 + int cnt = 0; // Call site counts 1.344 + if (ProfileInterpreter && next_m->method_data() != NULL) { 1.345 + ResourceMark rm; 1.346 + int bci = next->top_vframe()->bci(); 1.347 + ProfileData* data = next_m->method_data()->bci_to_data(bci); 1.348 + if (data != NULL && data->is_CounterData()) 1.349 + cnt = data->as_CounterData()->count(); 1.350 + } 1.351 + 1.352 + // Caller counts / call-site counts; i.e. is this call site 1.353 + // a hot call site for method next_m? 1.354 + int freq = (invcnt) ? cnt/invcnt : cnt; 1.355 + 1.356 + // Check size and frequency limits 1.357 + if ((msg = shouldInline(m, freq, cnt)) != NULL) { 1.358 + break; 1.359 + } 1.360 + // Check inlining negative tests 1.361 + if ((msg = shouldNotInline(m)) != NULL) { 1.362 + break; 1.363 + } 1.364 + 1.365 + 1.366 + // If the caller method is too big or something then we do not want to 1.367 + // compile it just to inline a method 1.368 + if (!canBeCompiled(next_m)) { 1.369 + msg = "caller cannot be compiled"; 1.370 + break; 1.371 + } 1.372 + 1.373 + if( next_m->name() == vmSymbols::class_initializer_name() ) { 1.374 + msg = "do not compile class initializer (OSR ok)"; 1.375 + break; 1.376 + } 1.377 + 1.378 + if (TraceCompilationPolicy && Verbose) { 1.379 + tty->print("\n\t check caller: "); 1.380 + next_m->print_short_name(tty); 1.381 + tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)next_m(), next_m->code_size()); 1.382 + } 1.383 + 1.384 + current = next; 1.385 + } 1.386 + 1.387 + assert( !current || !current->is_compiled(), "" ); 1.388 + 1.389 + if (TraceCompilationPolicy && msg) tty->print("(%s)\n", msg); 1.390 + 1.391 + return current; 1.392 +} 1.393 + 1.394 +RFrame* StackWalkCompPolicy::senderOf(RFrame* rf, GrowableArray<RFrame*>* stack) { 1.395 + RFrame* sender = rf->caller(); 1.396 + if (sender && sender->num() == stack->length()) stack->push(sender); 1.397 + return sender; 1.398 +} 1.399 + 1.400 + 1.401 +const char* StackWalkCompPolicy::shouldInline(methodHandle m, float freq, int cnt) { 1.402 + // Allows targeted inlining 1.403 + // positive filter: should send be inlined? returns NULL (--> yes) 1.404 + // or rejection msg 1.405 + int max_size = MaxInlineSize; 1.406 + int cost = m->code_size(); 1.407 + 1.408 + // Check for too many throws (and not too huge) 1.409 + if (m->interpreter_throwout_count() > InlineThrowCount && cost < InlineThrowMaxSize ) { 1.410 + return NULL; 1.411 + } 1.412 + 1.413 + // bump the max size if the call is frequent 1.414 + if ((freq >= InlineFrequencyRatio) || (cnt >= InlineFrequencyCount)) { 1.415 + if (TraceFrequencyInlining) { 1.416 + tty->print("(Inlined frequent method)\n"); 1.417 + m->print(); 1.418 + } 1.419 + max_size = FreqInlineSize; 1.420 + } 1.421 + if (cost > max_size) { 1.422 + return (_msg = "too big"); 1.423 + } 1.424 + return NULL; 1.425 +} 1.426 + 1.427 + 1.428 +const char* StackWalkCompPolicy::shouldNotInline(methodHandle m) { 1.429 + // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg 1.430 + if (m->is_abstract()) return (_msg = "abstract method"); 1.431 + // note: we allow ik->is_abstract() 1.432 + if (!instanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized"); 1.433 + if (m->is_native()) return (_msg = "native method"); 1.434 + nmethod* m_code = m->code(); 1.435 + if( m_code != NULL && m_code->instructions_size() > InlineSmallCode ) 1.436 + return (_msg = "already compiled into a big method"); 1.437 + 1.438 + // use frequency-based objections only for non-trivial methods 1.439 + if (m->code_size() <= MaxTrivialSize) return NULL; 1.440 + if (UseInterpreter) { // don't use counts with -Xcomp 1.441 + if ((m->code() == NULL) && m->was_never_executed()) return (_msg = "never executed"); 1.442 + if (!m->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return (_msg = "executed < MinInliningThreshold times"); 1.443 + } 1.444 + if (methodOopDesc::has_unloaded_classes_in_signature(m, JavaThread::current())) return (_msg = "unloaded signature classes"); 1.445 + 1.446 + return NULL; 1.447 +} 1.448 + 1.449 + 1.450 + 1.451 +#endif // COMPILER2