229 _resolved_klass = KlassHandle(THREAD, result); |
229 _resolved_klass = KlassHandle(THREAD, result); |
230 |
230 |
231 // Get name, signature, and static klass |
231 // Get name, signature, and static klass |
232 _name = pool->name_ref_at(index); |
232 _name = pool->name_ref_at(index); |
233 _signature = pool->signature_ref_at(index); |
233 _signature = pool->signature_ref_at(index); |
|
234 _tag = pool->tag_ref_at(index); |
234 _current_klass = KlassHandle(THREAD, pool->pool_holder()); |
235 _current_klass = KlassHandle(THREAD, pool->pool_holder()); |
235 |
236 |
236 // Coming from the constant pool always checks access |
237 // Coming from the constant pool always checks access |
237 _check_access = true; |
238 _check_access = true; |
238 } |
239 } |
571 resolved_klass = SystemDictionary::MethodHandle_klass(); |
572 resolved_klass = SystemDictionary::MethodHandle_klass(); |
572 Symbol* method_name = vmSymbols::invoke_name(); |
573 Symbol* method_name = vmSymbols::invoke_name(); |
573 Symbol* method_signature = pool->signature_ref_at(index); |
574 Symbol* method_signature = pool->signature_ref_at(index); |
574 KlassHandle current_klass(THREAD, pool->pool_holder()); |
575 KlassHandle current_klass(THREAD, pool->pool_holder()); |
575 LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass); |
576 LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass); |
576 return resolve_method(link_info, /*require_methodref*/false, THREAD); |
577 return resolve_method(link_info, code, THREAD); |
577 } |
578 } |
578 |
579 |
579 LinkInfo link_info(pool, index, CHECK_NULL); |
580 LinkInfo link_info(pool, index, CHECK_NULL); |
580 resolved_klass = link_info.resolved_klass(); |
581 resolved_klass = link_info.resolved_klass(); |
581 |
582 |
589 } |
590 } |
590 |
591 |
591 if (code == Bytecodes::_invokeinterface) { |
592 if (code == Bytecodes::_invokeinterface) { |
592 return resolve_interface_method(link_info, code, THREAD); |
593 return resolve_interface_method(link_info, code, THREAD); |
593 } else if (code == Bytecodes::_invokevirtual) { |
594 } else if (code == Bytecodes::_invokevirtual) { |
594 return resolve_method(link_info, /*require_methodref*/true, THREAD); |
595 return resolve_method(link_info, code, THREAD); |
595 } else if (!resolved_klass->is_interface()) { |
596 } else if (!resolved_klass->is_interface()) { |
596 return resolve_method(link_info, /*require_methodref*/false, THREAD); |
597 return resolve_method(link_info, code, THREAD); |
597 } else { |
598 } else { |
598 return resolve_interface_method(link_info, code, THREAD); |
599 return resolve_interface_method(link_info, code, THREAD); |
599 } |
600 } |
600 } |
601 } |
601 |
602 |
661 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
662 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
662 } |
663 } |
663 } |
664 } |
664 |
665 |
665 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info, |
666 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info, |
666 bool require_methodref, TRAPS) { |
667 Bytecodes::Code code, TRAPS) { |
667 |
668 |
668 Handle nested_exception; |
669 Handle nested_exception; |
669 KlassHandle resolved_klass = link_info.resolved_klass(); |
670 KlassHandle resolved_klass = link_info.resolved_klass(); |
670 |
671 |
671 // 1. check if methodref required, that resolved_klass is not interfacemethodref |
672 // 1. For invokevirtual, cannot call an interface method |
672 if (require_methodref && resolved_klass->is_interface()) { |
673 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) { |
673 ResourceMark rm(THREAD); |
674 ResourceMark rm(THREAD); |
674 char buf[200]; |
675 char buf[200]; |
675 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", |
676 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", |
676 resolved_klass()->external_name()); |
677 resolved_klass()->external_name()); |
677 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
678 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
678 } |
679 } |
679 |
680 |
680 // 2. lookup method in resolved klass and its super klasses |
681 // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref |
|
682 if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) { |
|
683 ResourceMark rm(THREAD); |
|
684 char buf[200]; |
|
685 jio_snprintf(buf, sizeof(buf), "Method %s must be Methodref constant", link_info.method_string()); |
|
686 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
|
687 } |
|
688 |
|
689 |
|
690 // 3. lookup method in resolved klass and its super klasses |
681 methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL); |
691 methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL); |
682 |
692 |
|
693 // 4. lookup method in all the interfaces implemented by the resolved klass |
683 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy |
694 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy |
684 // 3. lookup method in all the interfaces implemented by the resolved klass |
|
685 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL); |
695 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL); |
686 |
696 |
687 if (resolved_method.is_null()) { |
697 if (resolved_method.is_null()) { |
688 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc |
698 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc |
689 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD); |
699 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD); |
692 CLEAR_PENDING_EXCEPTION; |
702 CLEAR_PENDING_EXCEPTION; |
693 } |
703 } |
694 } |
704 } |
695 } |
705 } |
696 |
706 |
|
707 // 5. method lookup failed |
697 if (resolved_method.is_null()) { |
708 if (resolved_method.is_null()) { |
698 // 4. method lookup failed |
|
699 ResourceMark rm(THREAD); |
709 ResourceMark rm(THREAD); |
700 THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(), |
710 THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(), |
701 Method::name_and_sig_as_C_string(resolved_klass(), |
711 Method::name_and_sig_as_C_string(resolved_klass(), |
702 link_info.name(), |
712 link_info.name(), |
703 link_info.signature()), |
713 link_info.signature()), |
704 nested_exception, NULL); |
714 nested_exception, NULL); |
705 } |
715 } |
706 |
716 |
707 // 5. access checks, access checking may be turned off when calling from within the VM. |
717 // 6. access checks, access checking may be turned off when calling from within the VM. |
708 KlassHandle current_klass = link_info.current_klass(); |
718 KlassHandle current_klass = link_info.current_klass(); |
709 if (link_info.check_access()) { |
719 if (link_info.check_access()) { |
710 assert(current_klass.not_null() , "current_klass should not be null"); |
720 assert(current_klass.not_null() , "current_klass should not be null"); |
711 |
721 |
712 // check if method can be accessed by the referring class |
722 // check if method can be accessed by the referring class |
764 char buf[200]; |
774 char buf[200]; |
765 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); |
775 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); |
766 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
776 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
767 } |
777 } |
768 |
778 |
|
779 // check constant pool tag for called method - must be JVM_CONSTANT_InterfaceMethodref |
|
780 if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) { |
|
781 ResourceMark rm(THREAD); |
|
782 char buf[200]; |
|
783 jio_snprintf(buf, sizeof(buf), "Method %s must be InterfaceMethodref constant", link_info.method_string()); |
|
784 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
|
785 } |
|
786 |
769 // lookup method in this interface or its super, java.lang.Object |
787 // lookup method in this interface or its super, java.lang.Object |
770 // JDK8: also look for static methods |
788 // JDK8: also look for static methods |
771 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); |
789 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); |
772 |
790 |
773 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { |
791 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { |
954 // Initialize klass (this should only happen if everything is ok) |
972 // Initialize klass (this should only happen if everything is ok) |
955 if (initialize_class && resolved_klass->should_be_initialized()) { |
973 if (initialize_class && resolved_klass->should_be_initialized()) { |
956 resolved_klass->initialize(CHECK); |
974 resolved_klass->initialize(CHECK); |
957 // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?) |
975 // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?) |
958 LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(), |
976 LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(), |
959 link_info.current_klass(), link_info.check_access()); |
977 link_info.current_klass(), |
|
978 link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); |
960 resolved_method = linktime_resolve_static_method(new_info, CHECK); |
979 resolved_method = linktime_resolve_static_method(new_info, CHECK); |
961 } |
980 } |
962 |
981 |
963 assert(save_resolved_method == resolved_method(), "does this change?"); |
982 assert(save_resolved_method == resolved_method(), "does this change?"); |
964 // setup result |
983 // setup result |
969 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) { |
988 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) { |
970 |
989 |
971 KlassHandle resolved_klass = link_info.resolved_klass(); |
990 KlassHandle resolved_klass = link_info.resolved_klass(); |
972 methodHandle resolved_method; |
991 methodHandle resolved_method; |
973 if (!resolved_klass->is_interface()) { |
992 if (!resolved_klass->is_interface()) { |
974 resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL); |
993 resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
975 } else { |
994 } else { |
976 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
995 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
977 } |
996 } |
978 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); |
997 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); |
979 |
998 |
1012 // superinterface.method, which explicitly does not check shadowing |
1031 // superinterface.method, which explicitly does not check shadowing |
1013 KlassHandle resolved_klass = link_info.resolved_klass(); |
1032 KlassHandle resolved_klass = link_info.resolved_klass(); |
1014 methodHandle resolved_method; |
1033 methodHandle resolved_method; |
1015 |
1034 |
1016 if (!resolved_klass->is_interface()) { |
1035 if (!resolved_klass->is_interface()) { |
1017 resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL); |
1036 resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1018 } else { |
1037 } else { |
1019 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1038 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1020 } |
1039 } |
1021 |
1040 |
1022 // check if method name is <init>, that it is found in same klass as static type |
1041 // check if method name is <init>, that it is found in same klass as static type |
1162 |
1181 |
1163 // throws linktime exceptions |
1182 // throws linktime exceptions |
1164 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, |
1183 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, |
1165 TRAPS) { |
1184 TRAPS) { |
1166 // normal method resolution |
1185 // normal method resolution |
1167 methodHandle resolved_method = resolve_method(link_info, /*require_methodref*/true, CHECK_NULL); |
1186 methodHandle resolved_method = resolve_method(link_info, Bytecodes::_invokevirtual, CHECK_NULL); |
1168 |
1187 |
1169 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1188 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1170 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1189 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1171 |
1190 |
1172 // check if private interface method |
1191 // check if private interface method |
1173 KlassHandle resolved_klass = link_info.resolved_klass(); |
1192 KlassHandle resolved_klass = link_info.resolved_klass(); |
1174 KlassHandle current_klass = link_info.current_klass(); |
1193 KlassHandle current_klass = link_info.current_klass(); |
1175 |
1194 |
|
1195 // This is impossible, if resolve_klass is an interface, we've thrown icce in resolve_method |
1176 if (resolved_klass->is_interface() && resolved_method->is_private()) { |
1196 if (resolved_klass->is_interface() && resolved_method->is_private()) { |
1177 ResourceMark rm(THREAD); |
1197 ResourceMark rm(THREAD); |
1178 char buf[200]; |
1198 char buf[200]; |
1179 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s", |
1199 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s", |
1180 Method::name_and_sig_as_C_string(resolved_klass(), |
1200 Method::name_and_sig_as_C_string(resolved_klass(), |
1480 const methodHandle& attached_method, |
1500 const methodHandle& attached_method, |
1481 Bytecodes::Code byte, TRAPS) { |
1501 Bytecodes::Code byte, TRAPS) { |
1482 KlassHandle defc = attached_method->method_holder(); |
1502 KlassHandle defc = attached_method->method_holder(); |
1483 Symbol* name = attached_method->name(); |
1503 Symbol* name = attached_method->name(); |
1484 Symbol* type = attached_method->signature(); |
1504 Symbol* type = attached_method->signature(); |
1485 LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false); |
1505 LinkInfo link_info(defc, name, type); |
1486 switch(byte) { |
1506 switch(byte) { |
1487 case Bytecodes::_invokevirtual: |
1507 case Bytecodes::_invokevirtual: |
1488 resolve_virtual_call(result, recv, recv->klass(), link_info, |
1508 resolve_virtual_call(result, recv, recv->klass(), link_info, |
1489 /*check_null_and_abstract=*/true, CHECK); |
1509 /*check_null_and_abstract=*/true, CHECK); |
1490 break; |
1510 break; |