src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8141564 Sdiff src/share/vm/interpreter

src/share/vm/interpreter/linkResolver.cpp

Print this page




  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
src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File