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

src/share/vm/interpreter/linkResolver.cpp

Print this page




  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/symbolTable.hpp"
  28 #include "classfile/systemDictionary.hpp"
  29 #include "classfile/vmSymbols.hpp"
  30 #include "compiler/compileBroker.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "interpreter/bytecode.hpp"
  33 #include "interpreter/interpreterRuntime.hpp"
  34 #include "interpreter/linkResolver.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 
  55 
  56 void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) {
  57   int vtable_index = Method::nonvirtual_vtable_index;


 711 
 712   // 5. access checks, access checking may be turned off when calling from within the VM.
 713   KlassHandle current_klass = link_info.current_klass();
 714   if (link_info.check_access()) {
 715     assert(current_klass.not_null() , "current_klass should not be null");
 716 
 717     // check if method can be accessed by the referring class
 718     check_method_accessability(current_klass,
 719                                resolved_klass,
 720                                KlassHandle(THREAD, resolved_method->method_holder()),
 721                                resolved_method,
 722                                CHECK_NULL);
 723 
 724     // check loader constraints
 725     check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
 726   }
 727 
 728   return resolved_method;
 729 }
 730 






























 731 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
 732                                                     bool nostatics, TRAPS) {
 733 
 734   KlassHandle resolved_klass = link_info.resolved_klass();
 735 
 736   // check if klass is interface
 737   if (!resolved_klass->is_interface()) {
 738     ResourceMark rm(THREAD);
 739     char buf[200];
 740     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 741     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 742   }
 743 
 744   // lookup method in this interface or its super, java.lang.Object
 745   // JDK8: also look for static methods
 746   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 747 
 748   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 749     // lookup method in all the super-interfaces
 750     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);


 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 (TraceItables && Verbose) {
 788     trace_method_resolution("invokeinterface resolved method: caller-class",
 789                             link_info.current_klass(), resolved_klass, resolved_method);
 790     tty->cr();
 791   }
 792 
 793   return resolved_method;
 794 }
 795 
 796 //------------------------------------------------------------------------------------------------------------------------
 797 // Field resolution
 798 
 799 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
 800                                              KlassHandle resolved_klass,
 801                                              KlassHandle sel_klass,
 802                                              const fieldDescriptor& fd,
 803                                              TRAPS) {
 804   if (!Reflection::verify_field_access(ref_klass(),
 805                                        resolved_klass(),
 806                                        sel_klass(),
 807                                        fd.access_flags(),
 808                                        true)) {
 809     ResourceMark rm(THREAD);
 810     Exceptions::fthrow(


1015                    Method::name_and_sig_as_C_string(resolved_klass(),
1016                                                          resolved_method->name(),
1017                                                          resolved_method->signature()),
1018                    current_klass->external_name());
1019       THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1020     }
1021   }
1022 
1023   // check if not static
1024   if (resolved_method->is_static()) {
1025     ResourceMark rm(THREAD);
1026     char buf[200];
1027     jio_snprintf(buf, sizeof(buf),
1028                  "Expecting non-static method %s",
1029                  Method::name_and_sig_as_C_string(resolved_klass(),
1030                                                   resolved_method->name(),
1031                                                   resolved_method->signature()));
1032     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1033   }
1034 
1035   if (TraceItables && Verbose) {
1036     trace_method_resolution("invokespecial resolved method: caller-class:",
1037                             current_klass, resolved_klass, resolved_method);
1038     tty->cr();
1039   }
1040 
1041   return resolved_method;
1042 }
1043 
1044 // throws runtime exceptions
1045 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1046                                                   const methodHandle& resolved_method,
1047                                                   KlassHandle resolved_klass,
1048                                                   KlassHandle current_klass,
1049                                                   bool check_access, TRAPS) {
1050 
1051   // resolved method is selected method unless we have an old-style lookup
1052   // for a superclass method
1053   // Invokespecial for a superinterface, resolved method is selected method,
1054   // no checks for shadowing
1055   methodHandle sel_method(THREAD, resolved_method());
1056 
1057   // check if this is an old-style super call and do a new lookup if so
1058   { KlassHandle method_klass  = KlassHandle(THREAD,


1087 
1088   // check if not static
1089   if (sel_method->is_static()) {
1090     ResourceMark rm(THREAD);
1091     char buf[200];
1092     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1093                                                                                                              resolved_method->name(),
1094                                                                                                              resolved_method->signature()));
1095     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1096   }
1097 
1098   // check if abstract
1099   if (sel_method->is_abstract()) {
1100     ResourceMark rm(THREAD);
1101     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1102               Method::name_and_sig_as_C_string(resolved_klass(),
1103                                                sel_method->name(),
1104                                                sel_method->signature()));
1105   }
1106 
1107   if (TraceItables && Verbose) {
1108     trace_method_resolution("invokespecial selected method: resolved-class:",
1109                             resolved_klass, resolved_klass, sel_method);
1110     tty->cr();
1111   }
1112 
1113   // setup result
1114   result.set_static(resolved_klass, sel_method, CHECK);
1115 }
1116 
1117 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass,
1118                                         const LinkInfo& link_info,
1119                                         bool check_null_and_abstract, TRAPS) {
1120   methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK);
1121   runtime_resolve_virtual_method(result, resolved_method,
1122                                  link_info.resolved_klass(),
1123                                  recv, receiver_klass,
1124                                  check_null_and_abstract, CHECK);
1125 }
1126 
1127 // throws linktime exceptions
1128 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
1129                                                            TRAPS) {
1130   // normal method resolution


1141     ResourceMark rm(THREAD);
1142     char buf[200];
1143     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
1144                  Method::name_and_sig_as_C_string(resolved_klass(),
1145                                                   resolved_method->name(),
1146                                                   resolved_method->signature()),
1147                    (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
1148     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1149   }
1150 
1151   // check if not static
1152   if (resolved_method->is_static()) {
1153     ResourceMark rm(THREAD);
1154     char buf[200];
1155     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1156                                                                                                              resolved_method->name(),
1157                                                                                                              resolved_method->signature()));
1158     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1159   }
1160 
1161   if (PrintVtables && Verbose) {
1162     trace_method_resolution("invokevirtual resolved method: caller-class:",
1163                             current_klass, resolved_klass, resolved_method);
1164     tty->cr();
1165   }
1166 
1167   return resolved_method;
1168 }
1169 
1170 // throws runtime exceptions
1171 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
1172                                                   const methodHandle& resolved_method,
1173                                                   KlassHandle resolved_klass,
1174                                                   Handle recv,
1175                                                   KlassHandle recv_klass,
1176                                                   bool check_null_and_abstract,
1177                                                   TRAPS) {
1178 
1179   // setup default return values
1180   int vtable_index = Method::invalid_vtable_index;
1181   methodHandle selected_method;
1182 
1183   assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
1184 


1222   }
1223 
1224   // check if method exists
1225   if (selected_method.is_null()) {
1226     ResourceMark rm(THREAD);
1227     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1228               Method::name_and_sig_as_C_string(resolved_klass(),
1229                                                       resolved_method->name(),
1230                                                       resolved_method->signature()));
1231   }
1232 
1233   // check if abstract
1234   if (check_null_and_abstract && selected_method->is_abstract()) {
1235     ResourceMark rm(THREAD);
1236     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1237               Method::name_and_sig_as_C_string(resolved_klass(),
1238                                                       selected_method->name(),
1239                                                       selected_method->signature()));
1240   }
1241 
1242   if (PrintVtables && Verbose) {
1243     trace_method_resolution("invokevirtual selected method: receiver-class:",
1244                             recv_klass, resolved_klass, selected_method);
1245     tty->print_cr("vtable_index:%d", vtable_index);
1246   }
1247   // setup result
1248   result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1249 }
1250 
1251 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
1252                                           const LinkInfo& link_info,
1253                                           bool check_null_and_abstract, TRAPS) {
1254   // throws linktime exceptions
1255   methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1256   runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1257                                    recv, recv_klass, check_null_and_abstract, CHECK);
1258 }
1259 
1260 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
1261                                                              TRAPS) {
1262   // normal interface method resolution
1263   methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL);
1264   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
1265   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");


1321                                                     resolved_method->signature()));
1322   }
1323   // check access
1324   // Throw Illegal Access Error if sel_method is not public.
1325   if (!sel_method->is_public()) {
1326     ResourceMark rm(THREAD);
1327     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1328               Method::name_and_sig_as_C_string(recv_klass(),
1329                                                sel_method->name(),
1330                                                sel_method->signature()));
1331   }
1332   // check if abstract
1333   if (check_null_and_abstract && sel_method->is_abstract()) {
1334     ResourceMark rm(THREAD);
1335     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1336               Method::name_and_sig_as_C_string(recv_klass(),
1337                                                       sel_method->name(),
1338                                                       sel_method->signature()));
1339   }
1340 
1341   if (TraceItables && Verbose) {
1342     trace_method_resolution("invokeinterface selected method: receiver-class",
1343                             recv_klass, resolved_klass, sel_method);
1344     tty->cr();
1345   }
1346   // setup result
1347   if (!resolved_method->has_itable_index()) {
1348     int vtable_index = resolved_method->vtable_index();
1349     assert(vtable_index == sel_method->vtable_index(), "sanity check");
1350     result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1351   } else {
1352     int itable_index = resolved_method()->itable_index();
1353     result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
1354   }
1355 }
1356 
1357 
1358 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
1359                                                  const LinkInfo& link_info) {
1360   EXCEPTION_MARK;
1361   methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD);
1362   if (HAS_PENDING_EXCEPTION) {
1363     CLEAR_PENDING_EXCEPTION;
1364     return methodHandle();


1571 void LinkResolver::resolve_dynamic_call(CallInfo& result,
1572                                         Handle bootstrap_specifier,
1573                                         Symbol* method_name, Symbol* method_signature,
1574                                         KlassHandle current_klass,
1575                                         TRAPS) {
1576   // JSR 292:  this must resolve to an implicitly generated method MH.linkToCallSite(*...)
1577   // The appendix argument is likely to be a freshly-created CallSite.
1578   Handle       resolved_appendix;
1579   Handle       resolved_method_type;
1580   methodHandle resolved_method =
1581     SystemDictionary::find_dynamic_call_site_invoker(current_klass,
1582                                                      bootstrap_specifier,
1583                                                      method_name, method_signature,
1584                                                      &resolved_appendix,
1585                                                      &resolved_method_type,
1586                                                      THREAD);
1587   wrap_invokedynamic_exception(CHECK);
1588   result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
1589   wrap_invokedynamic_exception(CHECK);
1590 }
1591 
1592 #ifndef PRODUCT
1593 void LinkResolver::trace_method_resolution(const char* prefix,
1594                                            KlassHandle klass,
1595                                            KlassHandle resolved_klass,
1596                                            const methodHandle& method) {
1597   ResourceMark rm;
1598   tty->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
1599              prefix,
1600              (klass.is_null() ? "<NULL>" : klass->internal_name()),
1601              (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
1602              Method::name_and_sig_as_C_string(resolved_klass(),
1603                                               method->name(),
1604                                               method->signature()),
1605              method->method_holder()->internal_name()
1606              );
1607   method->access_flags().print_on(tty);
1608   if (method->is_default_method()) {
1609     tty->print("default ");
1610   }
1611   if (method->is_overpass()) {
1612     tty->print("overpass ");
1613   }
1614 }
1615 #endif // PRODUCT


  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/symbolTable.hpp"
  28 #include "classfile/systemDictionary.hpp"
  29 #include "classfile/vmSymbols.hpp"
  30 #include "compiler/compileBroker.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "interpreter/bytecode.hpp"
  33 #include "interpreter/interpreterRuntime.hpp"
  34 #include "interpreter/linkResolver.hpp"
  35 #include "logging/log.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "memory/universe.inline.hpp"
  38 #include "oops/instanceKlass.hpp"
  39 #include "oops/method.hpp"
  40 #include "oops/objArrayOop.hpp"
  41 #include "oops/oop.inline.hpp"
  42 #include "prims/methodHandles.hpp"
  43 #include "prims/nativeLookup.hpp"
  44 #include "runtime/compilationPolicy.hpp"
  45 #include "runtime/fieldDescriptor.hpp"
  46 #include "runtime/frame.inline.hpp"
  47 #include "runtime/handles.inline.hpp"
  48 #include "runtime/reflection.hpp"
  49 #include "runtime/signature.hpp"
  50 #include "runtime/thread.inline.hpp"
  51 #include "runtime/vmThread.hpp"
  52 
  53 
  54 //------------------------------------------------------------------------------------------------------------------------
  55 // Implementation of CallInfo
  56 
  57 
  58 void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) {
  59   int vtable_index = Method::nonvirtual_vtable_index;


 713 
 714   // 5. access checks, access checking may be turned off when calling from within the VM.
 715   KlassHandle current_klass = link_info.current_klass();
 716   if (link_info.check_access()) {
 717     assert(current_klass.not_null() , "current_klass should not be null");
 718 
 719     // check if method can be accessed by the referring class
 720     check_method_accessability(current_klass,
 721                                resolved_klass,
 722                                KlassHandle(THREAD, resolved_method->method_holder()),
 723                                resolved_method,
 724                                CHECK_NULL);
 725 
 726     // check loader constraints
 727     check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
 728   }
 729 
 730   return resolved_method;
 731 }
 732 
 733 static void trace_method_resolution(const char* prefix,
 734                                     KlassHandle klass,
 735                                     KlassHandle resolved_klass,
 736                                     const methodHandle& method,
 737                                     bool logitables,
 738                                     int index = -1) {
 739 #ifndef PRODUCT
 740   ResourceMark rm;
 741   outputStream* st;
 742   if (logitables) {
 743     st = LogHandle(itables)::trace_stream();
 744   } else {
 745     st = LogHandle(vtables)::trace_stream();
 746   }
 747   st->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
 748             prefix,
 749             (klass.is_null() ? "<NULL>" : klass->internal_name()),
 750             (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
 751             Method::name_and_sig_as_C_string(resolved_klass(),
 752                                              method->name(),
 753                                              method->signature()),
 754             method->method_holder()->internal_name());
 755   method->print_linkage_flags(st);
 756   if (index != -1) {
 757     st->print("vtable_index:%d", index);
 758   }
 759   st->cr();
 760 #endif // PRODUCT
 761 }
 762 
 763 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
 764                                                     bool nostatics, TRAPS) {
 765 
 766   KlassHandle resolved_klass = link_info.resolved_klass();
 767 
 768   // check if klass is interface
 769   if (!resolved_klass->is_interface()) {
 770     ResourceMark rm(THREAD);
 771     char buf[200];
 772     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 773     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 774   }
 775 
 776   // lookup method in this interface or its super, java.lang.Object
 777   // JDK8: also look for static methods
 778   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 779 
 780   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 781     // lookup method in all the super-interfaces
 782     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);


 799 
 800     // check if method can be accessed by the referring class
 801     check_method_accessability(current_klass,
 802                                resolved_klass,
 803                                KlassHandle(THREAD, resolved_method->method_holder()),
 804                                resolved_method,
 805                                CHECK_NULL);
 806 
 807     check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
 808   }
 809 
 810   if (nostatics && resolved_method->is_static()) {
 811     ResourceMark rm(THREAD);
 812     char buf[200];
 813     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
 814                  Method::name_and_sig_as_C_string(resolved_klass(),
 815                  resolved_method->name(), resolved_method->signature()));
 816     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 817   }
 818 
 819   if (develop_log_is_enabled(Trace, itables)) {
 820     trace_method_resolution("invokeinterface resolved method: caller-class",
 821                             link_info.current_klass(), resolved_klass,
 822                             resolved_method, true);
 823   }
 824 
 825   return resolved_method;
 826 }
 827 
 828 //------------------------------------------------------------------------------------------------------------------------
 829 // Field resolution
 830 
 831 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
 832                                              KlassHandle resolved_klass,
 833                                              KlassHandle sel_klass,
 834                                              const fieldDescriptor& fd,
 835                                              TRAPS) {
 836   if (!Reflection::verify_field_access(ref_klass(),
 837                                        resolved_klass(),
 838                                        sel_klass(),
 839                                        fd.access_flags(),
 840                                        true)) {
 841     ResourceMark rm(THREAD);
 842     Exceptions::fthrow(


1047                    Method::name_and_sig_as_C_string(resolved_klass(),
1048                                                          resolved_method->name(),
1049                                                          resolved_method->signature()),
1050                    current_klass->external_name());
1051       THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1052     }
1053   }
1054 
1055   // check if not static
1056   if (resolved_method->is_static()) {
1057     ResourceMark rm(THREAD);
1058     char buf[200];
1059     jio_snprintf(buf, sizeof(buf),
1060                  "Expecting non-static method %s",
1061                  Method::name_and_sig_as_C_string(resolved_klass(),
1062                                                   resolved_method->name(),
1063                                                   resolved_method->signature()));
1064     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1065   }
1066 
1067   if (develop_log_is_enabled(Trace, itables)) {
1068     trace_method_resolution("invokespecial resolved method: caller-class:",
1069                             current_klass, resolved_klass, resolved_method, true);

1070   }
1071 
1072   return resolved_method;
1073 }
1074 
1075 // throws runtime exceptions
1076 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
1077                                                   const methodHandle& resolved_method,
1078                                                   KlassHandle resolved_klass,
1079                                                   KlassHandle current_klass,
1080                                                   bool check_access, TRAPS) {
1081 
1082   // resolved method is selected method unless we have an old-style lookup
1083   // for a superclass method
1084   // Invokespecial for a superinterface, resolved method is selected method,
1085   // no checks for shadowing
1086   methodHandle sel_method(THREAD, resolved_method());
1087 
1088   // check if this is an old-style super call and do a new lookup if so
1089   { KlassHandle method_klass  = KlassHandle(THREAD,


1118 
1119   // check if not static
1120   if (sel_method->is_static()) {
1121     ResourceMark rm(THREAD);
1122     char buf[200];
1123     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1124                                                                                                              resolved_method->name(),
1125                                                                                                              resolved_method->signature()));
1126     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1127   }
1128 
1129   // check if abstract
1130   if (sel_method->is_abstract()) {
1131     ResourceMark rm(THREAD);
1132     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1133               Method::name_and_sig_as_C_string(resolved_klass(),
1134                                                sel_method->name(),
1135                                                sel_method->signature()));
1136   }
1137 
1138   if (develop_log_is_enabled(Trace, itables)) {
1139     trace_method_resolution("invokespecial selected method: resolved-class:",
1140                             resolved_klass, resolved_klass, sel_method, true);

1141   }
1142 
1143   // setup result
1144   result.set_static(resolved_klass, sel_method, CHECK);
1145 }
1146 
1147 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass,
1148                                         const LinkInfo& link_info,
1149                                         bool check_null_and_abstract, TRAPS) {
1150   methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK);
1151   runtime_resolve_virtual_method(result, resolved_method,
1152                                  link_info.resolved_klass(),
1153                                  recv, receiver_klass,
1154                                  check_null_and_abstract, CHECK);
1155 }
1156 
1157 // throws linktime exceptions
1158 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
1159                                                            TRAPS) {
1160   // normal method resolution


1171     ResourceMark rm(THREAD);
1172     char buf[200];
1173     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
1174                  Method::name_and_sig_as_C_string(resolved_klass(),
1175                                                   resolved_method->name(),
1176                                                   resolved_method->signature()),
1177                    (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
1178     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1179   }
1180 
1181   // check if not static
1182   if (resolved_method->is_static()) {
1183     ResourceMark rm(THREAD);
1184     char buf[200];
1185     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1186                                                                                                              resolved_method->name(),
1187                                                                                                              resolved_method->signature()));
1188     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1189   }
1190 
1191   if (develop_log_is_enabled(Trace, vtables)) {
1192     trace_method_resolution("invokevirtual resolved method: caller-class:",
1193                             current_klass, resolved_klass, resolved_method, false);

1194   }
1195 
1196   return resolved_method;
1197 }
1198 
1199 // throws runtime exceptions
1200 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
1201                                                   const methodHandle& resolved_method,
1202                                                   KlassHandle resolved_klass,
1203                                                   Handle recv,
1204                                                   KlassHandle recv_klass,
1205                                                   bool check_null_and_abstract,
1206                                                   TRAPS) {
1207 
1208   // setup default return values
1209   int vtable_index = Method::invalid_vtable_index;
1210   methodHandle selected_method;
1211 
1212   assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
1213 


1251   }
1252 
1253   // check if method exists
1254   if (selected_method.is_null()) {
1255     ResourceMark rm(THREAD);
1256     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1257               Method::name_and_sig_as_C_string(resolved_klass(),
1258                                                       resolved_method->name(),
1259                                                       resolved_method->signature()));
1260   }
1261 
1262   // check if abstract
1263   if (check_null_and_abstract && selected_method->is_abstract()) {
1264     ResourceMark rm(THREAD);
1265     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1266               Method::name_and_sig_as_C_string(resolved_klass(),
1267                                                       selected_method->name(),
1268                                                       selected_method->signature()));
1269   }
1270 
1271   if (develop_log_is_enabled(Trace, vtables)) {
1272     trace_method_resolution("invokevirtual selected method: receiver-class:",
1273                             recv_klass, resolved_klass, selected_method,
1274                             false, vtable_index);
1275   }
1276   // setup result
1277   result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1278 }
1279 
1280 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
1281                                           const LinkInfo& link_info,
1282                                           bool check_null_and_abstract, TRAPS) {
1283   // throws linktime exceptions
1284   methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1285   runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1286                                    recv, recv_klass, check_null_and_abstract, CHECK);
1287 }
1288 
1289 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
1290                                                              TRAPS) {
1291   // normal interface method resolution
1292   methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL);
1293   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
1294   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");


1350                                                     resolved_method->signature()));
1351   }
1352   // check access
1353   // Throw Illegal Access Error if sel_method is not public.
1354   if (!sel_method->is_public()) {
1355     ResourceMark rm(THREAD);
1356     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1357               Method::name_and_sig_as_C_string(recv_klass(),
1358                                                sel_method->name(),
1359                                                sel_method->signature()));
1360   }
1361   // check if abstract
1362   if (check_null_and_abstract && sel_method->is_abstract()) {
1363     ResourceMark rm(THREAD);
1364     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1365               Method::name_and_sig_as_C_string(recv_klass(),
1366                                                       sel_method->name(),
1367                                                       sel_method->signature()));
1368   }
1369 
1370   if (develop_log_is_enabled(Trace, itables)) {
1371     trace_method_resolution("invokeinterface selected method: receiver-class",
1372                             recv_klass, resolved_klass, sel_method, true);

1373   }
1374   // setup result
1375   if (!resolved_method->has_itable_index()) {
1376     int vtable_index = resolved_method->vtable_index();
1377     assert(vtable_index == sel_method->vtable_index(), "sanity check");
1378     result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1379   } else {
1380     int itable_index = resolved_method()->itable_index();
1381     result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
1382   }
1383 }
1384 
1385 
1386 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
1387                                                  const LinkInfo& link_info) {
1388   EXCEPTION_MARK;
1389   methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD);
1390   if (HAS_PENDING_EXCEPTION) {
1391     CLEAR_PENDING_EXCEPTION;
1392     return methodHandle();


1599 void LinkResolver::resolve_dynamic_call(CallInfo& result,
1600                                         Handle bootstrap_specifier,
1601                                         Symbol* method_name, Symbol* method_signature,
1602                                         KlassHandle current_klass,
1603                                         TRAPS) {
1604   // JSR 292:  this must resolve to an implicitly generated method MH.linkToCallSite(*...)
1605   // The appendix argument is likely to be a freshly-created CallSite.
1606   Handle       resolved_appendix;
1607   Handle       resolved_method_type;
1608   methodHandle resolved_method =
1609     SystemDictionary::find_dynamic_call_site_invoker(current_klass,
1610                                                      bootstrap_specifier,
1611                                                      method_name, method_signature,
1612                                                      &resolved_appendix,
1613                                                      &resolved_method_type,
1614                                                      THREAD);
1615   wrap_invokedynamic_exception(CHECK);
1616   result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
1617   wrap_invokedynamic_exception(CHECK);
1618 }

























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