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
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();
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/objArrayOop.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "prims/methodHandles.hpp"
41 #include "prims/nativeLookup.hpp"
42 #include "runtime/compilationPolicy.hpp"
43 #include "runtime/fieldDescriptor.hpp"
44 #include "runtime/frame.inline.hpp"
45 #include "runtime/handles.inline.hpp"
46 #include "runtime/reflection.hpp"
47 #include "runtime/signature.hpp"
48 #include "runtime/thread.inline.hpp"
49 #include "runtime/vmThread.hpp"
50
51
52 //------------------------------------------------------------------------------------------------------------------------
53 // Implementation of CallInfo
54
767
768 // check if method can be accessed by the referring class
769 check_method_accessability(current_klass,
770 resolved_klass,
771 KlassHandle(THREAD, resolved_method->method_holder()),
772 resolved_method,
773 CHECK_NULL);
774
775 check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
776 }
777
778 if (nostatics && resolved_method->is_static()) {
779 ResourceMark rm(THREAD);
780 char buf[200];
781 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
782 Method::name_and_sig_as_C_string(resolved_klass(),
783 resolved_method->name(), resolved_method->signature()));
784 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
785 }
786
787 if (develop_log_is_enabled(Trace, itables)) {
788 ResourceMark rm;
789 outputStream* logst = LogHandle(itables)::trace_stream();
790 trace_method_resolution(logst, "invokeinterface resolved method: caller-class",
791 link_info.current_klass(), resolved_klass, resolved_method);
792 logst->cr();
793 }
794
795 return resolved_method;
796 }
797
798 //------------------------------------------------------------------------------------------------------------------------
799 // Field resolution
800
801 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
802 KlassHandle resolved_klass,
803 KlassHandle sel_klass,
804 const fieldDescriptor& fd,
805 TRAPS) {
806 if (!Reflection::verify_field_access(ref_klass(),
807 resolved_klass(),
808 sel_klass(),
809 fd.access_flags(),
810 true)) {
811 ResourceMark rm(THREAD);
812 Exceptions::fthrow(
1017 Method::name_and_sig_as_C_string(resolved_klass(),
1018 resolved_method->name(),
1019 resolved_method->signature()),
1020 current_klass->external_name());
1021 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1022 }
1023 }
1024
1025 // check if not static
1026 if (resolved_method->is_static()) {
1027 ResourceMark rm(THREAD);
1028 char buf[200];
1029 jio_snprintf(buf, sizeof(buf),
1030 "Expecting non-static method %s",
1031 Method::name_and_sig_as_C_string(resolved_klass(),
1032 resolved_method->name(),
1033 resolved_method->signature()));
1034 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1035 }
1036
1037 if (develop_log_is_enabled(Trace, itables)) {
1038 ResourceMark rm;
1039 outputStream* logst = LogHandle(itables)::trace_stream();
1040 trace_method_resolution(logst, "invokespecial resolved method: caller-class:",
1041 current_klass, resolved_klass, resolved_method);
1042 logst->cr();
1043 }
1044
1045 return resolved_method;
1046 }
1047
1048 // throws runtime exceptions
1049 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1050 const methodHandle& resolved_method,
1051 KlassHandle resolved_klass,
1052 KlassHandle current_klass,
1053 bool check_access, TRAPS) {
1054
1055 // resolved method is selected method unless we have an old-style lookup
1056 // for a superclass method
1057 // Invokespecial for a superinterface, resolved method is selected method,
1058 // no checks for shadowing
1059 methodHandle sel_method(THREAD, resolved_method());
1060
1061 // check if this is an old-style super call and do a new lookup if so
1062 { KlassHandle method_klass = KlassHandle(THREAD,
1091
1092 // check if not static
1093 if (sel_method->is_static()) {
1094 ResourceMark rm(THREAD);
1095 char buf[200];
1096 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1097 resolved_method->name(),
1098 resolved_method->signature()));
1099 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1100 }
1101
1102 // check if abstract
1103 if (sel_method->is_abstract()) {
1104 ResourceMark rm(THREAD);
1105 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1106 Method::name_and_sig_as_C_string(resolved_klass(),
1107 sel_method->name(),
1108 sel_method->signature()));
1109 }
1110
1111 if (develop_log_is_enabled(Trace, itables)) {
1112 ResourceMark rm;
1113 outputStream* logst = LogHandle(itables)::trace_stream();
1114 trace_method_resolution(logst, "invokespecial selected method: resolved-class:",
1115 resolved_klass, resolved_klass, sel_method);
1116 logst->cr();
1117 }
1118
1119 // setup result
1120 result.set_static(resolved_klass, sel_method, CHECK);
1121 }
1122
1123 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass,
1124 const LinkInfo& link_info,
1125 bool check_null_and_abstract, TRAPS) {
1126 methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK);
1127 runtime_resolve_virtual_method(result, resolved_method,
1128 link_info.resolved_klass(),
1129 recv, receiver_klass,
1130 check_null_and_abstract, CHECK);
1131 }
1132
1133 // throws linktime exceptions
1134 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
1135 TRAPS) {
1136 // normal method resolution
1147 ResourceMark rm(THREAD);
1148 char buf[200];
1149 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
1150 Method::name_and_sig_as_C_string(resolved_klass(),
1151 resolved_method->name(),
1152 resolved_method->signature()),
1153 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
1154 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1155 }
1156
1157 // check if not static
1158 if (resolved_method->is_static()) {
1159 ResourceMark rm(THREAD);
1160 char buf[200];
1161 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1162 resolved_method->name(),
1163 resolved_method->signature()));
1164 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1165 }
1166
1167 if (develop_log_is_enabled(Trace, vtables)) {
1168 ResourceMark rm(THREAD);
1169 outputStream* logst = LogHandle(vtables)::trace_stream();
1170 trace_method_resolution(logst, "invokevirtual resolved method: caller-class:",
1171 current_klass, resolved_klass, resolved_method);
1172 logst->cr();
1173 }
1174
1175 return resolved_method;
1176 }
1177
1178 // throws runtime exceptions
1179 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
1180 const methodHandle& resolved_method,
1181 KlassHandle resolved_klass,
1182 Handle recv,
1183 KlassHandle recv_klass,
1184 bool check_null_and_abstract,
1185 TRAPS) {
1186
1187 // setup default return values
1188 int vtable_index = Method::invalid_vtable_index;
1189 methodHandle selected_method;
1190
1191 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
1192
1230 }
1231
1232 // check if method exists
1233 if (selected_method.is_null()) {
1234 ResourceMark rm(THREAD);
1235 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1236 Method::name_and_sig_as_C_string(resolved_klass(),
1237 resolved_method->name(),
1238 resolved_method->signature()));
1239 }
1240
1241 // check if abstract
1242 if (check_null_and_abstract && selected_method->is_abstract()) {
1243 ResourceMark rm(THREAD);
1244 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1245 Method::name_and_sig_as_C_string(resolved_klass(),
1246 selected_method->name(),
1247 selected_method->signature()));
1248 }
1249
1250 if (develop_log_is_enabled(Trace, vtables)) {
1251 ResourceMark rm;
1252 outputStream* logst = LogHandle(vtables)::trace_stream();
1253 trace_method_resolution(logst, "invokevirtual selected method: receiver-class:",
1254 recv_klass, resolved_klass, selected_method);
1255 logst->print_cr("vtable_index:%d", vtable_index);
1256 }
1257 // setup result
1258 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1259 }
1260
1261 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
1262 const LinkInfo& link_info,
1263 bool check_null_and_abstract, TRAPS) {
1264 // throws linktime exceptions
1265 methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1266 runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1267 recv, recv_klass, check_null_and_abstract, CHECK);
1268 }
1269
1270 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
1271 TRAPS) {
1272 // normal interface method resolution
1273 methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL);
1274 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
1275 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
1331 resolved_method->signature()));
1332 }
1333 // check access
1334 // Throw Illegal Access Error if sel_method is not public.
1335 if (!sel_method->is_public()) {
1336 ResourceMark rm(THREAD);
1337 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1338 Method::name_and_sig_as_C_string(recv_klass(),
1339 sel_method->name(),
1340 sel_method->signature()));
1341 }
1342 // check if abstract
1343 if (check_null_and_abstract && sel_method->is_abstract()) {
1344 ResourceMark rm(THREAD);
1345 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1346 Method::name_and_sig_as_C_string(recv_klass(),
1347 sel_method->name(),
1348 sel_method->signature()));
1349 }
1350
1351 if (develop_log_is_enabled(Trace, itables)) {
1352 ResourceMark rm;
1353 outputStream* logst = LogHandle(itables)::trace_stream();
1354 trace_method_resolution(logst, "invokeinterface selected method: receiver-class",
1355 recv_klass, resolved_klass, sel_method);
1356 logst->cr();
1357 }
1358 // setup result
1359 if (!resolved_method->has_itable_index()) {
1360 int vtable_index = resolved_method->vtable_index();
1361 assert(vtable_index == sel_method->vtable_index(), "sanity check");
1362 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1363 } else {
1364 int itable_index = resolved_method()->itable_index();
1365 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
1366 }
1367 }
1368
1369
1370 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
1371 const LinkInfo& link_info) {
1372 EXCEPTION_MARK;
1373 methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD);
1374 if (HAS_PENDING_EXCEPTION) {
1375 CLEAR_PENDING_EXCEPTION;
1376 return methodHandle();
1585 Symbol* method_name, Symbol* method_signature,
1586 KlassHandle current_klass,
1587 TRAPS) {
1588 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
1589 // The appendix argument is likely to be a freshly-created CallSite.
1590 Handle resolved_appendix;
1591 Handle resolved_method_type;
1592 methodHandle resolved_method =
1593 SystemDictionary::find_dynamic_call_site_invoker(current_klass,
1594 bootstrap_specifier,
1595 method_name, method_signature,
1596 &resolved_appendix,
1597 &resolved_method_type,
1598 THREAD);
1599 wrap_invokedynamic_exception(CHECK);
1600 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
1601 wrap_invokedynamic_exception(CHECK);
1602 }
1603
1604 #ifndef PRODUCT
1605 // Must call with a ResourceMark
1606 void LinkResolver::trace_method_resolution(outputStream* st,
1607 const char* prefix,
1608 KlassHandle klass,
1609 KlassHandle resolved_klass,
1610 const methodHandle& method) {
1611 st->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
1612 prefix,
1613 (klass.is_null() ? "<NULL>" : klass->internal_name()),
1614 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
1615 Method::name_and_sig_as_C_string(resolved_klass(),
1616 method->name(),
1617 method->signature()),
1618 method->method_holder()->internal_name()
1619 );
1620 method->access_flags().print_on(st);
1621 if (method->is_default_method()) {
1622 st->print("default ");
1623 }
1624 if (method->is_overpass()) {
1625 st->print("overpass ");
1626 }
1627 }
1628 #endif // PRODUCT
|