src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8141564.01 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 
  54 
  55 void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) {
  56   int vtable_index = Method::nonvirtual_vtable_index;


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






























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


 766 
 767     // check if method can be accessed by the referring class
 768     check_method_accessability(current_klass,
 769                                resolved_klass,
 770                                KlassHandle(THREAD, resolved_method->method_holder()),
 771                                resolved_method,
 772                                CHECK_NULL);
 773 
 774     check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
 775   }
 776 
 777   if (nostatics && resolved_method->is_static()) {
 778     ResourceMark rm(THREAD);
 779     char buf[200];
 780     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
 781                  Method::name_and_sig_as_C_string(resolved_klass(),
 782                  resolved_method->name(), resolved_method->signature()));
 783     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 784   }
 785 
 786   if (TraceItables && Verbose) {
 787     trace_method_resolution("invokeinterface resolved method: caller-class",
 788                             link_info.current_klass(), resolved_klass, resolved_method);
 789     tty->cr();
 790   }
 791 
 792   return resolved_method;
 793 }
 794 
 795 //------------------------------------------------------------------------------------------------------------------------
 796 // Field resolution
 797 
 798 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
 799                                              KlassHandle resolved_klass,
 800                                              KlassHandle sel_klass,
 801                                              const fieldDescriptor& fd,
 802                                              TRAPS) {
 803   if (!Reflection::verify_field_access(ref_klass(),
 804                                        resolved_klass(),
 805                                        sel_klass(),
 806                                        fd.access_flags(),
 807                                        true)) {
 808     ResourceMark rm(THREAD);
 809     Exceptions::fthrow(


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


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


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


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


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


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


  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/defaultMethods.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "gc/shared/collectedHeap.inline.hpp"
  31 #include "interpreter/bytecode.hpp"
  32 #include "interpreter/interpreterRuntime.hpp"
  33 #include "interpreter/linkResolver.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "memory/universe.inline.hpp"
  37 #include "oops/instanceKlass.hpp"
  38 #include "oops/method.hpp"
  39 #include "oops/objArrayOop.hpp"
  40 #include "oops/oop.inline.hpp"
  41 #include "prims/methodHandles.hpp"
  42 #include "prims/nativeLookup.hpp"
  43 #include "runtime/compilationPolicy.hpp"
  44 #include "runtime/fieldDescriptor.hpp"
  45 #include "runtime/frame.inline.hpp"
  46 #include "runtime/handles.inline.hpp"
  47 #include "runtime/reflection.hpp"
  48 #include "runtime/signature.hpp"
  49 #include "runtime/thread.inline.hpp"
  50 #include "runtime/vmThread.hpp"
  51 
  52 
  53 //------------------------------------------------------------------------------------------------------------------------
  54 // Implementation of CallInfo
  55 
  56 
  57 void CallInfo::set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS) {
  58   int vtable_index = Method::nonvirtual_vtable_index;


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


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


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

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


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

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


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

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


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


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

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


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

























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