759 }
760
761 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
762 GraphKit kit(jvms);
763 PhaseGVN& gvn = kit.gvn();
764 Compile* C = kit.C;
765 vmIntrinsics::ID iid = callee->intrinsic_id();
766 input_not_const = true;
767 switch (iid) {
768 case vmIntrinsics::_invokeBasic:
769 {
770 // Get MethodHandle receiver:
771 Node* receiver = kit.argument(0);
772 if (receiver->Opcode() == Op_ConP) {
773 input_not_const = false;
774 const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
775 ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
776 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove
777 const int vtable_index = Method::invalid_vtable_index;
778 CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, NULL, true, true);
779 assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
780 if (cg != NULL && cg->is_inline())
781 return cg;
782 }
783 }
784 break;
785
786 case vmIntrinsics::_linkToVirtual:
787 case vmIntrinsics::_linkToStatic:
788 case vmIntrinsics::_linkToSpecial:
789 case vmIntrinsics::_linkToInterface:
790 {
791 // Get MemberName argument:
792 Node* member_name = kit.argument(callee->arg_size() - 1);
793 if (member_name->Opcode() == Op_ConP) {
794 input_not_const = false;
795 const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();
796 ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
797
798 // In lamda forms we erase signature types to avoid resolving issues
799 // involving class loaders. When we optimize a method handle invoke
829 const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual);
830 const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface);
831 int vtable_index = Method::invalid_vtable_index;
832 bool call_does_dispatch = false;
833
834 ciKlass* speculative_receiver_type = NULL;
835 if (is_virtual_or_interface) {
836 ciInstanceKlass* klass = target->holder();
837 Node* receiver_node = kit.argument(0);
838 const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
839 // call_does_dispatch and vtable_index are out-parameters. They might be changed.
840 target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
841 is_virtual,
842 call_does_dispatch, vtable_index); // out-parameters
843 // We lack profiling at this call but type speculation may
844 // provide us with a type
845 speculative_receiver_type = receiver_type->speculative_type();
846 }
847
848 CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, speculative_receiver_type, true, true);
849 assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
850 if (cg != NULL && cg->is_inline())
851 return cg;
852 }
853 }
854 break;
855
856 default:
857 fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
858 break;
859 }
860 return NULL;
861 }
862
863
864 //------------------------PredictedIntrinsicGenerator------------------------------
865 // Internal class which handles all predicted Intrinsic calls.
866 class PredictedIntrinsicGenerator : public CallGenerator {
867 CallGenerator* _intrinsic;
868 CallGenerator* _cg;
869
|
759 }
760
761 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
762 GraphKit kit(jvms);
763 PhaseGVN& gvn = kit.gvn();
764 Compile* C = kit.C;
765 vmIntrinsics::ID iid = callee->intrinsic_id();
766 input_not_const = true;
767 switch (iid) {
768 case vmIntrinsics::_invokeBasic:
769 {
770 // Get MethodHandle receiver:
771 Node* receiver = kit.argument(0);
772 if (receiver->Opcode() == Op_ConP) {
773 input_not_const = false;
774 const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
775 ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
776 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove
777 const int vtable_index = Method::invalid_vtable_index;
778 CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, NULL, true, true);
779 assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
780 if (cg != NULL && cg->is_inline())
781 return cg;
782 }
783 }
784 break;
785
786 case vmIntrinsics::_linkToVirtual:
787 case vmIntrinsics::_linkToStatic:
788 case vmIntrinsics::_linkToSpecial:
789 case vmIntrinsics::_linkToInterface:
790 {
791 // Get MemberName argument:
792 Node* member_name = kit.argument(callee->arg_size() - 1);
793 if (member_name->Opcode() == Op_ConP) {
794 input_not_const = false;
795 const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();
796 ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
797
798 // In lamda forms we erase signature types to avoid resolving issues
799 // involving class loaders. When we optimize a method handle invoke
829 const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual);
830 const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface);
831 int vtable_index = Method::invalid_vtable_index;
832 bool call_does_dispatch = false;
833
834 ciKlass* speculative_receiver_type = NULL;
835 if (is_virtual_or_interface) {
836 ciInstanceKlass* klass = target->holder();
837 Node* receiver_node = kit.argument(0);
838 const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
839 // call_does_dispatch and vtable_index are out-parameters. They might be changed.
840 target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
841 is_virtual,
842 call_does_dispatch, vtable_index); // out-parameters
843 // We lack profiling at this call but type speculation may
844 // provide us with a type
845 speculative_receiver_type = receiver_type->speculative_type();
846 }
847
848 CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, speculative_receiver_type, true, true);
849 assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
850 if (cg != NULL && cg->is_inline())
851 return cg;
852 }
853 }
854 break;
855
856 default:
857 fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
858 break;
859 }
860 return NULL;
861 }
862
863
864 //------------------------PredictedIntrinsicGenerator------------------------------
865 // Internal class which handles all predicted Intrinsic calls.
866 class PredictedIntrinsicGenerator : public CallGenerator {
867 CallGenerator* _intrinsic;
868 CallGenerator* _cg;
869
|