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 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/defaultMethods.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "compiler/compileBroker.hpp" 30 #include "gc/shared/collectedHeap.inline.hpp" 31 #include "interpreter/bytecode.hpp" 32 #include "interpreter/interpreterRuntime.hpp" 33 #include "interpreter/linkResolver.hpp" 34 #include "memory/resourceArea.hpp" 35 #include "memory/universe.inline.hpp" 36 #include "oops/instanceKlass.hpp" 37 #include "oops/objArrayOop.hpp" 38 #include "oops/oop.inline.hpp" 39 #include "prims/methodHandles.hpp" 40 #include "prims/nativeLookup.hpp" 41 #include "runtime/compilationPolicy.hpp" 42 #include "runtime/fieldDescriptor.hpp" 43 #include "runtime/frame.inline.hpp" 44 #include "runtime/handles.inline.hpp" 45 #include "runtime/reflection.hpp" 46 #include "runtime/signature.hpp" 47 #include "runtime/thread.inline.hpp" 48 #include "runtime/vmThread.hpp" 49 50 51 //------------------------------------------------------------------------------------------------------------------------ 52 // Implementation of CallInfo 53 54 55 void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) { 56 int vtable_index = Method::nonvirtual_vtable_index; 710 711 // 5. access checks, access checking may be turned off when calling from within the VM. 712 KlassHandle current_klass = link_info.current_klass(); 713 if (link_info.check_access()) { 714 assert(current_klass.not_null() , "current_klass should not be null"); 715 716 // check if method can be accessed by the referring class 717 check_method_accessability(current_klass, 718 resolved_klass, 719 KlassHandle(THREAD, resolved_method->method_holder()), 720 resolved_method, 721 CHECK_NULL); 722 723 // check loader constraints 724 check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL); 725 } 726 727 return resolved_method; 728 } 729 730 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, 731 bool nostatics, TRAPS) { 732 733 KlassHandle resolved_klass = link_info.resolved_klass(); 734 735 // check if klass is interface 736 if (!resolved_klass->is_interface()) { 737 ResourceMark rm(THREAD); 738 char buf[200]; 739 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); 740 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 741 } 742 743 // lookup method in this interface or its super, java.lang.Object 744 // JDK8: also look for static methods 745 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); 746 747 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { 748 // lookup method in all the super-interfaces 749 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL); 766 767 // check if method can be accessed by the referring class 768 check_method_accessability(current_klass, 769 resolved_klass, 770 KlassHandle(THREAD, resolved_method->method_holder()), 771 resolved_method, 772 CHECK_NULL); 773 774 check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL); 775 } 776 777 if (nostatics && resolved_method->is_static()) { 778 ResourceMark rm(THREAD); 779 char buf[200]; 780 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", 781 Method::name_and_sig_as_C_string(resolved_klass(), 782 resolved_method->name(), resolved_method->signature())); 783 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 784 } 785 786 if (TraceItables && Verbose) { 787 trace_method_resolution("invokeinterface resolved method: caller-class", 788 link_info.current_klass(), resolved_klass, resolved_method); 789 tty->cr(); 790 } 791 792 return resolved_method; 793 } 794 795 //------------------------------------------------------------------------------------------------------------------------ 796 // Field resolution 797 798 void LinkResolver::check_field_accessability(KlassHandle ref_klass, 799 KlassHandle resolved_klass, 800 KlassHandle sel_klass, 801 const fieldDescriptor& fd, 802 TRAPS) { 803 if (!Reflection::verify_field_access(ref_klass(), 804 resolved_klass(), 805 sel_klass(), 806 fd.access_flags(), 807 true)) { 808 ResourceMark rm(THREAD); 809 Exceptions::fthrow( 1014 Method::name_and_sig_as_C_string(resolved_klass(), 1015 resolved_method->name(), 1016 resolved_method->signature()), 1017 current_klass->external_name()); 1018 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1019 } 1020 } 1021 1022 // check if not static 1023 if (resolved_method->is_static()) { 1024 ResourceMark rm(THREAD); 1025 char buf[200]; 1026 jio_snprintf(buf, sizeof(buf), 1027 "Expecting non-static method %s", 1028 Method::name_and_sig_as_C_string(resolved_klass(), 1029 resolved_method->name(), 1030 resolved_method->signature())); 1031 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1032 } 1033 1034 if (TraceItables && Verbose) { 1035 trace_method_resolution("invokespecial resolved method: caller-class:", 1036 current_klass, resolved_klass, resolved_method); 1037 tty->cr(); 1038 } 1039 1040 return resolved_method; 1041 } 1042 1043 // throws runtime exceptions 1044 void LinkResolver::runtime_resolve_special_method(CallInfo& result, 1045 const methodHandle& resolved_method, 1046 KlassHandle resolved_klass, 1047 KlassHandle current_klass, 1048 bool check_access, TRAPS) { 1049 1050 // resolved method is selected method unless we have an old-style lookup 1051 // for a superclass method 1052 // Invokespecial for a superinterface, resolved method is selected method, 1053 // no checks for shadowing 1054 methodHandle sel_method(THREAD, resolved_method()); 1055 1056 // check if this is an old-style super call and do a new lookup if so 1057 { KlassHandle method_klass = KlassHandle(THREAD, 1086 1087 // check if not static 1088 if (sel_method->is_static()) { 1089 ResourceMark rm(THREAD); 1090 char buf[200]; 1091 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), 1092 resolved_method->name(), 1093 resolved_method->signature())); 1094 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1095 } 1096 1097 // check if abstract 1098 if (sel_method->is_abstract()) { 1099 ResourceMark rm(THREAD); 1100 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1101 Method::name_and_sig_as_C_string(resolved_klass(), 1102 sel_method->name(), 1103 sel_method->signature())); 1104 } 1105 1106 if (TraceItables && Verbose) { 1107 trace_method_resolution("invokespecial selected method: resolved-class:", 1108 resolved_klass, resolved_klass, sel_method); 1109 tty->cr(); 1110 } 1111 1112 // setup result 1113 result.set_static(resolved_klass, sel_method, CHECK); 1114 } 1115 1116 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, 1117 const LinkInfo& link_info, 1118 bool check_null_and_abstract, TRAPS) { 1119 methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK); 1120 runtime_resolve_virtual_method(result, resolved_method, 1121 link_info.resolved_klass(), 1122 recv, receiver_klass, 1123 check_null_and_abstract, CHECK); 1124 } 1125 1126 // throws linktime exceptions 1127 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, 1128 TRAPS) { 1129 // normal method resolution 1140 ResourceMark rm(THREAD); 1141 char buf[200]; 1142 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s", 1143 Method::name_and_sig_as_C_string(resolved_klass(), 1144 resolved_method->name(), 1145 resolved_method->signature()), 1146 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name())); 1147 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1148 } 1149 1150 // check if not static 1151 if (resolved_method->is_static()) { 1152 ResourceMark rm(THREAD); 1153 char buf[200]; 1154 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), 1155 resolved_method->name(), 1156 resolved_method->signature())); 1157 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1158 } 1159 1160 if (PrintVtables && Verbose) { 1161 trace_method_resolution("invokevirtual resolved method: caller-class:", 1162 current_klass, resolved_klass, resolved_method); 1163 tty->cr(); 1164 } 1165 1166 return resolved_method; 1167 } 1168 1169 // throws runtime exceptions 1170 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, 1171 const methodHandle& resolved_method, 1172 KlassHandle resolved_klass, 1173 Handle recv, 1174 KlassHandle recv_klass, 1175 bool check_null_and_abstract, 1176 TRAPS) { 1177 1178 // setup default return values 1179 int vtable_index = Method::invalid_vtable_index; 1180 methodHandle selected_method; 1181 1182 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); 1183 1221 } 1222 1223 // check if method exists 1224 if (selected_method.is_null()) { 1225 ResourceMark rm(THREAD); 1226 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1227 Method::name_and_sig_as_C_string(resolved_klass(), 1228 resolved_method->name(), 1229 resolved_method->signature())); 1230 } 1231 1232 // check if abstract 1233 if (check_null_and_abstract && selected_method->is_abstract()) { 1234 ResourceMark rm(THREAD); 1235 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1236 Method::name_and_sig_as_C_string(resolved_klass(), 1237 selected_method->name(), 1238 selected_method->signature())); 1239 } 1240 1241 if (PrintVtables && Verbose) { 1242 trace_method_resolution("invokevirtual selected method: receiver-class:", 1243 recv_klass, resolved_klass, selected_method); 1244 tty->print_cr("vtable_index:%d", vtable_index); 1245 } 1246 // setup result 1247 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); 1248 } 1249 1250 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, 1251 const LinkInfo& link_info, 1252 bool check_null_and_abstract, TRAPS) { 1253 // throws linktime exceptions 1254 methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK); 1255 runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(), 1256 recv, recv_klass, check_null_and_abstract, CHECK); 1257 } 1258 1259 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info, 1260 TRAPS) { 1261 // normal interface method resolution 1262 methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL); 1263 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); 1264 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); 1320 resolved_method->signature())); 1321 } 1322 // check access 1323 // Throw Illegal Access Error if sel_method is not public. 1324 if (!sel_method->is_public()) { 1325 ResourceMark rm(THREAD); 1326 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 1327 Method::name_and_sig_as_C_string(recv_klass(), 1328 sel_method->name(), 1329 sel_method->signature())); 1330 } 1331 // check if abstract 1332 if (check_null_and_abstract && sel_method->is_abstract()) { 1333 ResourceMark rm(THREAD); 1334 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1335 Method::name_and_sig_as_C_string(recv_klass(), 1336 sel_method->name(), 1337 sel_method->signature())); 1338 } 1339 1340 if (TraceItables && Verbose) { 1341 trace_method_resolution("invokeinterface selected method: receiver-class", 1342 recv_klass, resolved_klass, sel_method); 1343 tty->cr(); 1344 } 1345 // setup result 1346 if (!resolved_method->has_itable_index()) { 1347 int vtable_index = resolved_method->vtable_index(); 1348 assert(vtable_index == sel_method->vtable_index(), "sanity check"); 1349 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); 1350 } else { 1351 int itable_index = resolved_method()->itable_index(); 1352 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); 1353 } 1354 } 1355 1356 1357 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( 1358 const LinkInfo& link_info) { 1359 EXCEPTION_MARK; 1360 methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD); 1361 if (HAS_PENDING_EXCEPTION) { 1362 CLEAR_PENDING_EXCEPTION; 1363 return methodHandle(); 1570 void LinkResolver::resolve_dynamic_call(CallInfo& result, 1571 Handle bootstrap_specifier, 1572 Symbol* method_name, Symbol* method_signature, 1573 KlassHandle current_klass, 1574 TRAPS) { 1575 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...) 1576 // The appendix argument is likely to be a freshly-created CallSite. 1577 Handle resolved_appendix; 1578 Handle resolved_method_type; 1579 methodHandle resolved_method = 1580 SystemDictionary::find_dynamic_call_site_invoker(current_klass, 1581 bootstrap_specifier, 1582 method_name, method_signature, 1583 &resolved_appendix, 1584 &resolved_method_type, 1585 THREAD); 1586 wrap_invokedynamic_exception(CHECK); 1587 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD); 1588 wrap_invokedynamic_exception(CHECK); 1589 } 1590 1591 #ifndef PRODUCT 1592 void LinkResolver::trace_method_resolution(const char* prefix, 1593 KlassHandle klass, 1594 KlassHandle resolved_klass, 1595 const methodHandle& method) { 1596 ResourceMark rm; 1597 tty->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", 1598 prefix, 1599 (klass.is_null() ? "<NULL>" : klass->internal_name()), 1600 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), 1601 Method::name_and_sig_as_C_string(resolved_klass(), 1602 method->name(), 1603 method->signature()), 1604 method->method_holder()->internal_name() 1605 ); 1606 method->access_flags().print_on(tty); 1607 if (method->is_default_method()) { 1608 tty->print("default "); 1609 } 1610 if (method->is_overpass()) { 1611 tty->print("overpass "); 1612 } 1613 } 1614 #endif // PRODUCT | 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 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/defaultMethods.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "compiler/compileBroker.hpp" 30 #include "gc/shared/collectedHeap.inline.hpp" 31 #include "interpreter/bytecode.hpp" 32 #include "interpreter/interpreterRuntime.hpp" 33 #include "interpreter/linkResolver.hpp" 34 #include "logging/log.hpp" 35 #include "memory/resourceArea.hpp" 36 #include "memory/universe.inline.hpp" 37 #include "oops/instanceKlass.hpp" 38 #include "oops/method.hpp" 39 #include "oops/objArrayOop.hpp" 40 #include "oops/oop.inline.hpp" 41 #include "prims/methodHandles.hpp" 42 #include "prims/nativeLookup.hpp" 43 #include "runtime/compilationPolicy.hpp" 44 #include "runtime/fieldDescriptor.hpp" 45 #include "runtime/frame.inline.hpp" 46 #include "runtime/handles.inline.hpp" 47 #include "runtime/reflection.hpp" 48 #include "runtime/signature.hpp" 49 #include "runtime/thread.inline.hpp" 50 #include "runtime/vmThread.hpp" 51 52 53 //------------------------------------------------------------------------------------------------------------------------ 54 // Implementation of CallInfo 55 56 57 void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) { 58 int vtable_index = Method::nonvirtual_vtable_index; 712 713 // 5. access checks, access checking may be turned off when calling from within the VM. 714 KlassHandle current_klass = link_info.current_klass(); 715 if (link_info.check_access()) { 716 assert(current_klass.not_null() , "current_klass should not be null"); 717 718 // check if method can be accessed by the referring class 719 check_method_accessability(current_klass, 720 resolved_klass, 721 KlassHandle(THREAD, resolved_method->method_holder()), 722 resolved_method, 723 CHECK_NULL); 724 725 // check loader constraints 726 check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL); 727 } 728 729 return resolved_method; 730 } 731 732 static void trace_method_resolution(const char* prefix, 733 KlassHandle klass, 734 KlassHandle resolved_klass, 735 const methodHandle& method, 736 bool logitables, 737 int index = -1) { 738 #ifndef PRODUCT 739 ResourceMark rm; 740 outputStream* st; 741 if (logitables) { 742 st = LogHandle(itables)::trace_stream(); 743 } else { 744 st = LogHandle(vtables)::trace_stream(); 745 } 746 st->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", 747 prefix, 748 (klass.is_null() ? "<NULL>" : klass->internal_name()), 749 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), 750 Method::name_and_sig_as_C_string(resolved_klass(), 751 method->name(), 752 method->signature()), 753 method->method_holder()->internal_name()); 754 method->print_linkage_flags(st); 755 if (index != -1) { 756 st->print("vtable_index:%d", index); 757 } 758 st->cr(); 759 #endif // PRODUCT 760 } 761 762 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, 763 bool nostatics, TRAPS) { 764 765 KlassHandle resolved_klass = link_info.resolved_klass(); 766 767 // check if klass is interface 768 if (!resolved_klass->is_interface()) { 769 ResourceMark rm(THREAD); 770 char buf[200]; 771 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); 772 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 773 } 774 775 // lookup method in this interface or its super, java.lang.Object 776 // JDK8: also look for static methods 777 methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); 778 779 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { 780 // lookup method in all the super-interfaces 781 resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL); 798 799 // check if method can be accessed by the referring class 800 check_method_accessability(current_klass, 801 resolved_klass, 802 KlassHandle(THREAD, resolved_method->method_holder()), 803 resolved_method, 804 CHECK_NULL); 805 806 check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL); 807 } 808 809 if (nostatics && resolved_method->is_static()) { 810 ResourceMark rm(THREAD); 811 char buf[200]; 812 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", 813 Method::name_and_sig_as_C_string(resolved_klass(), 814 resolved_method->name(), resolved_method->signature())); 815 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 816 } 817 818 if (develop_log_is_enabled(Trace, itables)) { 819 trace_method_resolution("invokeinterface resolved method: caller-class", 820 link_info.current_klass(), resolved_klass, 821 resolved_method, true); 822 } 823 824 return resolved_method; 825 } 826 827 //------------------------------------------------------------------------------------------------------------------------ 828 // Field resolution 829 830 void LinkResolver::check_field_accessability(KlassHandle ref_klass, 831 KlassHandle resolved_klass, 832 KlassHandle sel_klass, 833 const fieldDescriptor& fd, 834 TRAPS) { 835 if (!Reflection::verify_field_access(ref_klass(), 836 resolved_klass(), 837 sel_klass(), 838 fd.access_flags(), 839 true)) { 840 ResourceMark rm(THREAD); 841 Exceptions::fthrow( 1046 Method::name_and_sig_as_C_string(resolved_klass(), 1047 resolved_method->name(), 1048 resolved_method->signature()), 1049 current_klass->external_name()); 1050 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1051 } 1052 } 1053 1054 // check if not static 1055 if (resolved_method->is_static()) { 1056 ResourceMark rm(THREAD); 1057 char buf[200]; 1058 jio_snprintf(buf, sizeof(buf), 1059 "Expecting non-static method %s", 1060 Method::name_and_sig_as_C_string(resolved_klass(), 1061 resolved_method->name(), 1062 resolved_method->signature())); 1063 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1064 } 1065 1066 if (develop_log_is_enabled(Trace, itables)) { 1067 trace_method_resolution("invokespecial resolved method: caller-class:", 1068 current_klass, resolved_klass, resolved_method, true); 1069 } 1070 1071 return resolved_method; 1072 } 1073 1074 // throws runtime exceptions 1075 void LinkResolver::runtime_resolve_special_method(CallInfo& result, 1076 const methodHandle& resolved_method, 1077 KlassHandle resolved_klass, 1078 KlassHandle current_klass, 1079 bool check_access, TRAPS) { 1080 1081 // resolved method is selected method unless we have an old-style lookup 1082 // for a superclass method 1083 // Invokespecial for a superinterface, resolved method is selected method, 1084 // no checks for shadowing 1085 methodHandle sel_method(THREAD, resolved_method()); 1086 1087 // check if this is an old-style super call and do a new lookup if so 1088 { KlassHandle method_klass = KlassHandle(THREAD, 1117 1118 // check if not static 1119 if (sel_method->is_static()) { 1120 ResourceMark rm(THREAD); 1121 char buf[200]; 1122 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), 1123 resolved_method->name(), 1124 resolved_method->signature())); 1125 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1126 } 1127 1128 // check if abstract 1129 if (sel_method->is_abstract()) { 1130 ResourceMark rm(THREAD); 1131 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1132 Method::name_and_sig_as_C_string(resolved_klass(), 1133 sel_method->name(), 1134 sel_method->signature())); 1135 } 1136 1137 if (develop_log_is_enabled(Trace, itables)) { 1138 trace_method_resolution("invokespecial selected method: resolved-class:", 1139 resolved_klass, resolved_klass, sel_method, true); 1140 } 1141 1142 // setup result 1143 result.set_static(resolved_klass, sel_method, CHECK); 1144 } 1145 1146 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, 1147 const LinkInfo& link_info, 1148 bool check_null_and_abstract, TRAPS) { 1149 methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK); 1150 runtime_resolve_virtual_method(result, resolved_method, 1151 link_info.resolved_klass(), 1152 recv, receiver_klass, 1153 check_null_and_abstract, CHECK); 1154 } 1155 1156 // throws linktime exceptions 1157 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, 1158 TRAPS) { 1159 // normal method resolution 1170 ResourceMark rm(THREAD); 1171 char buf[200]; 1172 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s", 1173 Method::name_and_sig_as_C_string(resolved_klass(), 1174 resolved_method->name(), 1175 resolved_method->signature()), 1176 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name())); 1177 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1178 } 1179 1180 // check if not static 1181 if (resolved_method->is_static()) { 1182 ResourceMark rm(THREAD); 1183 char buf[200]; 1184 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), 1185 resolved_method->name(), 1186 resolved_method->signature())); 1187 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1188 } 1189 1190 if (develop_log_is_enabled(Trace, vtables)) { 1191 trace_method_resolution("invokevirtual resolved method: caller-class:", 1192 current_klass, resolved_klass, resolved_method, false); 1193 } 1194 1195 return resolved_method; 1196 } 1197 1198 // throws runtime exceptions 1199 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, 1200 const methodHandle& resolved_method, 1201 KlassHandle resolved_klass, 1202 Handle recv, 1203 KlassHandle recv_klass, 1204 bool check_null_and_abstract, 1205 TRAPS) { 1206 1207 // setup default return values 1208 int vtable_index = Method::invalid_vtable_index; 1209 methodHandle selected_method; 1210 1211 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); 1212 1250 } 1251 1252 // check if method exists 1253 if (selected_method.is_null()) { 1254 ResourceMark rm(THREAD); 1255 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1256 Method::name_and_sig_as_C_string(resolved_klass(), 1257 resolved_method->name(), 1258 resolved_method->signature())); 1259 } 1260 1261 // check if abstract 1262 if (check_null_and_abstract && selected_method->is_abstract()) { 1263 ResourceMark rm(THREAD); 1264 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1265 Method::name_and_sig_as_C_string(resolved_klass(), 1266 selected_method->name(), 1267 selected_method->signature())); 1268 } 1269 1270 if (develop_log_is_enabled(Trace, vtables)) { 1271 trace_method_resolution("invokevirtual selected method: receiver-class:", 1272 recv_klass, resolved_klass, selected_method, 1273 false, vtable_index); 1274 } 1275 // setup result 1276 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); 1277 } 1278 1279 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, 1280 const LinkInfo& link_info, 1281 bool check_null_and_abstract, TRAPS) { 1282 // throws linktime exceptions 1283 methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK); 1284 runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(), 1285 recv, recv_klass, check_null_and_abstract, CHECK); 1286 } 1287 1288 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info, 1289 TRAPS) { 1290 // normal interface method resolution 1291 methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL); 1292 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); 1293 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); 1349 resolved_method->signature())); 1350 } 1351 // check access 1352 // Throw Illegal Access Error if sel_method is not public. 1353 if (!sel_method->is_public()) { 1354 ResourceMark rm(THREAD); 1355 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 1356 Method::name_and_sig_as_C_string(recv_klass(), 1357 sel_method->name(), 1358 sel_method->signature())); 1359 } 1360 // check if abstract 1361 if (check_null_and_abstract && sel_method->is_abstract()) { 1362 ResourceMark rm(THREAD); 1363 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1364 Method::name_and_sig_as_C_string(recv_klass(), 1365 sel_method->name(), 1366 sel_method->signature())); 1367 } 1368 1369 if (develop_log_is_enabled(Trace, itables)) { 1370 trace_method_resolution("invokeinterface selected method: receiver-class", 1371 recv_klass, resolved_klass, sel_method, true); 1372 } 1373 // setup result 1374 if (!resolved_method->has_itable_index()) { 1375 int vtable_index = resolved_method->vtable_index(); 1376 assert(vtable_index == sel_method->vtable_index(), "sanity check"); 1377 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); 1378 } else { 1379 int itable_index = resolved_method()->itable_index(); 1380 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); 1381 } 1382 } 1383 1384 1385 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( 1386 const LinkInfo& link_info) { 1387 EXCEPTION_MARK; 1388 methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD); 1389 if (HAS_PENDING_EXCEPTION) { 1390 CLEAR_PENDING_EXCEPTION; 1391 return methodHandle(); 1598 void LinkResolver::resolve_dynamic_call(CallInfo& result, 1599 Handle bootstrap_specifier, 1600 Symbol* method_name, Symbol* method_signature, 1601 KlassHandle current_klass, 1602 TRAPS) { 1603 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...) 1604 // The appendix argument is likely to be a freshly-created CallSite. 1605 Handle resolved_appendix; 1606 Handle resolved_method_type; 1607 methodHandle resolved_method = 1608 SystemDictionary::find_dynamic_call_site_invoker(current_klass, 1609 bootstrap_specifier, 1610 method_name, method_signature, 1611 &resolved_appendix, 1612 &resolved_method_type, 1613 THREAD); 1614 wrap_invokedynamic_exception(CHECK); 1615 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD); 1616 wrap_invokedynamic_exception(CHECK); 1617 } |