src/share/vm/opto/callGenerator.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7071307 Sdiff src/share/vm/opto

src/share/vm/opto/callGenerator.cpp

Print this page




 135   address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
 136                              : SharedRuntime::get_resolve_opt_virtual_call_stub();
 137 
 138   if (kit.C->log() != NULL) {
 139     kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
 140   }
 141 
 142   CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), target, method(), kit.bci());
 143   if (!is_static) {
 144     // Make an explicit receiver null_check as part of this call.
 145     // Since we share a map with the caller, his JVMS gets adjusted.
 146     kit.null_check_receiver(method());
 147     if (kit.stopped()) {
 148       // And dump it back to the caller, decorated with any exceptions:
 149       return kit.transfer_exceptions_into_jvms();
 150     }
 151     // Mark the call node as virtual, sort of:
 152     call->set_optimized_virtual(true);
 153     if (method()->is_method_handle_invoke()) {
 154       call->set_method_handle_invoke(true);
 155       kit.C->set_has_method_handle_invokes(true);
 156     }
 157   }
 158   kit.set_arguments_for_java_call(call);
 159   kit.set_edges_for_java_call(call, false, _separate_io_proj);
 160   Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
 161   kit.push_node(method()->return_type()->basic_type(), ret);
 162   _call_node = call;  // Save the call node in case we need it later
 163   return kit.transfer_exceptions_into_jvms();
 164 }
 165 
 166 //---------------------------DynamicCallGenerator-----------------------------
 167 // Internal class which handles all out-of-line invokedynamic calls.
 168 class DynamicCallGenerator : public CallGenerator {
 169 public:
 170   DynamicCallGenerator(ciMethod* method)
 171     : CallGenerator(method)
 172   {
 173   }
 174   virtual JVMState* generate(JVMState* jvms);
 175 };


 193   int index = str.get_method_index();
 194   size_t call_site_offset = cpcache->get_f1_offset(index);
 195 
 196   // Load the CallSite object from the constant pool cache.
 197   const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
 198   Node* cpcache_adr = kit.makecon(cpcache_ptr);
 199   Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset);
 200   Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
 201 
 202   // Load the target MethodHandle from the CallSite object.
 203   Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
 204   Node* target_mh = kit.make_load(kit.control(), target_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
 205 
 206   address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
 207 
 208   CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
 209   // invokedynamic is treated as an optimized invokevirtual.
 210   call->set_optimized_virtual(true);
 211   // Take extra care (in the presence of argument motion) not to trash the SP:
 212   call->set_method_handle_invoke(true);
 213   kit.C->set_has_method_handle_invokes(true);
 214 
 215   // Pass the target MethodHandle as first argument and shift the
 216   // other arguments.
 217   call->init_req(0 + TypeFunc::Parms, target_mh);
 218   uint nargs = call->method()->arg_size();
 219   for (uint i = 1; i < nargs; i++) {
 220     Node* arg = kit.argument(i - 1);
 221     call->init_req(i + TypeFunc::Parms, arg);
 222   }
 223 
 224   kit.set_edges_for_java_call(call);
 225   Node* ret = kit.set_results_for_java_call(call);
 226   kit.push_node(method()->return_type()->basic_type(), ret);
 227   return kit.transfer_exceptions_into_jvms();
 228 }
 229 
 230 //--------------------------VirtualCallGenerator------------------------------
 231 // Internal class which handles all out-of-line calls checking receiver type.
 232 class VirtualCallGenerator : public CallGenerator {
 233 private:


 704   if (method_handle->Opcode() == Op_ConP) {
 705     const TypeOopPtr* oop_ptr = method_handle->bottom_type()->is_oopptr();
 706     ciObject* const_oop = oop_ptr->const_oop();
 707     ciMethodHandle* method_handle = const_oop->as_method_handle();
 708 
 709     // Set the callee to have access to the class and signature in
 710     // the MethodHandleCompiler.
 711     method_handle->set_callee(callee);
 712     method_handle->set_caller(caller);
 713     method_handle->set_call_profile(profile);
 714 
 715     // Get an adapter for the MethodHandle.
 716     ciMethod* target_method = method_handle->get_method_handle_adapter();
 717     if (target_method != NULL) {
 718       CallGenerator* cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
 719       if (cg != NULL && cg->is_inline())
 720         return cg;
 721     }
 722   } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 &&
 723              method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) {













 724     // selectAlternative idiom merging two constant MethodHandles.
 725     // Generate a guard so that each can be inlined.  We might want to
 726     // do more inputs at later point but this gets the most common
 727     // case.



 728     const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
 729     ciObject* const_oop = oop_ptr->const_oop();
 730     ciMethodHandle* mh = const_oop->as_method_handle();
 731 
 732     CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile);
 733     CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile);
 734     if (cg1 != NULL && cg2 != NULL) {
 735       return new PredictedDynamicCallGenerator(mh, cg2, cg1, PROB_FAIR);
 736     }
 737   }
 738   return NULL;
 739 }
 740 
 741 
 742 CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms,
 743                                                        ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
 744   assert(call_site->is_constant_call_site() || call_site->is_mutable_call_site(), "must be");
 745   ciMethodHandle* method_handle = call_site->get_target();
 746 
 747   // Set the callee to have access to the class and signature in the
 748   // MethodHandleCompiler.
 749   method_handle->set_callee(callee);
 750   method_handle->set_caller(caller);
 751   method_handle->set_call_profile(profile);
 752 
 753   // Get an adapter for the MethodHandle.
 754   ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 755   if (target_method != NULL) {




 135   address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
 136                              : SharedRuntime::get_resolve_opt_virtual_call_stub();
 137 
 138   if (kit.C->log() != NULL) {
 139     kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
 140   }
 141 
 142   CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), target, method(), kit.bci());
 143   if (!is_static) {
 144     // Make an explicit receiver null_check as part of this call.
 145     // Since we share a map with the caller, his JVMS gets adjusted.
 146     kit.null_check_receiver(method());
 147     if (kit.stopped()) {
 148       // And dump it back to the caller, decorated with any exceptions:
 149       return kit.transfer_exceptions_into_jvms();
 150     }
 151     // Mark the call node as virtual, sort of:
 152     call->set_optimized_virtual(true);
 153     if (method()->is_method_handle_invoke()) {
 154       call->set_method_handle_invoke(true);

 155     }
 156   }
 157   kit.set_arguments_for_java_call(call);
 158   kit.set_edges_for_java_call(call, false, _separate_io_proj);
 159   Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
 160   kit.push_node(method()->return_type()->basic_type(), ret);
 161   _call_node = call;  // Save the call node in case we need it later
 162   return kit.transfer_exceptions_into_jvms();
 163 }
 164 
 165 //---------------------------DynamicCallGenerator-----------------------------
 166 // Internal class which handles all out-of-line invokedynamic calls.
 167 class DynamicCallGenerator : public CallGenerator {
 168 public:
 169   DynamicCallGenerator(ciMethod* method)
 170     : CallGenerator(method)
 171   {
 172   }
 173   virtual JVMState* generate(JVMState* jvms);
 174 };


 192   int index = str.get_method_index();
 193   size_t call_site_offset = cpcache->get_f1_offset(index);
 194 
 195   // Load the CallSite object from the constant pool cache.
 196   const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
 197   Node* cpcache_adr = kit.makecon(cpcache_ptr);
 198   Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset);
 199   Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
 200 
 201   // Load the target MethodHandle from the CallSite object.
 202   Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
 203   Node* target_mh = kit.make_load(kit.control(), target_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
 204 
 205   address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
 206 
 207   CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
 208   // invokedynamic is treated as an optimized invokevirtual.
 209   call->set_optimized_virtual(true);
 210   // Take extra care (in the presence of argument motion) not to trash the SP:
 211   call->set_method_handle_invoke(true);

 212 
 213   // Pass the target MethodHandle as first argument and shift the
 214   // other arguments.
 215   call->init_req(0 + TypeFunc::Parms, target_mh);
 216   uint nargs = call->method()->arg_size();
 217   for (uint i = 1; i < nargs; i++) {
 218     Node* arg = kit.argument(i - 1);
 219     call->init_req(i + TypeFunc::Parms, arg);
 220   }
 221 
 222   kit.set_edges_for_java_call(call);
 223   Node* ret = kit.set_results_for_java_call(call);
 224   kit.push_node(method()->return_type()->basic_type(), ret);
 225   return kit.transfer_exceptions_into_jvms();
 226 }
 227 
 228 //--------------------------VirtualCallGenerator------------------------------
 229 // Internal class which handles all out-of-line calls checking receiver type.
 230 class VirtualCallGenerator : public CallGenerator {
 231 private:


 702   if (method_handle->Opcode() == Op_ConP) {
 703     const TypeOopPtr* oop_ptr = method_handle->bottom_type()->is_oopptr();
 704     ciObject* const_oop = oop_ptr->const_oop();
 705     ciMethodHandle* method_handle = const_oop->as_method_handle();
 706 
 707     // Set the callee to have access to the class and signature in
 708     // the MethodHandleCompiler.
 709     method_handle->set_callee(callee);
 710     method_handle->set_caller(caller);
 711     method_handle->set_call_profile(profile);
 712 
 713     // Get an adapter for the MethodHandle.
 714     ciMethod* target_method = method_handle->get_method_handle_adapter();
 715     if (target_method != NULL) {
 716       CallGenerator* cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
 717       if (cg != NULL && cg->is_inline())
 718         return cg;
 719     }
 720   } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 &&
 721              method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) {
 722     float prob = PROB_FAIR;
 723     Node* meth_region = method_handle->in(0);
 724     if (meth_region->is_Region() &&
 725         meth_region->in(1)->is_Proj() && meth_region->in(2)->is_Proj() &&
 726         meth_region->in(1)->in(0) == meth_region->in(2)->in(0) &&
 727         meth_region->in(1)->in(0)->is_If()) {
 728       // If diamond, so grab the probability of the test to drive the inlining below
 729       prob = meth_region->in(1)->in(0)->as_If()->_prob;
 730       if (meth_region->in(1)->is_IfTrue()) {
 731         prob = 1 - prob;
 732       }
 733     }
 734 
 735     // selectAlternative idiom merging two constant MethodHandles.
 736     // Generate a guard so that each can be inlined.  We might want to
 737     // do more inputs at later point but this gets the most common
 738     // case.
 739     CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob));
 740     CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile.rescale(prob));
 741     if (cg1 != NULL && cg2 != NULL) {
 742       const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
 743       ciObject* const_oop = oop_ptr->const_oop();
 744       ciMethodHandle* mh = const_oop->as_method_handle();
 745       return new PredictedDynamicCallGenerator(mh, cg2, cg1, prob);




 746     }
 747   }
 748   return NULL;
 749 }
 750 
 751 
 752 CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms,
 753                                                        ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
 754   assert(call_site->is_constant_call_site() || call_site->is_mutable_call_site(), "must be");
 755   ciMethodHandle* method_handle = call_site->get_target();
 756 
 757   // Set the callee to have access to the class and signature in the
 758   // MethodHandleCompiler.
 759   method_handle->set_callee(callee);
 760   method_handle->set_caller(caller);
 761   method_handle->set_call_profile(profile);
 762 
 763   // Get an adapter for the MethodHandle.
 764   ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 765   if (target_method != NULL) {


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