602 target, failed_type_name); |
611 target, failed_type_name); |
603 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
612 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
604 } |
613 } |
605 } |
614 } |
606 } |
615 } |
|
616 |
|
617 if (TraceItables && Verbose) { |
|
618 ResourceMark rm(THREAD); |
|
619 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", |
|
620 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), |
|
621 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
|
622 Method::name_and_sig_as_C_string(resolved_klass(), |
|
623 resolved_method->name(), |
|
624 resolved_method->signature()), |
|
625 resolved_method->method_holder()->internal_name() |
|
626 ); |
|
627 resolved_method->access_flags().print_on(tty); |
|
628 tty->cr(); |
|
629 } |
607 } |
630 } |
608 |
631 |
609 //------------------------------------------------------------------------------------------------------------------------ |
632 //------------------------------------------------------------------------------------------------------------------------ |
610 // Field resolution |
633 // Field resolution |
611 |
634 |
793 // throws linktime exceptions |
816 // throws linktime exceptions |
794 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
817 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
795 Symbol* method_name, Symbol* method_signature, |
818 Symbol* method_name, Symbol* method_signature, |
796 KlassHandle current_klass, bool check_access, TRAPS) { |
819 KlassHandle current_klass, bool check_access, TRAPS) { |
797 |
820 |
798 if (resolved_klass->is_interface() && current_klass() != NULL) { |
821 // Invokespecial is called for multiple special reasons: |
799 // If the target class is a direct interface, treat this as a "super" |
822 // <init> |
800 // default call. |
823 // local private method invocation, for classes and interfaces |
801 // |
824 // superclass.method, which can also resolve to a default method |
802 // If the current method is an overpass that happens to call a direct |
825 // and the selected method is recalculated relative to the direct superclass |
803 // super-interface's method, then we'll end up rerunning the default method |
826 // superinterface.method, which explicitly does not check shadowing |
804 // analysis even though we don't need to, but that's ok since it will end |
|
805 // up with the same answer. |
|
806 InstanceKlass* ik = InstanceKlass::cast(current_klass()); |
|
807 Array<Klass*>* interfaces = ik->local_interfaces(); |
|
808 int num_interfaces = interfaces->length(); |
|
809 for (int index = 0; index < num_interfaces; index++) { |
|
810 if (interfaces->at(index) == resolved_klass()) { |
|
811 Method* method = DefaultMethods::find_super_default(current_klass(), |
|
812 resolved_klass(), method_name, method_signature, CHECK); |
|
813 resolved_method = methodHandle(THREAD, method); |
|
814 return; |
|
815 } |
|
816 } |
|
817 } |
|
818 |
827 |
819 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
828 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
820 |
829 |
821 // check if method name is <init>, that it is found in same klass as static type |
830 // check if method name is <init>, that it is found in same klass as static type |
822 if (resolved_method->name() == vmSymbols::object_initializer_name() && |
831 if (resolved_method->name() == vmSymbols::object_initializer_name() && |
842 Method::name_and_sig_as_C_string(resolved_klass(), |
851 Method::name_and_sig_as_C_string(resolved_klass(), |
843 resolved_method->name(), |
852 resolved_method->name(), |
844 resolved_method->signature())); |
853 resolved_method->signature())); |
845 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
854 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
846 } |
855 } |
|
856 if (TraceItables && Verbose) { |
|
857 ResourceMark rm(THREAD); |
|
858 tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", |
|
859 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), |
|
860 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
|
861 Method::name_and_sig_as_C_string(resolved_klass(), |
|
862 resolved_method->name(), |
|
863 resolved_method->signature()), |
|
864 resolved_method->method_holder()->internal_name() |
|
865 ); |
|
866 resolved_method->access_flags().print_on(tty); |
|
867 if (resolved_method->method_holder()->is_interface() && |
|
868 !resolved_method->is_abstract()) { |
|
869 tty->print("default"); |
|
870 } |
|
871 if (resolved_method->is_overpass()) { |
|
872 tty->print("overpass"); |
|
873 } |
|
874 tty->cr(); |
|
875 } |
847 } |
876 } |
848 |
877 |
849 // throws runtime exceptions |
878 // throws runtime exceptions |
850 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, |
879 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, |
851 KlassHandle current_klass, bool check_access, TRAPS) { |
880 KlassHandle current_klass, bool check_access, TRAPS) { |
852 |
881 |
853 // resolved method is selected method unless we have an old-style lookup |
882 // resolved method is selected method unless we have an old-style lookup |
|
883 // for a superclass method |
|
884 // Invokespecial for a superinterface, resolved method is selected method, |
|
885 // no checks for shadowing |
854 methodHandle sel_method(THREAD, resolved_method()); |
886 methodHandle sel_method(THREAD, resolved_method()); |
855 |
887 |
856 // check if this is an old-style super call and do a new lookup if so |
888 // check if this is an old-style super call and do a new lookup if so |
857 { KlassHandle method_klass = KlassHandle(THREAD, |
889 { KlassHandle method_klass = KlassHandle(THREAD, |
858 resolved_method->method_holder()); |
890 resolved_method->method_holder()); |
859 |
891 |
860 const bool direct_calling_default_method = |
892 if (check_access && |
861 resolved_klass() != NULL && resolved_method() != NULL && |
|
862 resolved_klass->is_interface() && !resolved_method->is_abstract(); |
|
863 |
|
864 if (!direct_calling_default_method && |
|
865 check_access && |
|
866 // a) check if ACC_SUPER flag is set for the current class |
893 // a) check if ACC_SUPER flag is set for the current class |
867 (current_klass->is_super() || !AllowNonVirtualCalls) && |
894 (current_klass->is_super() || !AllowNonVirtualCalls) && |
868 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) |
895 // b) check if the class of the resolved_klass is a superclass |
869 current_klass->is_subtype_of(method_klass()) && |
896 // (not supertype in order to exclude interface classes) of the current class. |
870 current_klass() != method_klass() && |
897 // This check is not performed for super.invoke for interface methods |
|
898 // in super interfaces. |
|
899 current_klass->is_subclass_of(resolved_klass()) && |
|
900 current_klass() != resolved_klass() && |
871 // c) check if the method is not <init> |
901 // c) check if the method is not <init> |
872 resolved_method->name() != vmSymbols::object_initializer_name()) { |
902 resolved_method->name() != vmSymbols::object_initializer_name()) { |
873 // Lookup super method |
903 // Lookup super method |
874 KlassHandle super_klass(THREAD, current_klass->super()); |
904 KlassHandle super_klass(THREAD, current_klass->super()); |
875 lookup_instance_method_in_klasses(sel_method, super_klass, |
905 lookup_instance_method_in_klasses(sel_method, super_klass, |
903 Method::name_and_sig_as_C_string(resolved_klass(), |
933 Method::name_and_sig_as_C_string(resolved_klass(), |
904 sel_method->name(), |
934 sel_method->name(), |
905 sel_method->signature())); |
935 sel_method->signature())); |
906 } |
936 } |
907 |
937 |
|
938 if (TraceItables && Verbose) { |
|
939 ResourceMark rm(THREAD); |
|
940 tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ", |
|
941 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
|
942 Method::name_and_sig_as_C_string(resolved_klass(), |
|
943 sel_method->name(), |
|
944 sel_method->signature()), |
|
945 sel_method->method_holder()->internal_name() |
|
946 ); |
|
947 sel_method->access_flags().print_on(tty); |
|
948 if (sel_method->method_holder()->is_interface() && |
|
949 !sel_method->is_abstract()) { |
|
950 tty->print("default"); |
|
951 } |
|
952 tty->cr(); |
|
953 } |
|
954 |
908 // setup result |
955 // setup result |
909 result.set_static(resolved_klass, sel_method, CHECK); |
956 result.set_static(resolved_klass, sel_method, CHECK); |
910 } |
957 } |
911 |
958 |
912 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass, |
959 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass, |
925 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
972 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
926 |
973 |
927 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
974 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
928 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
975 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
929 |
976 |
|
977 // check if private interface method |
|
978 if (resolved_klass->is_interface() && resolved_method->is_private()) { |
|
979 ResourceMark rm(THREAD); |
|
980 char buf[200]; |
|
981 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s", |
|
982 Method::name_and_sig_as_C_string(resolved_klass(), |
|
983 resolved_method->name(), |
|
984 resolved_method->signature()), |
|
985 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name())); |
|
986 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
|
987 } |
|
988 |
930 // check if not static |
989 // check if not static |
931 if (resolved_method->is_static()) { |
990 if (resolved_method->is_static()) { |
932 ResourceMark rm(THREAD); |
991 ResourceMark rm(THREAD); |
933 char buf[200]; |
992 char buf[200]; |
934 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), |
993 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), |
935 resolved_method->name(), |
994 resolved_method->name(), |
936 resolved_method->signature())); |
995 resolved_method->signature())); |
937 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
996 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
938 } |
997 } |
|
998 |
|
999 if (PrintVtables && Verbose) { |
|
1000 ResourceMark rm(THREAD); |
|
1001 tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", |
|
1002 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), |
|
1003 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
|
1004 Method::name_and_sig_as_C_string(resolved_klass(), |
|
1005 resolved_method->name(), |
|
1006 resolved_method->signature()), |
|
1007 resolved_method->method_holder()->internal_name() |
|
1008 ); |
|
1009 resolved_method->access_flags().print_on(tty); |
|
1010 if (resolved_method->method_holder()->is_interface() && |
|
1011 !resolved_method->is_abstract()) { |
|
1012 tty->print("default"); |
|
1013 } |
|
1014 if (resolved_method->is_overpass()) { |
|
1015 tty->print("overpass"); |
|
1016 } |
|
1017 tty->cr(); |
|
1018 } |
939 } |
1019 } |
940 |
1020 |
941 // throws runtime exceptions |
1021 // throws runtime exceptions |
942 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, |
1022 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, |
943 methodHandle resolved_method, |
1023 methodHandle resolved_method, |
1010 Method::name_and_sig_as_C_string(resolved_klass(), |
1090 Method::name_and_sig_as_C_string(resolved_klass(), |
1011 selected_method->name(), |
1091 selected_method->name(), |
1012 selected_method->signature())); |
1092 selected_method->signature())); |
1013 } |
1093 } |
1014 |
1094 |
|
1095 if (PrintVtables && Verbose) { |
|
1096 ResourceMark rm(THREAD); |
|
1097 tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ", |
|
1098 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()), |
|
1099 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
|
1100 Method::name_and_sig_as_C_string(resolved_klass(), |
|
1101 resolved_method->name(), |
|
1102 resolved_method->signature()), |
|
1103 selected_method->method_holder()->internal_name(), |
|
1104 vtable_index |
|
1105 ); |
|
1106 selected_method->access_flags().print_on(tty); |
|
1107 if (selected_method->method_holder()->is_interface() && |
|
1108 !selected_method->is_abstract()) { |
|
1109 tty->print("default"); |
|
1110 } |
|
1111 if (resolved_method->is_overpass()) { |
|
1112 tty->print("overpass"); |
|
1113 } |
|
1114 tty->cr(); |
|
1115 } |
1015 // setup result |
1116 // setup result |
1016 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); |
1117 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); |
1017 } |
1118 } |
1018 |
1119 |
1019 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, |
1120 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, |
1038 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, |
1139 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, |
1039 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) { |
1140 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) { |
1040 // check if receiver exists |
1141 // check if receiver exists |
1041 if (check_null_and_abstract && recv.is_null()) { |
1142 if (check_null_and_abstract && recv.is_null()) { |
1042 THROW(vmSymbols::java_lang_NullPointerException()); |
1143 THROW(vmSymbols::java_lang_NullPointerException()); |
|
1144 } |
|
1145 |
|
1146 // check if private interface method |
|
1147 if (resolved_klass->is_interface() && resolved_method->is_private()) { |
|
1148 ResourceMark rm(THREAD); |
|
1149 char buf[200]; |
|
1150 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s", |
|
1151 Method::name_and_sig_as_C_string(resolved_klass(), |
|
1152 resolved_method->name(), |
|
1153 resolved_method->signature())); |
|
1154 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
1043 } |
1155 } |
1044 |
1156 |
1045 // check if receiver klass implements the resolved interface |
1157 // check if receiver klass implements the resolved interface |
1046 if (!recv_klass->is_subtype_of(resolved_klass())) { |
1158 if (!recv_klass->is_subtype_of(resolved_klass())) { |
1047 ResourceMark rm(THREAD); |
1159 ResourceMark rm(THREAD); |
1069 Method::name_and_sig_as_C_string(recv_klass(), |
1181 Method::name_and_sig_as_C_string(recv_klass(), |
1070 resolved_method->name(), |
1182 resolved_method->name(), |
1071 resolved_method->signature())); |
1183 resolved_method->signature())); |
1072 } |
1184 } |
1073 // check access |
1185 // check access |
1074 if (sel_method->method_holder()->is_interface()) { |
1186 // Throw Illegal Access Error if sel_method is not public. |
1075 // Method holder is an interface. Throw Illegal Access Error if sel_method |
1187 if (!sel_method->is_public()) { |
1076 // is neither public nor private. |
1188 ResourceMark rm(THREAD); |
1077 if (!(sel_method->is_public() || sel_method->is_private())) { |
1189 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), |
1078 ResourceMark rm(THREAD); |
1190 Method::name_and_sig_as_C_string(recv_klass(), |
1079 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), |
1191 sel_method->name(), |
1080 Method::name_and_sig_as_C_string(recv_klass(), |
1192 sel_method->signature())); |
1081 sel_method->name(), |
1193 } |
1082 sel_method->signature())); |
1194 |
1083 } |
|
1084 } |
|
1085 else { |
|
1086 // Method holder is a class. Throw Illegal Access Error if sel_method |
|
1087 // is not public. |
|
1088 if (!sel_method->is_public()) { |
|
1089 ResourceMark rm(THREAD); |
|
1090 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), |
|
1091 Method::name_and_sig_as_C_string(recv_klass(), |
|
1092 sel_method->name(), |
|
1093 sel_method->signature())); |
|
1094 } |
|
1095 } |
|
1096 // check if abstract |
1195 // check if abstract |
1097 if (check_null_and_abstract && sel_method->is_abstract()) { |
1196 if (check_null_and_abstract && sel_method->is_abstract()) { |
1098 ResourceMark rm(THREAD); |
1197 ResourceMark rm(THREAD); |
1099 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
1198 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
1100 Method::name_and_sig_as_C_string(recv_klass(), |
1199 Method::name_and_sig_as_C_string(recv_klass(), |
1107 assert(vtable_index == sel_method->vtable_index(), "sanity check"); |
1206 assert(vtable_index == sel_method->vtable_index(), "sanity check"); |
1108 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); |
1207 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); |
1109 return; |
1208 return; |
1110 } |
1209 } |
1111 int itable_index = resolved_method()->itable_index(); |
1210 int itable_index = resolved_method()->itable_index(); |
|
1211 |
|
1212 if (TraceItables && Verbose) { |
|
1213 ResourceMark rm(THREAD); |
|
1214 tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ", |
|
1215 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()), |
|
1216 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
|
1217 Method::name_and_sig_as_C_string(resolved_klass(), |
|
1218 resolved_method->name(), |
|
1219 resolved_method->signature()), |
|
1220 sel_method->method_holder()->internal_name() |
|
1221 ); |
|
1222 sel_method->access_flags().print_on(tty); |
|
1223 if (sel_method->method_holder()->is_interface() && |
|
1224 !sel_method->is_abstract()) { |
|
1225 tty->print("default"); |
|
1226 } |
|
1227 if (resolved_method->is_overpass()) { |
|
1228 tty->print("overpass"); |
|
1229 } |
|
1230 tty->cr(); |
|
1231 } |
1112 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); |
1232 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); |
1113 } |
1233 } |
1114 |
1234 |
1115 |
1235 |
1116 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( |
1236 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( |