src/share/vm/opto/bytecodeInfo.cpp

changeset 476
874b2c4f43d1
parent 435
a61af66fc99e
child 631
d1605aabd0a1
child 679
524eca34ea76
     1.1 --- a/src/share/vm/opto/bytecodeInfo.cpp	Thu Mar 06 20:58:16 2008 -0800
     1.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp	Fri Mar 07 11:09:13 2008 -0800
     1.3 @@ -79,8 +79,20 @@
     1.4    for (int i = depth; i != 0; --i) tty->print("  ");
     1.5  }
     1.6  
     1.7 +static bool is_init_with_ea(ciMethod* callee_method,
     1.8 +                            ciMethod* caller_method, Compile* C) {
     1.9 +  // True when EA is ON and a java constructor is called or
    1.10 +  // a super constructor is called from an inlined java constructor.
    1.11 +  return DoEscapeAnalysis && EliminateAllocations &&
    1.12 +         ( callee_method->is_initializer() ||
    1.13 +           (caller_method->is_initializer() &&
    1.14 +            caller_method != C->method() &&
    1.15 +            caller_method->holder()->is_subclass_of(callee_method->holder()))
    1.16 +         );
    1.17 +}
    1.18 +
    1.19  // positive filter: should send be inlined?  returns NULL, if yes, or rejection msg
    1.20 -const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
    1.21 +const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
    1.22    // Allows targeted inlining
    1.23    if(callee_method->should_inline()) {
    1.24      *wci_result = *(WarmCallInfo::always_hot());
    1.25 @@ -97,7 +109,8 @@
    1.26    int size     = callee_method->code_size();
    1.27  
    1.28    // Check for too many throws (and not too huge)
    1.29 -  if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) {
    1.30 +  if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
    1.31 +     size < InlineThrowMaxSize ) {
    1.32      wci_result->set_profit(wci_result->profit() * 100);
    1.33      if (PrintInlining && Verbose) {
    1.34        print_indent(inline_depth());
    1.35 @@ -114,8 +127,12 @@
    1.36    int invoke_count     = method()->interpreter_invocation_count();
    1.37    assert( invoke_count != 0, "Require invokation count greater than zero");
    1.38    int freq = call_site_count/invoke_count;
    1.39 +
    1.40    // bump the max size if the call is frequent
    1.41 -  if ((freq >= InlineFrequencyRatio) || (call_site_count >= InlineFrequencyCount)) {
    1.42 +  if ((freq >= InlineFrequencyRatio) ||
    1.43 +      (call_site_count >= InlineFrequencyCount) ||
    1.44 +      is_init_with_ea(callee_method, caller_method, C)) {
    1.45 +
    1.46      max_size = C->freq_inline_size();
    1.47      if (size <= max_size && TraceFrequencyInlining) {
    1.48        print_indent(inline_depth());
    1.49 @@ -126,7 +143,8 @@
    1.50      }
    1.51    } else {
    1.52      // Not hot.  Check for medium-sized pre-existing nmethod at cold sites.
    1.53 -    if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode/4)
    1.54 +    if (callee_method->has_compiled_code() &&
    1.55 +        callee_method->instructions_size() > InlineSmallCode/4)
    1.56        return "already compiled into a medium method";
    1.57    }
    1.58    if (size > max_size) {
    1.59 @@ -139,7 +157,7 @@
    1.60  
    1.61  
    1.62  // negative filter: should send NOT be inlined?  returns NULL, ok to inline, or rejection msg
    1.63 -const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* wci_result) const {
    1.64 +const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
    1.65    // negative filter: should send NOT be inlined?  returns NULL (--> inline) or rejection msg
    1.66    if (!UseOldInlining) {
    1.67      const char* fail = NULL;
    1.68 @@ -204,9 +222,23 @@
    1.69  
    1.70    // use frequency-based objections only for non-trivial methods
    1.71    if (callee_method->code_size() <= MaxTrivialSize) return NULL;
    1.72 -  if (UseInterpreter && !CompileTheWorld) { // don't use counts with -Xcomp or CTW
    1.73 -    if (!callee_method->has_compiled_code() && !callee_method->was_executed_more_than(0)) return "never executed";
    1.74 -    if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return "executed < MinInliningThreshold times";
    1.75 +
    1.76 +  // don't use counts with -Xcomp or CTW
    1.77 +  if (UseInterpreter && !CompileTheWorld) {
    1.78 +
    1.79 +    if (!callee_method->has_compiled_code() &&
    1.80 +        !callee_method->was_executed_more_than(0)) {
    1.81 +      return "never executed";
    1.82 +    }
    1.83 +
    1.84 +    if (is_init_with_ea(callee_method, caller_method, C)) {
    1.85 +
    1.86 +      // Escape Analysis: inline all executed constructors
    1.87 +
    1.88 +    } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
    1.89 +                                                           CompileThreshold >> 1))) {
    1.90 +      return "executed < MinInliningThreshold times";
    1.91 +    }
    1.92    }
    1.93  
    1.94    if (callee_method->should_not_inline()) {
    1.95 @@ -219,8 +251,7 @@
    1.96  //-----------------------------try_to_inline-----------------------------------
    1.97  // return NULL if ok, reason for not inlining otherwise
    1.98  // Relocated from "InliningClosure::try_to_inline"
    1.99 -const char* InlineTree::try_to_inline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) {
   1.100 -  ciMethod* caller_method = method();
   1.101 +const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) {
   1.102  
   1.103    // Old algorithm had funny accumulating BC-size counters
   1.104    if (UseOldInlining && ClipInlining
   1.105 @@ -229,25 +260,47 @@
   1.106    }
   1.107  
   1.108    const char *msg = NULL;
   1.109 -  if ((msg = shouldInline(callee_method, caller_bci, profile, wci_result)) != NULL) return msg;
   1.110 -  if ((msg = shouldNotInline(callee_method,                   wci_result)) != NULL) return msg;
   1.111 +  if ((msg = shouldInline(callee_method, caller_method, caller_bci,
   1.112 +                          profile, wci_result)) != NULL) {
   1.113 +    return msg;
   1.114 +  }
   1.115 +  if ((msg = shouldNotInline(callee_method, caller_method,
   1.116 +                             wci_result)) != NULL) {
   1.117 +    return msg;
   1.118 +  }
   1.119  
   1.120    bool is_accessor = InlineAccessors && callee_method->is_accessor();
   1.121  
   1.122    // suppress a few checks for accessors and trivial methods
   1.123    if (!is_accessor && callee_method->code_size() > MaxTrivialSize) {
   1.124 +
   1.125      // don't inline into giant methods
   1.126 -    if (C->unique() > (uint)NodeCountInliningCutoff) return "NodeCountInliningCutoff";
   1.127 +    if (C->unique() > (uint)NodeCountInliningCutoff) {
   1.128 +      return "NodeCountInliningCutoff";
   1.129 +    }
   1.130  
   1.131 -    // don't inline unreached call sites
   1.132 -    if (profile.count() == 0)                        return "call site not reached";
   1.133 +    if ((!UseInterpreter || CompileTheWorld) &&
   1.134 +        is_init_with_ea(callee_method, caller_method, C)) {
   1.135 +
   1.136 +      // Escape Analysis stress testing when running Xcomp or CTW:
   1.137 +      // inline constructors even if they are not reached.
   1.138 +
   1.139 +    } else if (profile.count() == 0) {
   1.140 +      // don't inline unreached call sites
   1.141 +      return "call site not reached";
   1.142 +    }
   1.143    }
   1.144  
   1.145 -  if (!C->do_inlining() && InlineAccessors && !is_accessor) return "not an accessor";
   1.146 -
   1.147 -  if( inline_depth() > MaxInlineLevel )           return "inlining too deep";
   1.148 +  if (!C->do_inlining() && InlineAccessors && !is_accessor) {
   1.149 +    return "not an accessor";
   1.150 +  }
   1.151 +  if( inline_depth() > MaxInlineLevel ) {
   1.152 +    return "inlining too deep";
   1.153 +  }
   1.154    if( method() == callee_method &&
   1.155 -      inline_depth() > MaxRecursiveInlineLevel )  return "recursively inlining too deep";
   1.156 +      inline_depth() > MaxRecursiveInlineLevel ) {
   1.157 +    return "recursively inlining too deep";
   1.158 +  }
   1.159  
   1.160    int size = callee_method->code_size();
   1.161  
   1.162 @@ -336,7 +389,7 @@
   1.163  
   1.164    // Check if inlining policy says no.
   1.165    WarmCallInfo wci = *(initial_wci);
   1.166 -  failure_msg = try_to_inline(callee_method, caller_bci, profile, &wci);
   1.167 +  failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci);
   1.168    if (failure_msg != NULL && C->log() != NULL) {
   1.169      C->log()->begin_elem("inline_fail reason='");
   1.170      C->log()->text("%s", failure_msg);

mercurial