1 /* |
1 /* |
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
781 // Return NULL if the call has no target or the target is abstract. |
781 // Return NULL if the call has no target or the target is abstract. |
782 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access) { |
782 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access) { |
783 check_is_loaded(); |
783 check_is_loaded(); |
784 VM_ENTRY_MARK; |
784 VM_ENTRY_MARK; |
785 |
785 |
786 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
786 Klass* caller_klass = caller->get_Klass(); |
787 KlassHandle h_recv (THREAD, exact_receiver->get_Klass()); |
787 Klass* recv = exact_receiver->get_Klass(); |
788 KlassHandle h_resolved (THREAD, holder()->get_Klass()); |
788 Klass* resolved = holder()->get_Klass(); |
789 Symbol* h_name = name()->get_symbol(); |
789 Symbol* h_name = name()->get_symbol(); |
790 Symbol* h_signature = signature()->get_symbol(); |
790 Symbol* h_signature = signature()->get_symbol(); |
791 |
791 |
792 LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, |
792 LinkInfo link_info(resolved, h_name, h_signature, caller_klass, |
793 check_access ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); |
793 check_access ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); |
794 methodHandle m; |
794 methodHandle m; |
795 // Only do exact lookup if receiver klass has been linked. Otherwise, |
795 // Only do exact lookup if receiver klass has been linked. Otherwise, |
796 // the vtable has not been setup, and the LinkResolver will fail. |
796 // the vtable has not been setup, and the LinkResolver will fail. |
797 if (h_recv->is_array_klass() |
797 if (recv->is_array_klass() |
798 || |
798 || |
799 InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { |
799 InstanceKlass::cast(recv)->is_linked() && !exact_receiver->is_interface()) { |
800 if (holder()->is_interface()) { |
800 if (holder()->is_interface()) { |
801 m = LinkResolver::resolve_interface_call_or_null(h_recv, link_info); |
801 m = LinkResolver::resolve_interface_call_or_null(recv, link_info); |
802 } else { |
802 } else { |
803 m = LinkResolver::resolve_virtual_call_or_null(h_recv, link_info); |
803 m = LinkResolver::resolve_virtual_call_or_null(recv, link_info); |
804 } |
804 } |
805 } |
805 } |
806 |
806 |
807 if (m.is_null()) { |
807 if (m.is_null()) { |
808 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) |
808 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) |
837 if (!receiver->is_interface() |
837 if (!receiver->is_interface() |
838 && (!receiver->is_instance_klass() || |
838 && (!receiver->is_instance_klass() || |
839 receiver->as_instance_klass()->is_linked())) { |
839 receiver->as_instance_klass()->is_linked())) { |
840 VM_ENTRY_MARK; |
840 VM_ENTRY_MARK; |
841 |
841 |
842 KlassHandle caller_klass (THREAD, caller->get_Klass()); |
842 Klass* caller_klass = caller->get_Klass(); |
843 KlassHandle h_recv (THREAD, receiver->get_Klass()); |
843 Klass* recv = receiver->get_Klass(); |
844 Symbol* h_name = name()->get_symbol(); |
844 Symbol* h_name = name()->get_symbol(); |
845 Symbol* h_signature = signature()->get_symbol(); |
845 Symbol* h_signature = signature()->get_symbol(); |
846 |
846 |
847 LinkInfo link_info(h_recv, h_name, h_signature, caller_klass); |
847 LinkInfo link_info(recv, h_name, h_signature, caller_klass); |
848 vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, link_info); |
848 vtable_index = LinkResolver::resolve_virtual_vtable_index(recv, link_info); |
849 if (vtable_index == Method::nonvirtual_vtable_index) { |
849 if (vtable_index == Method::nonvirtual_vtable_index) { |
850 // A statically bound method. Return "no such index". |
850 // A statically bound method. Return "no such index". |
851 vtable_index = Method::invalid_vtable_index; |
851 vtable_index = Method::invalid_vtable_index; |
852 } |
852 } |
853 } |
853 } |