src/share/vm/runtime/compilationPolicy.cpp

changeset 435
a61af66fc99e
child 1609
ddb7834449d0
     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(&reg_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

mercurial