229 case direct_call: kindstr = "direct"; break;
230 case vtable_call: kindstr = "vtable"; break;
231 case itable_call: kindstr = "itable"; break;
232 }
233 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
234 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
235 }
236 #endif
237
238 //------------------------------------------------------------------------------------------------------------------------
239 // Implementation of LinkInfo
240
241 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
242 // resolve klass
243 Klass* result = pool->klass_ref_at(index, CHECK);
244 _resolved_klass = KlassHandle(THREAD, result);
245
246 // Get name, signature, and static klass
247 _name = pool->name_ref_at(index);
248 _signature = pool->signature_ref_at(index);
249 _current_klass = KlassHandle(THREAD, pool->pool_holder());
250
251 // Coming from the constant pool always checks access
252 _check_access = true;
253 }
254
255 char* LinkInfo::method_string() const {
256 return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
257 }
258
259 #ifndef PRODUCT
260 void LinkInfo::print() {
261 ResourceMark rm;
262 tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
263 _resolved_klass->name()->as_C_string(),
264 _name->as_C_string(),
265 _signature->as_C_string(),
266 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
267 _check_access ? "true" : "false");
268 }
665 failed_type_name);
666 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
667 }
668 }
669
670 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
671 bool require_methodref, TRAPS) {
672
673 Handle nested_exception;
674 KlassHandle resolved_klass = link_info.resolved_klass();
675
676 // 1. check if methodref required, that resolved_klass is not interfacemethodref
677 if (require_methodref && resolved_klass->is_interface()) {
678 ResourceMark rm(THREAD);
679 char buf[200];
680 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
681 resolved_klass()->external_name());
682 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
683 }
684
685 // 2. lookup method in resolved klass and its super klasses
686 methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
687
688 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
689 // 3. lookup method in all the interfaces implemented by the resolved klass
690 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
691
692 if (resolved_method.is_null()) {
693 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
694 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
695 if (HAS_PENDING_EXCEPTION) {
696 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
697 CLEAR_PENDING_EXCEPTION;
698 }
699 }
700 }
701
702 if (resolved_method.is_null()) {
703 // 4. method lookup failed
704 ResourceMark rm(THREAD);
724 // check loader constraints
725 check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
726 }
727
728 return resolved_method;
729 }
730
731 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
732 bool nostatics, TRAPS) {
733
734 KlassHandle resolved_klass = link_info.resolved_klass();
735
736 // check if klass is interface
737 if (!resolved_klass->is_interface()) {
738 ResourceMark rm(THREAD);
739 char buf[200];
740 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
741 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
742 }
743
744 // lookup method in this interface or its super, java.lang.Object
745 // JDK8: also look for static methods
746 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
747
748 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
749 // lookup method in all the super-interfaces
750 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
751 }
752
753 if (resolved_method.is_null()) {
754 // no method found
755 ResourceMark rm(THREAD);
756 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
757 Method::name_and_sig_as_C_string(resolved_klass(),
758 link_info.name(),
759 link_info.signature()));
760 }
761
762 if (link_info.check_access()) {
763 // JDK8 adds non-public interface methods, and accessability check requirement
901 // resolved_method the specified method (i.e., static receiver specified via constant pool index)
902 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class)
903 // resolved_klass the specified klass (i.e., specified via constant pool index)
904 // recv_klass the receiver klass
905
906
907 void LinkResolver::resolve_static_call(CallInfo& result,
908 const LinkInfo& link_info,
909 bool initialize_class, TRAPS) {
910 methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
911
912 // The resolved class can change as a result of this resolution.
913 KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
914
915 Method* save_resolved_method = resolved_method();
916 // Initialize klass (this should only happen if everything is ok)
917 if (initialize_class && resolved_klass->should_be_initialized()) {
918 resolved_klass->initialize(CHECK);
919 // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
920 LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
921 link_info.current_klass(), link_info.check_access());
922 resolved_method = linktime_resolve_static_method(new_info, CHECK);
923 }
924
925 assert(save_resolved_method == resolved_method(), "does this change?");
926 // setup result
927 result.set_static(resolved_klass, resolved_method, CHECK);
928 }
929
930 // throws linktime exceptions
931 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
932
933 KlassHandle resolved_klass = link_info.resolved_klass();
934 methodHandle resolved_method;
935 if (!resolved_klass->is_interface()) {
936 resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
937 } else {
938 resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
939 }
940 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
941
|
229 case direct_call: kindstr = "direct"; break;
230 case vtable_call: kindstr = "vtable"; break;
231 case itable_call: kindstr = "itable"; break;
232 }
233 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
234 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
235 }
236 #endif
237
238 //------------------------------------------------------------------------------------------------------------------------
239 // Implementation of LinkInfo
240
241 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
242 // resolve klass
243 Klass* result = pool->klass_ref_at(index, CHECK);
244 _resolved_klass = KlassHandle(THREAD, result);
245
246 // Get name, signature, and static klass
247 _name = pool->name_ref_at(index);
248 _signature = pool->signature_ref_at(index);
249 _tag = pool->tag_ref_at(index);
250 _current_klass = KlassHandle(THREAD, pool->pool_holder());
251
252 // Coming from the constant pool always checks access
253 _check_access = true;
254 }
255
256 char* LinkInfo::method_string() const {
257 return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
258 }
259
260 #ifndef PRODUCT
261 void LinkInfo::print() {
262 ResourceMark rm;
263 tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
264 _resolved_klass->name()->as_C_string(),
265 _name->as_C_string(),
266 _signature->as_C_string(),
267 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
268 _check_access ? "true" : "false");
269 }
666 failed_type_name);
667 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
668 }
669 }
670
671 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
672 bool require_methodref, TRAPS) {
673
674 Handle nested_exception;
675 KlassHandle resolved_klass = link_info.resolved_klass();
676
677 // 1. check if methodref required, that resolved_klass is not interfacemethodref
678 if (require_methodref && resolved_klass->is_interface()) {
679 ResourceMark rm(THREAD);
680 char buf[200];
681 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
682 resolved_klass()->external_name());
683 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
684 }
685
686 // check tag at call is method
687 if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
688 ResourceMark rm(THREAD);
689 char buf[200];
690 jio_snprintf(buf, sizeof(buf), "Resolving to non regular method %s", link_info.method_string());
691 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
692 }
693
694
695 // 2. lookup method in resolved klass and its super klasses
696 methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
697
698 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
699 // 3. lookup method in all the interfaces implemented by the resolved klass
700 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
701
702 if (resolved_method.is_null()) {
703 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
704 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
705 if (HAS_PENDING_EXCEPTION) {
706 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
707 CLEAR_PENDING_EXCEPTION;
708 }
709 }
710 }
711
712 if (resolved_method.is_null()) {
713 // 4. method lookup failed
714 ResourceMark rm(THREAD);
734 // check loader constraints
735 check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
736 }
737
738 return resolved_method;
739 }
740
741 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
742 bool nostatics, TRAPS) {
743
744 KlassHandle resolved_klass = link_info.resolved_klass();
745
746 // check if klass is interface
747 if (!resolved_klass->is_interface()) {
748 ResourceMark rm(THREAD);
749 char buf[200];
750 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
751 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
752 }
753
754 // check tag at call is an interface method
755 if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) {
756 ResourceMark rm(THREAD);
757 char buf[200];
758 jio_snprintf(buf, sizeof(buf), "Resolving to non interface method %s", link_info.method_string());
759 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
760 }
761
762 // lookup method in this interface or its super, java.lang.Object
763 // JDK8: also look for static methods
764 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
765
766 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
767 // lookup method in all the super-interfaces
768 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
769 }
770
771 if (resolved_method.is_null()) {
772 // no method found
773 ResourceMark rm(THREAD);
774 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
775 Method::name_and_sig_as_C_string(resolved_klass(),
776 link_info.name(),
777 link_info.signature()));
778 }
779
780 if (link_info.check_access()) {
781 // JDK8 adds non-public interface methods, and accessability check requirement
919 // resolved_method the specified method (i.e., static receiver specified via constant pool index)
920 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class)
921 // resolved_klass the specified klass (i.e., specified via constant pool index)
922 // recv_klass the receiver klass
923
924
925 void LinkResolver::resolve_static_call(CallInfo& result,
926 const LinkInfo& link_info,
927 bool initialize_class, TRAPS) {
928 methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
929
930 // The resolved class can change as a result of this resolution.
931 KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
932
933 Method* save_resolved_method = resolved_method();
934 // Initialize klass (this should only happen if everything is ok)
935 if (initialize_class && resolved_klass->should_be_initialized()) {
936 resolved_klass->initialize(CHECK);
937 // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
938 LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
939 link_info.current_klass(),
940 link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
941 resolved_method = linktime_resolve_static_method(new_info, CHECK);
942 }
943
944 assert(save_resolved_method == resolved_method(), "does this change?");
945 // setup result
946 result.set_static(resolved_klass, resolved_method, CHECK);
947 }
948
949 // throws linktime exceptions
950 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
951
952 KlassHandle resolved_klass = link_info.resolved_klass();
953 methodHandle resolved_method;
954 if (!resolved_klass->is_interface()) {
955 resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
956 } else {
957 resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
958 }
959 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
960
|