Wed, 13 Jan 2010 23:05:52 -0800
6912065: final fields in objects need to support inlining optimizations for JSR 292
Reviewed-by: twisti, kvn
duke@435 | 1 | /* |
duke@435 | 2 | * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | # include "incls/_precompiled.incl" |
duke@435 | 26 | # include "incls/_compilationPolicy.cpp.incl" |
duke@435 | 27 | |
duke@435 | 28 | CompilationPolicy* CompilationPolicy::_policy; |
duke@435 | 29 | elapsedTimer CompilationPolicy::_accumulated_time; |
duke@435 | 30 | bool CompilationPolicy::_in_vm_startup; |
duke@435 | 31 | |
duke@435 | 32 | // Determine compilation policy based on command line argument |
duke@435 | 33 | void compilationPolicy_init() { |
duke@435 | 34 | CompilationPolicy::set_in_vm_startup(DelayCompilationDuringStartup); |
duke@435 | 35 | |
duke@435 | 36 | switch(CompilationPolicyChoice) { |
duke@435 | 37 | case 0: |
duke@435 | 38 | CompilationPolicy::set_policy(new SimpleCompPolicy()); |
duke@435 | 39 | break; |
duke@435 | 40 | |
duke@435 | 41 | case 1: |
duke@435 | 42 | #ifdef COMPILER2 |
duke@435 | 43 | CompilationPolicy::set_policy(new StackWalkCompPolicy()); |
duke@435 | 44 | #else |
duke@435 | 45 | Unimplemented(); |
duke@435 | 46 | #endif |
duke@435 | 47 | break; |
duke@435 | 48 | |
duke@435 | 49 | default: |
duke@435 | 50 | fatal("CompilationPolicyChoice must be in the range: [0-1]"); |
duke@435 | 51 | } |
duke@435 | 52 | } |
duke@435 | 53 | |
duke@435 | 54 | void CompilationPolicy::completed_vm_startup() { |
duke@435 | 55 | if (TraceCompilationPolicy) { |
duke@435 | 56 | tty->print("CompilationPolicy: completed vm startup.\n"); |
duke@435 | 57 | } |
duke@435 | 58 | _in_vm_startup = false; |
duke@435 | 59 | } |
duke@435 | 60 | |
duke@435 | 61 | // Returns true if m must be compiled before executing it |
duke@435 | 62 | // This is intended to force compiles for methods (usually for |
duke@435 | 63 | // debugging) that would otherwise be interpreted for some reason. |
duke@435 | 64 | bool CompilationPolicy::mustBeCompiled(methodHandle m) { |
duke@435 | 65 | if (m->has_compiled_code()) return false; // already compiled |
duke@435 | 66 | if (!canBeCompiled(m)) return false; |
duke@435 | 67 | |
duke@435 | 68 | return !UseInterpreter || // must compile all methods |
duke@435 | 69 | (UseCompiler && AlwaysCompileLoopMethods && m->has_loops()); // eagerly compile loop methods |
duke@435 | 70 | } |
duke@435 | 71 | |
duke@435 | 72 | // Returns true if m is allowed to be compiled |
duke@435 | 73 | bool CompilationPolicy::canBeCompiled(methodHandle m) { |
duke@435 | 74 | if (m->is_abstract()) return false; |
duke@435 | 75 | if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false; |
duke@435 | 76 | |
duke@435 | 77 | return !m->is_not_compilable(); |
duke@435 | 78 | } |
duke@435 | 79 | |
duke@435 | 80 | #ifndef PRODUCT |
duke@435 | 81 | void CompilationPolicy::print_time() { |
duke@435 | 82 | tty->print_cr ("Accumulated compilationPolicy times:"); |
duke@435 | 83 | tty->print_cr ("---------------------------"); |
duke@435 | 84 | tty->print_cr (" Total: %3.3f sec.", _accumulated_time.seconds()); |
duke@435 | 85 | } |
duke@435 | 86 | |
duke@435 | 87 | static void trace_osr_completion(nmethod* osr_nm) { |
duke@435 | 88 | if (TraceOnStackReplacement) { |
duke@435 | 89 | if (osr_nm == NULL) tty->print_cr("compilation failed"); |
duke@435 | 90 | else tty->print_cr("nmethod " INTPTR_FORMAT, osr_nm); |
duke@435 | 91 | } |
duke@435 | 92 | } |
duke@435 | 93 | #endif // !PRODUCT |
duke@435 | 94 | |
duke@435 | 95 | void CompilationPolicy::reset_counter_for_invocation_event(methodHandle m) { |
duke@435 | 96 | // Make sure invocation and backedge counter doesn't overflow again right away |
duke@435 | 97 | // as would be the case for native methods. |
duke@435 | 98 | |
duke@435 | 99 | // BUT also make sure the method doesn't look like it was never executed. |
duke@435 | 100 | // Set carry bit and reduce counter's value to min(count, CompileThreshold/2). |
duke@435 | 101 | m->invocation_counter()->set_carry(); |
duke@435 | 102 | m->backedge_counter()->set_carry(); |
duke@435 | 103 | |
duke@435 | 104 | assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed"); |
duke@435 | 105 | } |
duke@435 | 106 | |
duke@435 | 107 | void CompilationPolicy::reset_counter_for_back_branch_event(methodHandle m) { |
duke@435 | 108 | // Delay next back-branch event but pump up invocation counter to triger |
duke@435 | 109 | // whole method compilation. |
duke@435 | 110 | InvocationCounter* i = m->invocation_counter(); |
duke@435 | 111 | InvocationCounter* b = m->backedge_counter(); |
duke@435 | 112 | |
duke@435 | 113 | // Don't set invocation_counter's value too low otherwise the method will |
duke@435 | 114 | // look like immature (ic < ~5300) which prevents the inlining based on |
duke@435 | 115 | // the type profiling. |
duke@435 | 116 | i->set(i->state(), CompileThreshold); |
duke@435 | 117 | // Don't reset counter too low - it is used to check if OSR method is ready. |
duke@435 | 118 | b->set(b->state(), CompileThreshold / 2); |
duke@435 | 119 | } |
duke@435 | 120 | |
duke@435 | 121 | // SimpleCompPolicy - compile current method |
duke@435 | 122 | |
duke@435 | 123 | void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) { |
duke@435 | 124 | assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); |
duke@435 | 125 | |
duke@435 | 126 | int hot_count = m->invocation_count(); |
duke@435 | 127 | reset_counter_for_invocation_event(m); |
duke@435 | 128 | const char* comment = "count"; |
duke@435 | 129 | |
duke@435 | 130 | if (!delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler) { |
duke@435 | 131 | nmethod* nm = m->code(); |
duke@435 | 132 | if (nm == NULL ) { |
duke@435 | 133 | const char* comment = "count"; |
duke@435 | 134 | CompileBroker::compile_method(m, InvocationEntryBci, |
duke@435 | 135 | m, hot_count, comment, CHECK); |
duke@435 | 136 | } else { |
duke@435 | 137 | #ifdef TIERED |
duke@435 | 138 | |
duke@435 | 139 | if (nm->is_compiled_by_c1()) { |
duke@435 | 140 | const char* comment = "tier1 overflow"; |
duke@435 | 141 | CompileBroker::compile_method(m, InvocationEntryBci, |
duke@435 | 142 | m, hot_count, comment, CHECK); |
duke@435 | 143 | } |
duke@435 | 144 | #endif // TIERED |
duke@435 | 145 | } |
duke@435 | 146 | } |
duke@435 | 147 | } |
duke@435 | 148 | |
duke@435 | 149 | void SimpleCompPolicy::method_back_branch_event(methodHandle m, int branch_bci, int loop_top_bci, TRAPS) { |
duke@435 | 150 | assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); |
duke@435 | 151 | |
duke@435 | 152 | int hot_count = m->backedge_count(); |
duke@435 | 153 | const char* comment = "backedge_count"; |
duke@435 | 154 | |
duke@435 | 155 | if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m)) { |
duke@435 | 156 | CompileBroker::compile_method(m, loop_top_bci, m, hot_count, comment, CHECK); |
duke@435 | 157 | |
duke@435 | 158 | NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(loop_top_bci));) |
duke@435 | 159 | } |
duke@435 | 160 | } |
duke@435 | 161 | |
duke@435 | 162 | int SimpleCompPolicy::compilation_level(methodHandle m, int branch_bci) |
duke@435 | 163 | { |
duke@435 | 164 | #ifdef TIERED |
duke@435 | 165 | if (!TieredCompilation) { |
duke@435 | 166 | return CompLevel_highest_tier; |
duke@435 | 167 | } |
duke@435 | 168 | if (/* m()->tier1_compile_done() && */ |
duke@435 | 169 | // QQQ HACK FIX ME set tier1_compile_done!! |
duke@435 | 170 | !m()->is_native()) { |
duke@435 | 171 | // Grab the nmethod so it doesn't go away while it's being queried |
duke@435 | 172 | nmethod* code = m()->code(); |
duke@435 | 173 | if (code != NULL && code->is_compiled_by_c1()) { |
duke@435 | 174 | return CompLevel_highest_tier; |
duke@435 | 175 | } |
duke@435 | 176 | } |
duke@435 | 177 | return CompLevel_fast_compile; |
duke@435 | 178 | #else |
duke@435 | 179 | return CompLevel_highest_tier; |
duke@435 | 180 | #endif // TIERED |
duke@435 | 181 | } |
duke@435 | 182 | |
duke@435 | 183 | // StackWalkCompPolicy - walk up stack to find a suitable method to compile |
duke@435 | 184 | |
duke@435 | 185 | #ifdef COMPILER2 |
duke@435 | 186 | const char* StackWalkCompPolicy::_msg = NULL; |
duke@435 | 187 | |
duke@435 | 188 | |
duke@435 | 189 | // Consider m for compilation |
duke@435 | 190 | void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) { |
duke@435 | 191 | assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); |
duke@435 | 192 | |
duke@435 | 193 | int hot_count = m->invocation_count(); |
duke@435 | 194 | reset_counter_for_invocation_event(m); |
duke@435 | 195 | const char* comment = "count"; |
duke@435 | 196 | |
duke@435 | 197 | if (m->code() == NULL && !delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler) { |
duke@435 | 198 | ResourceMark rm(THREAD); |
duke@435 | 199 | JavaThread *thread = (JavaThread*)THREAD; |
duke@435 | 200 | frame fr = thread->last_frame(); |
duke@435 | 201 | assert(fr.is_interpreted_frame(), "must be interpreted"); |
duke@435 | 202 | assert(fr.interpreter_frame_method() == m(), "bad method"); |
duke@435 | 203 | |
duke@435 | 204 | if (TraceCompilationPolicy) { |
duke@435 | 205 | tty->print("method invocation trigger: "); |
duke@435 | 206 | m->print_short_name(tty); |
duke@435 | 207 | tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)m(), m->code_size()); |
duke@435 | 208 | } |
duke@435 | 209 | RegisterMap reg_map(thread, false); |
duke@435 | 210 | javaVFrame* triggerVF = thread->last_java_vframe(®_map); |
duke@435 | 211 | // triggerVF is the frame that triggered its counter |
duke@435 | 212 | RFrame* first = new InterpretedRFrame(triggerVF->fr(), thread, m); |
duke@435 | 213 | |
duke@435 | 214 | if (first->top_method()->code() != NULL) { |
duke@435 | 215 | // called obsolete method/nmethod -- no need to recompile |
duke@435 | 216 | if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, first->top_method()->code()); |
duke@435 | 217 | } else if (compilation_level(m, InvocationEntryBci) == CompLevel_fast_compile) { |
duke@435 | 218 | // Tier1 compilation policy avaoids stack walking. |
duke@435 | 219 | CompileBroker::compile_method(m, InvocationEntryBci, |
duke@435 | 220 | m, hot_count, comment, CHECK); |
duke@435 | 221 | } else { |
duke@435 | 222 | if (TimeCompilationPolicy) accumulated_time()->start(); |
duke@435 | 223 | GrowableArray<RFrame*>* stack = new GrowableArray<RFrame*>(50); |
duke@435 | 224 | stack->push(first); |
duke@435 | 225 | RFrame* top = findTopInlinableFrame(stack); |
duke@435 | 226 | if (TimeCompilationPolicy) accumulated_time()->stop(); |
duke@435 | 227 | assert(top != NULL, "findTopInlinableFrame returned null"); |
duke@435 | 228 | if (TraceCompilationPolicy) top->print(); |
duke@435 | 229 | CompileBroker::compile_method(top->top_method(), InvocationEntryBci, |
duke@435 | 230 | m, hot_count, comment, CHECK); |
duke@435 | 231 | } |
duke@435 | 232 | } |
duke@435 | 233 | } |
duke@435 | 234 | |
duke@435 | 235 | void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int branch_bci, int loop_top_bci, TRAPS) { |
duke@435 | 236 | assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now."); |
duke@435 | 237 | |
duke@435 | 238 | int hot_count = m->backedge_count(); |
duke@435 | 239 | const char* comment = "backedge_count"; |
duke@435 | 240 | |
duke@435 | 241 | if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m)) { |
duke@435 | 242 | CompileBroker::compile_method(m, loop_top_bci, m, hot_count, comment, CHECK); |
duke@435 | 243 | |
duke@435 | 244 | NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(loop_top_bci));) |
duke@435 | 245 | } |
duke@435 | 246 | } |
duke@435 | 247 | |
duke@435 | 248 | int StackWalkCompPolicy::compilation_level(methodHandle m, int osr_bci) |
duke@435 | 249 | { |
duke@435 | 250 | int comp_level = CompLevel_full_optimization; |
duke@435 | 251 | if (TieredCompilation && osr_bci == InvocationEntryBci) { |
duke@435 | 252 | if (CompileTheWorld) { |
duke@435 | 253 | // Under CTW, the first compile is tier1, the second tier2 |
duke@435 | 254 | if (m->highest_tier_compile() == CompLevel_none) { |
duke@435 | 255 | comp_level = CompLevel_fast_compile; |
duke@435 | 256 | } |
duke@435 | 257 | } else if (!m->has_osr_nmethod()) { |
duke@435 | 258 | // Before tier1 is done, use invocation_count + backedge_count to |
duke@435 | 259 | // compare against the threshold. After that, the counters may/will |
duke@435 | 260 | // be reset, so rely on the straight interpreter_invocation_count. |
duke@435 | 261 | if (m->highest_tier_compile() == CompLevel_initial_compile) { |
duke@435 | 262 | if (m->interpreter_invocation_count() < Tier2CompileThreshold) { |
duke@435 | 263 | comp_level = CompLevel_fast_compile; |
duke@435 | 264 | } |
duke@435 | 265 | } else if (m->invocation_count() + m->backedge_count() < |
duke@435 | 266 | Tier2CompileThreshold) { |
duke@435 | 267 | comp_level = CompLevel_fast_compile; |
duke@435 | 268 | } |
duke@435 | 269 | } |
duke@435 | 270 | |
duke@435 | 271 | } |
duke@435 | 272 | return comp_level; |
duke@435 | 273 | } |
duke@435 | 274 | |
duke@435 | 275 | |
duke@435 | 276 | RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack) { |
duke@435 | 277 | // go up the stack until finding a frame that (probably) won't be inlined |
duke@435 | 278 | // into its caller |
duke@435 | 279 | RFrame* current = stack->at(0); // current choice for stopping |
duke@435 | 280 | assert( current && !current->is_compiled(), "" ); |
duke@435 | 281 | const char* msg = NULL; |
duke@435 | 282 | |
duke@435 | 283 | while (1) { |
duke@435 | 284 | |
duke@435 | 285 | // before going up the stack further, check if doing so would get us into |
duke@435 | 286 | // compiled code |
duke@435 | 287 | RFrame* next = senderOf(current, stack); |
duke@435 | 288 | if( !next ) // No next frame up the stack? |
duke@435 | 289 | break; // Then compile with current frame |
duke@435 | 290 | |
duke@435 | 291 | methodHandle m = current->top_method(); |
duke@435 | 292 | methodHandle next_m = next->top_method(); |
duke@435 | 293 | |
duke@435 | 294 | if (TraceCompilationPolicy && Verbose) { |
duke@435 | 295 | tty->print("[caller: "); |
duke@435 | 296 | next_m->print_short_name(tty); |
duke@435 | 297 | tty->print("] "); |
duke@435 | 298 | } |
duke@435 | 299 | |
duke@435 | 300 | if( !Inline ) { // Inlining turned off |
duke@435 | 301 | msg = "Inlining turned off"; |
duke@435 | 302 | break; |
duke@435 | 303 | } |
duke@435 | 304 | if (next_m->is_not_compilable()) { // Did fail to compile this before/ |
duke@435 | 305 | msg = "caller not compilable"; |
duke@435 | 306 | break; |
duke@435 | 307 | } |
duke@435 | 308 | if (next->num() > MaxRecompilationSearchLength) { |
duke@435 | 309 | // don't go up too high when searching for recompilees |
duke@435 | 310 | msg = "don't go up any further: > MaxRecompilationSearchLength"; |
duke@435 | 311 | break; |
duke@435 | 312 | } |
duke@435 | 313 | if (next->distance() > MaxInterpretedSearchLength) { |
duke@435 | 314 | // don't go up too high when searching for recompilees |
duke@435 | 315 | msg = "don't go up any further: next > MaxInterpretedSearchLength"; |
duke@435 | 316 | break; |
duke@435 | 317 | } |
duke@435 | 318 | // Compiled frame above already decided not to inline; |
duke@435 | 319 | // do not recompile him. |
duke@435 | 320 | if (next->is_compiled()) { |
duke@435 | 321 | msg = "not going up into optimized code"; |
duke@435 | 322 | break; |
duke@435 | 323 | } |
duke@435 | 324 | |
duke@435 | 325 | // Interpreted frame above us was already compiled. Do not force |
duke@435 | 326 | // a recompile, although if the frame above us runs long enough an |
duke@435 | 327 | // OSR might still happen. |
duke@435 | 328 | if( current->is_interpreted() && next_m->has_compiled_code() ) { |
duke@435 | 329 | msg = "not going up -- already compiled caller"; |
duke@435 | 330 | break; |
duke@435 | 331 | } |
duke@435 | 332 | |
duke@435 | 333 | // Compute how frequent this call site is. We have current method 'm'. |
duke@435 | 334 | // We know next method 'next_m' is interpreted. Find the call site and |
duke@435 | 335 | // check the various invocation counts. |
duke@435 | 336 | int invcnt = 0; // Caller counts |
duke@435 | 337 | if (ProfileInterpreter) { |
duke@435 | 338 | invcnt = next_m->interpreter_invocation_count(); |
duke@435 | 339 | } |
duke@435 | 340 | int cnt = 0; // Call site counts |
duke@435 | 341 | if (ProfileInterpreter && next_m->method_data() != NULL) { |
duke@435 | 342 | ResourceMark rm; |
duke@435 | 343 | int bci = next->top_vframe()->bci(); |
duke@435 | 344 | ProfileData* data = next_m->method_data()->bci_to_data(bci); |
duke@435 | 345 | if (data != NULL && data->is_CounterData()) |
duke@435 | 346 | cnt = data->as_CounterData()->count(); |
duke@435 | 347 | } |
duke@435 | 348 | |
duke@435 | 349 | // Caller counts / call-site counts; i.e. is this call site |
duke@435 | 350 | // a hot call site for method next_m? |
duke@435 | 351 | int freq = (invcnt) ? cnt/invcnt : cnt; |
duke@435 | 352 | |
duke@435 | 353 | // Check size and frequency limits |
duke@435 | 354 | if ((msg = shouldInline(m, freq, cnt)) != NULL) { |
duke@435 | 355 | break; |
duke@435 | 356 | } |
duke@435 | 357 | // Check inlining negative tests |
duke@435 | 358 | if ((msg = shouldNotInline(m)) != NULL) { |
duke@435 | 359 | break; |
duke@435 | 360 | } |
duke@435 | 361 | |
duke@435 | 362 | |
duke@435 | 363 | // If the caller method is too big or something then we do not want to |
duke@435 | 364 | // compile it just to inline a method |
duke@435 | 365 | if (!canBeCompiled(next_m)) { |
duke@435 | 366 | msg = "caller cannot be compiled"; |
duke@435 | 367 | break; |
duke@435 | 368 | } |
duke@435 | 369 | |
duke@435 | 370 | if( next_m->name() == vmSymbols::class_initializer_name() ) { |
duke@435 | 371 | msg = "do not compile class initializer (OSR ok)"; |
duke@435 | 372 | break; |
duke@435 | 373 | } |
duke@435 | 374 | |
duke@435 | 375 | if (TraceCompilationPolicy && Verbose) { |
duke@435 | 376 | tty->print("\n\t check caller: "); |
duke@435 | 377 | next_m->print_short_name(tty); |
duke@435 | 378 | tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)next_m(), next_m->code_size()); |
duke@435 | 379 | } |
duke@435 | 380 | |
duke@435 | 381 | current = next; |
duke@435 | 382 | } |
duke@435 | 383 | |
duke@435 | 384 | assert( !current || !current->is_compiled(), "" ); |
duke@435 | 385 | |
duke@435 | 386 | if (TraceCompilationPolicy && msg) tty->print("(%s)\n", msg); |
duke@435 | 387 | |
duke@435 | 388 | return current; |
duke@435 | 389 | } |
duke@435 | 390 | |
duke@435 | 391 | RFrame* StackWalkCompPolicy::senderOf(RFrame* rf, GrowableArray<RFrame*>* stack) { |
duke@435 | 392 | RFrame* sender = rf->caller(); |
duke@435 | 393 | if (sender && sender->num() == stack->length()) stack->push(sender); |
duke@435 | 394 | return sender; |
duke@435 | 395 | } |
duke@435 | 396 | |
duke@435 | 397 | |
duke@435 | 398 | const char* StackWalkCompPolicy::shouldInline(methodHandle m, float freq, int cnt) { |
duke@435 | 399 | // Allows targeted inlining |
duke@435 | 400 | // positive filter: should send be inlined? returns NULL (--> yes) |
duke@435 | 401 | // or rejection msg |
duke@435 | 402 | int max_size = MaxInlineSize; |
duke@435 | 403 | int cost = m->code_size(); |
duke@435 | 404 | |
duke@435 | 405 | // Check for too many throws (and not too huge) |
duke@435 | 406 | if (m->interpreter_throwout_count() > InlineThrowCount && cost < InlineThrowMaxSize ) { |
duke@435 | 407 | return NULL; |
duke@435 | 408 | } |
duke@435 | 409 | |
duke@435 | 410 | // bump the max size if the call is frequent |
duke@435 | 411 | if ((freq >= InlineFrequencyRatio) || (cnt >= InlineFrequencyCount)) { |
duke@435 | 412 | if (TraceFrequencyInlining) { |
duke@435 | 413 | tty->print("(Inlined frequent method)\n"); |
duke@435 | 414 | m->print(); |
duke@435 | 415 | } |
duke@435 | 416 | max_size = FreqInlineSize; |
duke@435 | 417 | } |
duke@435 | 418 | if (cost > max_size) { |
duke@435 | 419 | return (_msg = "too big"); |
duke@435 | 420 | } |
duke@435 | 421 | return NULL; |
duke@435 | 422 | } |
duke@435 | 423 | |
duke@435 | 424 | |
duke@435 | 425 | const char* StackWalkCompPolicy::shouldNotInline(methodHandle m) { |
duke@435 | 426 | // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg |
duke@435 | 427 | if (m->is_abstract()) return (_msg = "abstract method"); |
duke@435 | 428 | // note: we allow ik->is_abstract() |
duke@435 | 429 | if (!instanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized"); |
duke@435 | 430 | if (m->is_native()) return (_msg = "native method"); |
duke@435 | 431 | nmethod* m_code = m->code(); |
duke@435 | 432 | if( m_code != NULL && m_code->instructions_size() > InlineSmallCode ) |
duke@435 | 433 | return (_msg = "already compiled into a big method"); |
duke@435 | 434 | |
duke@435 | 435 | // use frequency-based objections only for non-trivial methods |
duke@435 | 436 | if (m->code_size() <= MaxTrivialSize) return NULL; |
duke@435 | 437 | if (UseInterpreter) { // don't use counts with -Xcomp |
duke@435 | 438 | if ((m->code() == NULL) && m->was_never_executed()) return (_msg = "never executed"); |
duke@435 | 439 | if (!m->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return (_msg = "executed < MinInliningThreshold times"); |
duke@435 | 440 | } |
duke@435 | 441 | if (methodOopDesc::has_unloaded_classes_in_signature(m, JavaThread::current())) return (_msg = "unloaded signature classes"); |
duke@435 | 442 | |
duke@435 | 443 | return NULL; |
duke@435 | 444 | } |
duke@435 | 445 | |
duke@435 | 446 | |
duke@435 | 447 | |
duke@435 | 448 | #endif // COMPILER2 |