src/share/vm/opto/doCall.cpp

Print this page
rev 3904 : 8005071: Incremental inlining for JSR 292
Summary: post parse inlining driven by number of live nodes.
Reviewed-by:


  46     if (!PrintInlining) {
  47       if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
  48         method->print_short_name();
  49         tty->cr();
  50       }
  51       CompileTask::print_inlining(prof_method, depth, bci);
  52     } else {
  53       out = C->print_inlining_stream();
  54     }
  55     CompileTask::print_inline_indent(depth, out);
  56     out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
  57     stringStream ss;
  58     prof_klass->name()->print_symbol_on(&ss);
  59     out->print(ss.as_string());
  60     out->cr();
  61   }
  62 }
  63 
  64 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual,
  65                                        JVMState* jvms, bool allow_inline,
  66                                        float prof_factor, bool allow_intrinsics) {
  67   ciMethod*       caller   = jvms->method();
  68   int             bci      = jvms->bci();
  69   Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
  70   guarantee(callee != NULL, "failed method resolution");
  71 
  72   // Dtrace currently doesn't work unless all calls are vanilla
  73   if (env()->dtrace_method_probes()) {
  74     allow_inline = false;
  75   }
  76 
  77   // Note: When we get profiling during stage-1 compiles, we want to pull
  78   // from more specific profile data which pertains to this inlining.
  79   // Right now, ignore the information in jvms->caller(), and do method[bci].
  80   ciCallProfile profile = caller->call_profile_at_bci(bci);
  81 
  82   // See how many times this site has been invoked.
  83   int site_count = profile.count();
  84   int receiver_count = -1;
  85   if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) {
  86     // Receivers in the profile structure are ordered by call counts


 113   if (allow_inline && allow_intrinsics) {
 114     CallGenerator* cg = find_intrinsic(callee, call_is_virtual);
 115     if (cg != NULL) {
 116       if (cg->is_predicted()) {
 117         // Code without intrinsic but, hopefully, inlined.
 118         CallGenerator* inline_cg = this->call_generator(callee,
 119               vtable_index, call_is_virtual, jvms, allow_inline, prof_factor, false);
 120         if (inline_cg != NULL) {
 121           cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
 122         }
 123       }
 124       return cg;
 125     }
 126   }
 127 
 128   // Do method handle calls.
 129   // NOTE: This must happen before normal inlining logic below since
 130   // MethodHandle.invoke* are native methods which obviously don't
 131   // have bytecodes and so normal inlining fails.
 132   if (callee->is_method_handle_intrinsic()) {
 133     return CallGenerator::for_method_handle_call(jvms, caller, callee);


 134   }
 135 
 136   // Do not inline strict fp into non-strict code, or the reverse
 137   if (caller->is_strict() ^ callee->is_strict()) {
 138     allow_inline = false;
 139   }
 140 
 141   // Attempt to inline...
 142   if (allow_inline) {
 143     // The profile data is only partly attributable to this caller,
 144     // scale back the call site information.
 145     float past_uses = jvms->method()->scale_count(site_count, prof_factor);
 146     // This is the number of times we expect the call code to be used.
 147     float expected_uses = past_uses;
 148 
 149     // Try inlining a bytecoded method:
 150     if (!call_is_virtual) {
 151       InlineTree* ilt;
 152       if (UseOldInlining) {
 153         ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method());
 154       } else {
 155         // Make a disembodied, stateless ILT.
 156         // TO DO:  When UseOldInlining is removed, copy the ILT code elsewhere.
 157         float site_invoke_ratio = prof_factor;
 158         // Note:  ilt is for the root of this parse, not the present call site.
 159         ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio, MaxInlineLevel);
 160       }
 161       WarmCallInfo scratch_ci;
 162       if (!UseOldInlining)
 163         scratch_ci.init(jvms, callee, profile, prof_factor);
 164       WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci);

 165       assert(ci != &scratch_ci, "do not let this pointer escape");
 166       bool allow_inline   = (ci != NULL && !ci->is_cold());
 167       bool require_inline = (allow_inline && ci->is_hot());
 168 
 169       if (allow_inline) {
 170         CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses);
 171         if (require_inline && cg != NULL && should_delay_inlining(callee, jvms)) {

 172           // Delay the inlining of this method to give us the
 173           // opportunity to perform some high level optimizations
 174           // first.




 175           return CallGenerator::for_late_inline(callee, cg);
 176         }
 177         if (cg == NULL) {

 178           // Fall through.
 179         } else if (require_inline || !InlineWarmCalls) {
 180           return cg;
 181         } else {
 182           CallGenerator* cold_cg = call_generator(callee, vtable_index, call_is_virtual, jvms, false, prof_factor);
 183           return CallGenerator::for_warm_call(ci, cold_cg, cg);
 184         }
 185       }
 186     }
 187 
 188     // Try using the type profile.
 189     if (call_is_virtual && site_count > 0 && receiver_count > 0) {
 190       // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count.
 191       bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent);
 192       ciMethod* receiver_method = NULL;
 193       if (have_major_receiver || profile.morphism() == 1 ||
 194           (profile.morphism() == 2 && UseBimorphicInlining)) {
 195         // receiver_method = profile.method();
 196         // Profiles do not suggest methods now.  Look it up in the major receiver.
 197         receiver_method = callee->resolve_invoke(jvms->method()->holder(),




  46     if (!PrintInlining) {
  47       if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
  48         method->print_short_name();
  49         tty->cr();
  50       }
  51       CompileTask::print_inlining(prof_method, depth, bci);
  52     } else {
  53       out = C->print_inlining_stream();
  54     }
  55     CompileTask::print_inline_indent(depth, out);
  56     out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
  57     stringStream ss;
  58     prof_klass->name()->print_symbol_on(&ss);
  59     out->print(ss.as_string());
  60     out->cr();
  61   }
  62 }
  63 
  64 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual,
  65                                        JVMState* jvms, bool allow_inline,
  66                                        float prof_factor, bool allow_intrinsics, bool delayed_forbidden) {
  67   ciMethod*       caller   = jvms->method();
  68   int             bci      = jvms->bci();
  69   Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
  70   guarantee(callee != NULL, "failed method resolution");
  71 
  72   // Dtrace currently doesn't work unless all calls are vanilla
  73   if (env()->dtrace_method_probes()) {
  74     allow_inline = false;
  75   }
  76 
  77   // Note: When we get profiling during stage-1 compiles, we want to pull
  78   // from more specific profile data which pertains to this inlining.
  79   // Right now, ignore the information in jvms->caller(), and do method[bci].
  80   ciCallProfile profile = caller->call_profile_at_bci(bci);
  81 
  82   // See how many times this site has been invoked.
  83   int site_count = profile.count();
  84   int receiver_count = -1;
  85   if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) {
  86     // Receivers in the profile structure are ordered by call counts


 113   if (allow_inline && allow_intrinsics) {
 114     CallGenerator* cg = find_intrinsic(callee, call_is_virtual);
 115     if (cg != NULL) {
 116       if (cg->is_predicted()) {
 117         // Code without intrinsic but, hopefully, inlined.
 118         CallGenerator* inline_cg = this->call_generator(callee,
 119               vtable_index, call_is_virtual, jvms, allow_inline, prof_factor, false);
 120         if (inline_cg != NULL) {
 121           cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
 122         }
 123       }
 124       return cg;
 125     }
 126   }
 127 
 128   // Do method handle calls.
 129   // NOTE: This must happen before normal inlining logic below since
 130   // MethodHandle.invoke* are native methods which obviously don't
 131   // have bytecodes and so normal inlining fails.
 132   if (callee->is_method_handle_intrinsic()) {
 133     CallGenerator* cg = CallGenerator::for_method_handle_call(jvms, caller, callee, delayed_forbidden);
 134     assert (cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator");
 135     return cg;
 136   }
 137 
 138   // Do not inline strict fp into non-strict code, or the reverse
 139   if (caller->is_strict() ^ callee->is_strict()) {
 140     allow_inline = false;
 141   }
 142 
 143   // Attempt to inline...
 144   if (allow_inline) {
 145     // The profile data is only partly attributable to this caller,
 146     // scale back the call site information.
 147     float past_uses = jvms->method()->scale_count(site_count, prof_factor);
 148     // This is the number of times we expect the call code to be used.
 149     float expected_uses = past_uses;
 150 
 151     // Try inlining a bytecoded method:
 152     if (!call_is_virtual) {
 153       InlineTree* ilt;
 154       if (UseOldInlining) {
 155         ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method());
 156       } else {
 157         // Make a disembodied, stateless ILT.
 158         // TO DO:  When UseOldInlining is removed, copy the ILT code elsewhere.
 159         float site_invoke_ratio = prof_factor;
 160         // Note:  ilt is for the root of this parse, not the present call site.
 161         ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio, MaxInlineLevel);
 162       }
 163       WarmCallInfo scratch_ci;
 164       if (!UseOldInlining)
 165         scratch_ci.init(jvms, callee, profile, prof_factor);
 166       bool should_delay = false;
 167       WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci, should_delay);
 168       assert(ci != &scratch_ci, "do not let this pointer escape");
 169       bool allow_inline   = (ci != NULL && !ci->is_cold());
 170       bool require_inline = (allow_inline && ci->is_hot());
 171 
 172       if (allow_inline) {
 173         CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses);
 174 
 175         if (require_inline && cg != NULL) {
 176           // Delay the inlining of this method to give us the
 177           // opportunity to perform some high level optimizations
 178           // first.
 179           if (should_delay_inlining(callee, jvms)) {
 180             assert(!delayed_forbidden, "strange");
 181             return CallGenerator::for_string_late_inline(callee, cg);
 182           } else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) {
 183             return CallGenerator::for_late_inline(callee, cg);
 184           }
 185         }
 186         if (cg == NULL || should_delay) {
 187           // Fall through.
 188         } else if (require_inline || !InlineWarmCalls) {
 189           return cg;
 190         } else {
 191           CallGenerator* cold_cg = call_generator(callee, vtable_index, call_is_virtual, jvms, false, prof_factor);
 192           return CallGenerator::for_warm_call(ci, cold_cg, cg);
 193         }
 194       }
 195     }
 196 
 197     // Try using the type profile.
 198     if (call_is_virtual && site_count > 0 && receiver_count > 0) {
 199       // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count.
 200       bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent);
 201       ciMethod* receiver_method = NULL;
 202       if (have_major_receiver || profile.morphism() == 1 ||
 203           (profile.morphism() == 2 && UseBimorphicInlining)) {
 204         // receiver_method = profile.method();
 205         // Profiles do not suggest methods now.  Look it up in the major receiver.
 206         receiver_method = callee->resolve_invoke(jvms->method()->holder(),