src/share/vm/opto/bytecodeInfo.cpp

changeset 5901
0c4c40f5c399
parent 5763
1b64d46620a3
child 6106
e74074c34312
     1.1 --- a/src/share/vm/opto/bytecodeInfo.cpp	Wed Oct 02 06:17:10 2013 -0700
     1.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp	Fri Oct 04 10:11:48 2013 -0700
     1.3 @@ -197,6 +197,7 @@
     1.4  // negative filter: should callee NOT be inlined?
     1.5  bool InlineTree::should_not_inline(ciMethod *callee_method,
     1.6                                     ciMethod* caller_method,
     1.7 +                                   JVMState* jvms,
     1.8                                     WarmCallInfo* wci_result) {
     1.9  
    1.10    const char* fail_msg = NULL;
    1.11 @@ -226,7 +227,7 @@
    1.12      // don't inline exception code unless the top method belongs to an
    1.13      // exception class
    1.14      if (callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
    1.15 -      ciMethod* top_method = caller_jvms() ? caller_jvms()->of_depth(1)->method() : method();
    1.16 +      ciMethod* top_method = jvms->caller() != NULL ? jvms->caller()->of_depth(1)->method() : method();
    1.17        if (!top_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
    1.18          wci_result->set_profit(wci_result->profit() * 0.1);
    1.19        }
    1.20 @@ -328,7 +329,7 @@
    1.21  // return true if ok
    1.22  // Relocated from "InliningClosure::try_to_inline"
    1.23  bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method,
    1.24 -                               int caller_bci, ciCallProfile& profile,
    1.25 +                               int caller_bci, JVMState* jvms, ciCallProfile& profile,
    1.26                                 WarmCallInfo* wci_result, bool& should_delay) {
    1.27  
    1.28     // Old algorithm had funny accumulating BC-size counters
    1.29 @@ -346,7 +347,7 @@
    1.30                       wci_result)) {
    1.31      return false;
    1.32    }
    1.33 -  if (should_not_inline(callee_method, caller_method, wci_result)) {
    1.34 +  if (should_not_inline(callee_method, caller_method, jvms, wci_result)) {
    1.35      return false;
    1.36    }
    1.37  
    1.38 @@ -397,24 +398,35 @@
    1.39    }
    1.40  
    1.41    // detect direct and indirect recursive inlining
    1.42 -  if (!callee_method->is_compiled_lambda_form()) {
    1.43 +  {
    1.44      // count the current method and the callee
    1.45 -    int inline_level = (method() == callee_method) ? 1 : 0;
    1.46 -    if (inline_level > MaxRecursiveInlineLevel) {
    1.47 -      set_msg("recursively inlining too deep");
    1.48 -      return false;
    1.49 +    const bool is_compiled_lambda_form = callee_method->is_compiled_lambda_form();
    1.50 +    int inline_level = 0;
    1.51 +    if (!is_compiled_lambda_form) {
    1.52 +      if (method() == callee_method) {
    1.53 +        inline_level++;
    1.54 +      }
    1.55      }
    1.56      // count callers of current method and callee
    1.57 -    JVMState* jvms = caller_jvms();
    1.58 -    while (jvms != NULL && jvms->has_method()) {
    1.59 -      if (jvms->method() == callee_method) {
    1.60 -        inline_level++;
    1.61 -        if (inline_level > MaxRecursiveInlineLevel) {
    1.62 -          set_msg("recursively inlining too deep");
    1.63 -          return false;
    1.64 +    Node* callee_argument0 = is_compiled_lambda_form ? jvms->map()->argument(jvms, 0)->uncast() : NULL;
    1.65 +    for (JVMState* j = jvms->caller(); j != NULL && j->has_method(); j = j->caller()) {
    1.66 +      if (j->method() == callee_method) {
    1.67 +        if (is_compiled_lambda_form) {
    1.68 +          // Since compiled lambda forms are heavily reused we allow recursive inlining.  If it is truly
    1.69 +          // a recursion (using the same "receiver") we limit inlining otherwise we can easily blow the
    1.70 +          // compiler stack.
    1.71 +          Node* caller_argument0 = j->map()->argument(j, 0)->uncast();
    1.72 +          if (caller_argument0 == callee_argument0) {
    1.73 +            inline_level++;
    1.74 +          }
    1.75 +        } else {
    1.76 +          inline_level++;
    1.77          }
    1.78        }
    1.79 -      jvms = jvms->caller();
    1.80 +    }
    1.81 +    if (inline_level > MaxRecursiveInlineLevel) {
    1.82 +      set_msg("recursive inlining is too deep");
    1.83 +      return false;
    1.84      }
    1.85    }
    1.86  
    1.87 @@ -536,7 +548,7 @@
    1.88    // Check if inlining policy says no.
    1.89    WarmCallInfo wci = *(initial_wci);
    1.90    bool success = try_to_inline(callee_method, caller_method, caller_bci,
    1.91 -                               profile, &wci, should_delay);
    1.92 +                               jvms, profile, &wci, should_delay);
    1.93  
    1.94  #ifndef PRODUCT
    1.95    if (UseOldInlining && InlineWarmCalls

mercurial