1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
231 case direct_call: kindstr = "direct"; break;
232 case vtable_call: kindstr = "vtable"; break;
233 case itable_call: kindstr = "itable"; break;
234 }
235 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
236 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
237 }
238 #endif
239
240 //------------------------------------------------------------------------------------------------------------------------
241 // Implementation of LinkInfo
242
243 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
244 // resolve klass
245 Klass* result = pool->klass_ref_at(index, CHECK);
246 _resolved_klass = KlassHandle(THREAD, result);
247
248 // Get name, signature, and static klass
249 _name = pool->name_ref_at(index);
250 _signature = pool->signature_ref_at(index);
251 _current_klass = KlassHandle(THREAD, pool->pool_holder());
252
253 // Coming from the constant pool always checks access
254 _check_access = true;
255 }
256
257 char* LinkInfo::method_string() const {
258 return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
259 }
260
261 #ifndef PRODUCT
262 void LinkInfo::print() {
263 ResourceMark rm;
264 tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
265 _resolved_klass->name()->as_C_string(),
266 _name->as_C_string(),
267 _signature->as_C_string(),
268 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
269 _check_access ? "true" : "false");
270 }
667 failed_type_name);
668 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
669 }
670 }
671
672 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
673 bool require_methodref, TRAPS) {
674
675 Handle nested_exception;
676 KlassHandle resolved_klass = link_info.resolved_klass();
677
678 // 1. check if methodref required, that resolved_klass is not interfacemethodref
679 if (require_methodref && resolved_klass->is_interface()) {
680 ResourceMark rm(THREAD);
681 char buf[200];
682 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
683 resolved_klass()->external_name());
684 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
685 }
686
687 // 2. lookup method in resolved klass and its super klasses
688 methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
689
690 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
691 // 3. lookup method in all the interfaces implemented by the resolved klass
692 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
693
694 if (resolved_method.is_null()) {
695 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
696 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
697 if (HAS_PENDING_EXCEPTION) {
698 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
699 CLEAR_PENDING_EXCEPTION;
700 }
701 }
702 }
703
704 if (resolved_method.is_null()) {
705 // 4. method lookup failed
706 ResourceMark rm(THREAD);
756 if (index != -1) {
757 st->print("vtable_index:%d", index);
758 }
759 st->cr();
760 #endif // PRODUCT
761 }
762
763 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
764 bool nostatics, TRAPS) {
765
766 KlassHandle resolved_klass = link_info.resolved_klass();
767
768 // check if klass is interface
769 if (!resolved_klass->is_interface()) {
770 ResourceMark rm(THREAD);
771 char buf[200];
772 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
773 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
774 }
775
776 // lookup method in this interface or its super, java.lang.Object
777 // JDK8: also look for static methods
778 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
779
780 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
781 // lookup method in all the super-interfaces
782 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
783 }
784
785 if (resolved_method.is_null()) {
786 // no method found
787 ResourceMark rm(THREAD);
788 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
789 Method::name_and_sig_as_C_string(resolved_klass(),
790 link_info.name(),
791 link_info.signature()));
792 }
793
794 if (link_info.check_access()) {
795 // JDK8 adds non-public interface methods, and accessability check requirement
933 // resolved_method the specified method (i.e., static receiver specified via constant pool index)
934 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class)
935 // resolved_klass the specified klass (i.e., specified via constant pool index)
936 // recv_klass the receiver klass
937
938
939 void LinkResolver::resolve_static_call(CallInfo& result,
940 const LinkInfo& link_info,
941 bool initialize_class, TRAPS) {
942 methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
943
944 // The resolved class can change as a result of this resolution.
945 KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
946
947 Method* save_resolved_method = resolved_method();
948 // Initialize klass (this should only happen if everything is ok)
949 if (initialize_class && resolved_klass->should_be_initialized()) {
950 resolved_klass->initialize(CHECK);
951 // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
952 LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
953 link_info.current_klass(), link_info.check_access());
954 resolved_method = linktime_resolve_static_method(new_info, CHECK);
955 }
956
957 assert(save_resolved_method == resolved_method(), "does this change?");
958 // setup result
959 result.set_static(resolved_klass, resolved_method, CHECK);
960 }
961
962 // throws linktime exceptions
963 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
964
965 KlassHandle resolved_klass = link_info.resolved_klass();
966 methodHandle resolved_method;
967 if (!resolved_klass->is_interface()) {
968 resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
969 } else {
970 resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
971 }
972 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
973
1474 // ConstantPool entries
1475
1476 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1477 switch (byte) {
1478 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
1479 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break;
1480 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break;
1481 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break;
1482 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break;
1483 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1484 }
1485 return;
1486 }
1487
1488 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1489 const methodHandle& attached_method,
1490 Bytecodes::Code byte, TRAPS) {
1491 KlassHandle defc = attached_method->method_holder();
1492 Symbol* name = attached_method->name();
1493 Symbol* type = attached_method->signature();
1494 LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false);
1495 switch(byte) {
1496 case Bytecodes::_invokevirtual:
1497 resolve_virtual_call(result, recv, recv->klass(), link_info,
1498 /*check_null_and_abstract=*/true, CHECK);
1499 break;
1500 case Bytecodes::_invokeinterface:
1501 resolve_interface_call(result, recv, recv->klass(), link_info,
1502 /*check_null_and_abstract=*/true, CHECK);
1503 break;
1504 case Bytecodes::_invokestatic:
1505 resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1506 break;
1507 case Bytecodes::_invokespecial:
1508 resolve_special_call(result, link_info, CHECK);
1509 break;
1510 default:
1511 fatal("bad call: %s", Bytecodes::name(byte));
1512 }
1513 }
1514
|
1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
231 case direct_call: kindstr = "direct"; break;
232 case vtable_call: kindstr = "vtable"; break;
233 case itable_call: kindstr = "itable"; break;
234 }
235 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
236 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
237 }
238 #endif
239
240 //------------------------------------------------------------------------------------------------------------------------
241 // Implementation of LinkInfo
242
243 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
244 // resolve klass
245 Klass* result = pool->klass_ref_at(index, CHECK);
246 _resolved_klass = KlassHandle(THREAD, result);
247
248 // Get name, signature, and static klass
249 _name = pool->name_ref_at(index);
250 _signature = pool->signature_ref_at(index);
251 _tag = pool->tag_ref_at(index);
252 _current_klass = KlassHandle(THREAD, pool->pool_holder());
253
254 // Coming from the constant pool always checks access
255 _check_access = true;
256 }
257
258 char* LinkInfo::method_string() const {
259 return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
260 }
261
262 #ifndef PRODUCT
263 void LinkInfo::print() {
264 ResourceMark rm;
265 tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
266 _resolved_klass->name()->as_C_string(),
267 _name->as_C_string(),
268 _signature->as_C_string(),
269 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
270 _check_access ? "true" : "false");
271 }
668 failed_type_name);
669 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
670 }
671 }
672
673 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
674 bool require_methodref, TRAPS) {
675
676 Handle nested_exception;
677 KlassHandle resolved_klass = link_info.resolved_klass();
678
679 // 1. check if methodref required, that resolved_klass is not interfacemethodref
680 if (require_methodref && resolved_klass->is_interface()) {
681 ResourceMark rm(THREAD);
682 char buf[200];
683 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
684 resolved_klass()->external_name());
685 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
686 }
687
688 // check tag at call is method
689 if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
690 ResourceMark rm(THREAD);
691 char buf[200];
692 jio_snprintf(buf, sizeof(buf), "Resolving to non regular method %s", link_info.method_string());
693 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
694 }
695
696
697 // 2. lookup method in resolved klass and its super klasses
698 methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
699
700 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
701 // 3. lookup method in all the interfaces implemented by the resolved klass
702 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
703
704 if (resolved_method.is_null()) {
705 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
706 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
707 if (HAS_PENDING_EXCEPTION) {
708 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
709 CLEAR_PENDING_EXCEPTION;
710 }
711 }
712 }
713
714 if (resolved_method.is_null()) {
715 // 4. method lookup failed
716 ResourceMark rm(THREAD);
766 if (index != -1) {
767 st->print("vtable_index:%d", index);
768 }
769 st->cr();
770 #endif // PRODUCT
771 }
772
773 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
774 bool nostatics, TRAPS) {
775
776 KlassHandle resolved_klass = link_info.resolved_klass();
777
778 // check if klass is interface
779 if (!resolved_klass->is_interface()) {
780 ResourceMark rm(THREAD);
781 char buf[200];
782 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
783 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
784 }
785
786 // check tag at call is an interface method
787 if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) {
788 ResourceMark rm(THREAD);
789 char buf[200];
790 jio_snprintf(buf, sizeof(buf), "Resolving to non interface method %s", link_info.method_string());
791 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
792 }
793
794 // lookup method in this interface or its super, java.lang.Object
795 // JDK8: also look for static methods
796 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
797
798 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
799 // lookup method in all the super-interfaces
800 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
801 }
802
803 if (resolved_method.is_null()) {
804 // no method found
805 ResourceMark rm(THREAD);
806 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
807 Method::name_and_sig_as_C_string(resolved_klass(),
808 link_info.name(),
809 link_info.signature()));
810 }
811
812 if (link_info.check_access()) {
813 // JDK8 adds non-public interface methods, and accessability check requirement
951 // resolved_method the specified method (i.e., static receiver specified via constant pool index)
952 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class)
953 // resolved_klass the specified klass (i.e., specified via constant pool index)
954 // recv_klass the receiver klass
955
956
957 void LinkResolver::resolve_static_call(CallInfo& result,
958 const LinkInfo& link_info,
959 bool initialize_class, TRAPS) {
960 methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
961
962 // The resolved class can change as a result of this resolution.
963 KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
964
965 Method* save_resolved_method = resolved_method();
966 // Initialize klass (this should only happen if everything is ok)
967 if (initialize_class && resolved_klass->should_be_initialized()) {
968 resolved_klass->initialize(CHECK);
969 // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
970 LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
971 link_info.current_klass(),
972 link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
973 resolved_method = linktime_resolve_static_method(new_info, CHECK);
974 }
975
976 assert(save_resolved_method == resolved_method(), "does this change?");
977 // setup result
978 result.set_static(resolved_klass, resolved_method, CHECK);
979 }
980
981 // throws linktime exceptions
982 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
983
984 KlassHandle resolved_klass = link_info.resolved_klass();
985 methodHandle resolved_method;
986 if (!resolved_klass->is_interface()) {
987 resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
988 } else {
989 resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
990 }
991 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
992
1493 // ConstantPool entries
1494
1495 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
1496 switch (byte) {
1497 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
1498 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break;
1499 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break;
1500 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break;
1501 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break;
1502 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1503 }
1504 return;
1505 }
1506
1507 void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
1508 const methodHandle& attached_method,
1509 Bytecodes::Code byte, TRAPS) {
1510 KlassHandle defc = attached_method->method_holder();
1511 Symbol* name = attached_method->name();
1512 Symbol* type = attached_method->signature();
1513 LinkInfo link_info(defc, name, type, KlassHandle(), LinkInfo::skip_access_check);
1514 switch(byte) {
1515 case Bytecodes::_invokevirtual:
1516 resolve_virtual_call(result, recv, recv->klass(), link_info,
1517 /*check_null_and_abstract=*/true, CHECK);
1518 break;
1519 case Bytecodes::_invokeinterface:
1520 resolve_interface_call(result, recv, recv->klass(), link_info,
1521 /*check_null_and_abstract=*/true, CHECK);
1522 break;
1523 case Bytecodes::_invokestatic:
1524 resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
1525 break;
1526 case Bytecodes::_invokespecial:
1527 resolve_special_call(result, link_info, CHECK);
1528 break;
1529 default:
1530 fatal("bad call: %s", Bytecodes::name(byte));
1531 }
1532 }
1533
|