< prev index next >

src/share/vm/opto/callGenerator.cpp

Print this page
rev 12109 : 8167656: Unstable MethodHandle inlining causing huge performance variations
Summary: Don't forbid inlining of method handles without type profile
Reviewed-by:


 813 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
 814   GraphKit kit(jvms);
 815   PhaseGVN& gvn = kit.gvn();
 816   Compile* C = kit.C;
 817   vmIntrinsics::ID iid = callee->intrinsic_id();
 818   input_not_const = true;
 819   switch (iid) {
 820   case vmIntrinsics::_invokeBasic:
 821     {
 822       // Get MethodHandle receiver:
 823       Node* receiver = kit.argument(0);
 824       if (receiver->Opcode() == Op_ConP) {
 825         input_not_const = false;
 826         const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
 827         ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
 828         const int vtable_index = Method::invalid_vtable_index;
 829         CallGenerator* cg = C->call_generator(target, vtable_index,
 830                                               false /* call_does_dispatch */,
 831                                               jvms,
 832                                               true /* allow_inline */,

 833                                               PROB_ALWAYS);
 834         return cg;
 835       } else {
 836         const char* msg = "receiver not constant";
 837         if (PrintInlining)  C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
 838         C->log_inline_failure(msg);
 839       }
 840     }
 841     break;
 842 
 843   case vmIntrinsics::_linkToVirtual:
 844   case vmIntrinsics::_linkToStatic:
 845   case vmIntrinsics::_linkToSpecial:
 846   case vmIntrinsics::_linkToInterface:
 847     {
 848       // Get MemberName argument:
 849       Node* member_name = kit.argument(callee->arg_size() - 1);
 850       if (member_name->Opcode() == Op_ConP) {
 851         input_not_const = false;
 852         const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();


 891 
 892         ciKlass* speculative_receiver_type = NULL;
 893         if (is_virtual_or_interface) {
 894           ciInstanceKlass* klass = target->holder();
 895           Node*             receiver_node = kit.argument(0);
 896           const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
 897           // call_does_dispatch and vtable_index are out-parameters.  They might be changed.
 898           // optimize_virtual_call() takes 2 different holder
 899           // arguments for a corner case that doesn't apply here (see
 900           // Parse::do_call())
 901           target = C->optimize_virtual_call(caller, jvms->bci(), klass, klass,
 902                                             target, receiver_type, is_virtual,
 903                                             call_does_dispatch, vtable_index, // out-parameters
 904                                             false /* check_access */);
 905           // We lack profiling at this call but type speculation may
 906           // provide us with a type
 907           speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL;
 908         }
 909         CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms,
 910                                               true /* allow_inline */,

 911                                               PROB_ALWAYS,
 912                                               speculative_receiver_type);
 913         return cg;
 914       } else {
 915         const char* msg = "member_name not constant";
 916         if (PrintInlining)  C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
 917         C->log_inline_failure(msg);
 918       }
 919     }
 920     break;
 921 
 922   default:
 923     fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 924     break;
 925   }
 926   return NULL;
 927 }
 928 
 929 
 930 //------------------------PredicatedIntrinsicGenerator------------------------------




 813 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
 814   GraphKit kit(jvms);
 815   PhaseGVN& gvn = kit.gvn();
 816   Compile* C = kit.C;
 817   vmIntrinsics::ID iid = callee->intrinsic_id();
 818   input_not_const = true;
 819   switch (iid) {
 820   case vmIntrinsics::_invokeBasic:
 821     {
 822       // Get MethodHandle receiver:
 823       Node* receiver = kit.argument(0);
 824       if (receiver->Opcode() == Op_ConP) {
 825         input_not_const = false;
 826         const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
 827         ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
 828         const int vtable_index = Method::invalid_vtable_index;
 829         CallGenerator* cg = C->call_generator(target, vtable_index,
 830                                               false /* call_does_dispatch */,
 831                                               jvms,
 832                                               true /* allow_inline */,
 833                                               true /* is_mh_inline */,
 834                                               PROB_ALWAYS);
 835         return cg;
 836       } else {
 837         const char* msg = "receiver not constant";
 838         if (PrintInlining)  C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
 839         C->log_inline_failure(msg);
 840       }
 841     }
 842     break;
 843 
 844   case vmIntrinsics::_linkToVirtual:
 845   case vmIntrinsics::_linkToStatic:
 846   case vmIntrinsics::_linkToSpecial:
 847   case vmIntrinsics::_linkToInterface:
 848     {
 849       // Get MemberName argument:
 850       Node* member_name = kit.argument(callee->arg_size() - 1);
 851       if (member_name->Opcode() == Op_ConP) {
 852         input_not_const = false;
 853         const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();


 892 
 893         ciKlass* speculative_receiver_type = NULL;
 894         if (is_virtual_or_interface) {
 895           ciInstanceKlass* klass = target->holder();
 896           Node*             receiver_node = kit.argument(0);
 897           const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
 898           // call_does_dispatch and vtable_index are out-parameters.  They might be changed.
 899           // optimize_virtual_call() takes 2 different holder
 900           // arguments for a corner case that doesn't apply here (see
 901           // Parse::do_call())
 902           target = C->optimize_virtual_call(caller, jvms->bci(), klass, klass,
 903                                             target, receiver_type, is_virtual,
 904                                             call_does_dispatch, vtable_index, // out-parameters
 905                                             false /* check_access */);
 906           // We lack profiling at this call but type speculation may
 907           // provide us with a type
 908           speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL;
 909         }
 910         CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms,
 911                                               true /* allow_inline */,
 912                                               true /* is_mh_inline */,
 913                                               PROB_ALWAYS,
 914                                               speculative_receiver_type);
 915         return cg;
 916       } else {
 917         const char* msg = "member_name not constant";
 918         if (PrintInlining)  C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
 919         C->log_inline_failure(msg);
 920       }
 921     }
 922     break;
 923 
 924   default:
 925     fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 926     break;
 927   }
 928   return NULL;
 929 }
 930 
 931 
 932 //------------------------PredicatedIntrinsicGenerator------------------------------


< prev index next >