src/share/vm/opto/doCall.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6987634 Sdiff src/share/vm/opto

src/share/vm/opto/doCall.cpp

Print this page
rev 1722 : [mq]: 6987634


  77     if (allow_inline)     log->print(" inline='1'");
  78     if (receiver_count >= 0) {
  79       log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);
  80       if (profile.has_receiver(1)) {
  81         log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1));
  82       }
  83     }
  84     log->end_elem();
  85   }
  86 
  87   // Special case the handling of certain common, profitable library
  88   // methods.  If these methods are replaced with specialized code,
  89   // then we return it as the inlined version of the call.
  90   // We do this before the strict f.p. check below because the
  91   // intrinsics handle strict f.p. correctly.
  92   if (allow_inline) {
  93     cg = find_intrinsic(call_method, call_is_virtual);
  94     if (cg != NULL)  return cg;
  95   }
  96 






















































  97   // Do not inline strict fp into non-strict code, or the reverse
  98   bool caller_method_is_strict = jvms->method()->is_strict();
  99   if( caller_method_is_strict ^ call_method->is_strict() ) {
 100     allow_inline = false;
 101   }
 102 
 103   // Attempt to inline...
 104   if (allow_inline) {
 105     // The profile data is only partly attributable to this caller,
 106     // scale back the call site information.
 107     float past_uses = jvms->method()->scale_count(site_count, prof_factor);
 108     // This is the number of times we expect the call code to be used.
 109     float expected_uses = past_uses;
 110 
 111     // Try inlining a bytecoded method:
 112     if (!call_is_virtual) {
 113       InlineTree* ilt;
 114       if (UseOldInlining) {
 115         ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method());
 116       } else {


 199             miss_cg = CallGenerator::for_virtual_call(call_method, vtable_index);
 200           }
 201           if (miss_cg != NULL) {
 202             if (next_hit_cg != NULL) {
 203               NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth(), jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)));
 204               // We don't need to record dependency on a receiver here and below.
 205               // Whenever we inline, the dependency is added by Parse::Parse().
 206               miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
 207             }
 208             if (miss_cg != NULL) {
 209               NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth(), jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count));
 210               cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
 211               if (cg != NULL)  return cg;
 212             }
 213           }
 214         }
 215       }
 216     }
 217   }
 218 
 219   // Do MethodHandle calls.
 220   if (call_method->is_method_handle_invoke()) {
 221     if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) {
 222       GraphKit kit(jvms);
 223       Node* n = kit.argument(0);
 224 
 225       if (n->Opcode() == Op_ConP) {
 226         const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
 227         ciObject* const_oop = oop_ptr->const_oop();
 228         ciMethodHandle* method_handle = const_oop->as_method_handle();
 229 
 230         // Set the actually called method to have access to the class
 231         // and signature in the MethodHandleCompiler.
 232         method_handle->set_callee(call_method);
 233 
 234         // Get an adapter for the MethodHandle.
 235         ciMethod* target_method = method_handle->get_method_handle_adapter();
 236 
 237         CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
 238         if (hit_cg != NULL && hit_cg->is_inline())
 239           return hit_cg;
 240       }
 241 
 242       return CallGenerator::for_direct_call(call_method);
 243     }
 244     else {
 245       // Get the MethodHandle from the CallSite.
 246       ciMethod* caller_method = jvms->method();
 247       ciBytecodeStream str(caller_method);
 248       str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
 249       ciCallSite*     call_site     = str.get_call_site();
 250       ciMethodHandle* method_handle = call_site->get_target();
 251 
 252       // Set the actually called method to have access to the class
 253       // and signature in the MethodHandleCompiler.
 254       method_handle->set_callee(call_method);
 255 
 256       // Get an adapter for the MethodHandle.
 257       ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 258 
 259       CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
 260       if (hit_cg != NULL && hit_cg->is_inline()) {
 261         CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
 262         return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
 263       }
 264 
 265       // If something failed, generate a normal dynamic call.
 266       return CallGenerator::for_dynamic_call(call_method);
 267     }
 268   }
 269 
 270   // There was no special inlining tactic, or it bailed out.
 271   // Use a more generic tactic, like a simple call.
 272   if (call_is_virtual) {
 273     return CallGenerator::for_virtual_call(call_method, vtable_index);
 274   } else {
 275     // Class Hierarchy Analysis or Type Profile reveals a unique target,
 276     // or it is a static or special call.
 277     return CallGenerator::for_direct_call(call_method, should_delay_inlining(call_method, jvms));
 278   }
 279 }
 280 
 281 // Return true for methods that shouldn't be inlined early so that
 282 // they are easier to analyze and optimize as intrinsics.
 283 bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
 284   if (has_stringbuilder()) {
 285 
 286     if ((call_method->holder() == C->env()->StringBuilder_klass() ||
 287          call_method->holder() == C->env()->StringBuffer_klass()) &&
 288         (jvms->method()->holder() == C->env()->StringBuilder_klass() ||
 289          jvms->method()->holder() == C->env()->StringBuffer_klass())) {




  77     if (allow_inline)     log->print(" inline='1'");
  78     if (receiver_count >= 0) {
  79       log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);
  80       if (profile.has_receiver(1)) {
  81         log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1));
  82       }
  83     }
  84     log->end_elem();
  85   }
  86 
  87   // Special case the handling of certain common, profitable library
  88   // methods.  If these methods are replaced with specialized code,
  89   // then we return it as the inlined version of the call.
  90   // We do this before the strict f.p. check below because the
  91   // intrinsics handle strict f.p. correctly.
  92   if (allow_inline) {
  93     cg = find_intrinsic(call_method, call_is_virtual);
  94     if (cg != NULL)  return cg;
  95   }
  96 
  97   // Do MethodHandle calls.
  98   // NOTE: This must happen before normal inlining logic below since
  99   // MethodHandle.invoke* are native methods which obviously don't
 100   // have bytecodes and so normal inlining fails.
 101   if (call_method->is_method_handle_invoke()) {
 102     if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) {
 103       GraphKit kit(jvms);
 104       Node* n = kit.argument(0);
 105 
 106       if (n->Opcode() == Op_ConP) {
 107         const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
 108         ciObject* const_oop = oop_ptr->const_oop();
 109         ciMethodHandle* method_handle = const_oop->as_method_handle();
 110 
 111         // Set the actually called method to have access to the class
 112         // and signature in the MethodHandleCompiler.
 113         method_handle->set_callee(call_method);
 114 
 115         // Get an adapter for the MethodHandle.
 116         ciMethod* target_method = method_handle->get_method_handle_adapter();
 117 
 118         CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
 119         if (hit_cg != NULL && hit_cg->is_inline())
 120           return hit_cg;
 121       }
 122 
 123       return CallGenerator::for_direct_call(call_method);
 124     }
 125     else {
 126       // Get the MethodHandle from the CallSite.
 127       ciMethod* caller_method = jvms->method();
 128       ciBytecodeStream str(caller_method);
 129       str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
 130       ciCallSite*     call_site     = str.get_call_site();
 131       ciMethodHandle* method_handle = call_site->get_target();
 132 
 133       // Set the actually called method to have access to the class
 134       // and signature in the MethodHandleCompiler.
 135       method_handle->set_callee(call_method);
 136 
 137       // Get an adapter for the MethodHandle.
 138       ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 139 
 140       CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
 141       if (hit_cg != NULL && hit_cg->is_inline()) {
 142         CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
 143         return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
 144       }
 145 
 146       // If something failed, generate a normal dynamic call.
 147       return CallGenerator::for_dynamic_call(call_method);
 148     }
 149   }
 150 
 151   // Do not inline strict fp into non-strict code, or the reverse
 152   bool caller_method_is_strict = jvms->method()->is_strict();
 153   if( caller_method_is_strict ^ call_method->is_strict() ) {
 154     allow_inline = false;
 155   }
 156 
 157   // Attempt to inline...
 158   if (allow_inline) {
 159     // The profile data is only partly attributable to this caller,
 160     // scale back the call site information.
 161     float past_uses = jvms->method()->scale_count(site_count, prof_factor);
 162     // This is the number of times we expect the call code to be used.
 163     float expected_uses = past_uses;
 164 
 165     // Try inlining a bytecoded method:
 166     if (!call_is_virtual) {
 167       InlineTree* ilt;
 168       if (UseOldInlining) {
 169         ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method());
 170       } else {


 253             miss_cg = CallGenerator::for_virtual_call(call_method, vtable_index);
 254           }
 255           if (miss_cg != NULL) {
 256             if (next_hit_cg != NULL) {
 257               NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth(), jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)));
 258               // We don't need to record dependency on a receiver here and below.
 259               // Whenever we inline, the dependency is added by Parse::Parse().
 260               miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
 261             }
 262             if (miss_cg != NULL) {
 263               NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth(), jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count));
 264               cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
 265               if (cg != NULL)  return cg;
 266             }
 267           }
 268         }
 269       }
 270     }
 271   }
 272 



















































 273   // There was no special inlining tactic, or it bailed out.
 274   // Use a more generic tactic, like a simple call.
 275   if (call_is_virtual) {
 276     return CallGenerator::for_virtual_call(call_method, vtable_index);
 277   } else {
 278     // Class Hierarchy Analysis or Type Profile reveals a unique target,
 279     // or it is a static or special call.
 280     return CallGenerator::for_direct_call(call_method, should_delay_inlining(call_method, jvms));
 281   }
 282 }
 283 
 284 // Return true for methods that shouldn't be inlined early so that
 285 // they are easier to analyze and optimize as intrinsics.
 286 bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
 287   if (has_stringbuilder()) {
 288 
 289     if ((call_method->holder() == C->env()->StringBuilder_klass() ||
 290          call_method->holder() == C->env()->StringBuffer_klass()) &&
 291         (jvms->method()->holder() == C->env()->StringBuilder_klass() ||
 292          jvms->method()->holder() == C->env()->StringBuffer_klass())) {


src/share/vm/opto/doCall.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File