686 // The returned method is never abstract. |
686 // The returned method is never abstract. |
687 // Note: If caller uses a non-null result, it must inform dependencies |
687 // Note: If caller uses a non-null result, it must inform dependencies |
688 // via assert_unique_concrete_method or assert_leaf_type. |
688 // via assert_unique_concrete_method or assert_leaf_type. |
689 ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller, |
689 ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller, |
690 ciInstanceKlass* callee_holder, |
690 ciInstanceKlass* callee_holder, |
691 ciInstanceKlass* actual_recv) { |
691 ciInstanceKlass* actual_recv, |
|
692 bool check_access) { |
692 check_is_loaded(); |
693 check_is_loaded(); |
693 |
694 |
694 if (actual_recv->is_interface()) { |
695 if (actual_recv->is_interface()) { |
695 // %%% We cannot trust interface types, yet. See bug 6312651. |
696 // %%% We cannot trust interface types, yet. See bug 6312651. |
696 return NULL; |
697 return NULL; |
697 } |
698 } |
698 |
699 |
699 ciMethod* root_m = resolve_invoke(caller, actual_recv); |
700 ciMethod* root_m = resolve_invoke(caller, actual_recv, check_access); |
700 if (root_m == NULL) { |
701 if (root_m == NULL) { |
701 // Something went wrong looking up the actual receiver method. |
702 // Something went wrong looking up the actual receiver method. |
702 return NULL; |
703 return NULL; |
703 } |
704 } |
704 assert(!root_m->is_abstract(), "resolve_invoke promise"); |
705 assert(!root_m->is_abstract(), "resolve_invoke promise"); |
773 // ------------------------------------------------------------------ |
774 // ------------------------------------------------------------------ |
774 // ciMethod::resolve_invoke |
775 // ciMethod::resolve_invoke |
775 // |
776 // |
776 // Given a known receiver klass, find the target for the call. |
777 // Given a known receiver klass, find the target for the call. |
777 // Return NULL if the call has no target or the target is abstract. |
778 // Return NULL if the call has no target or the target is abstract. |
778 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) { |
779 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access) { |
779 check_is_loaded(); |
780 check_is_loaded(); |
780 VM_ENTRY_MARK; |
781 VM_ENTRY_MARK; |
781 |
782 |
782 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
783 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
783 KlassHandle h_recv (THREAD, exact_receiver->get_Klass()); |
784 KlassHandle h_recv (THREAD, exact_receiver->get_Klass()); |
790 // the vtable has not been setup, and the LinkResolver will fail. |
791 // the vtable has not been setup, and the LinkResolver will fail. |
791 if (h_recv->oop_is_array() |
792 if (h_recv->oop_is_array() |
792 || |
793 || |
793 InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { |
794 InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { |
794 if (holder()->is_interface()) { |
795 if (holder()->is_interface()) { |
795 m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); |
796 m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access); |
796 } else { |
797 } else { |
797 m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); |
798 m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access); |
798 } |
799 } |
799 } |
800 } |
800 |
801 |
801 if (m.is_null()) { |
802 if (m.is_null()) { |
802 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) |
803 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) |