src/share/vm/runtime/advancedThresholdPolicy.cpp

changeset 2988
2c359f27615c
parent 2987
6f6e91603a45
child 3035
43f9d800f276
     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  }

mercurial