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

src/share/vm/interpreter/linkResolver.cpp

Print this page




 595     Symbol* method_name = vmSymbols::invoke_name();
 596     Symbol* method_signature = pool->signature_ref_at(index);
 597     KlassHandle  current_klass(THREAD, pool->pool_holder());
 598     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
 599     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 600   }
 601 
 602   LinkInfo link_info(pool, index, CHECK_NULL);
 603   resolved_klass = link_info.resolved_klass();
 604 
 605   if (pool->has_preresolution()
 606       || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
 607           MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
 608     Method* result = ConstantPool::method_at_if_loaded(pool, index);
 609     if (result != NULL) {
 610       return methodHandle(THREAD, result);
 611     }
 612   }
 613 
 614   if (code == Bytecodes::_invokeinterface) {
 615     return resolve_interface_method(link_info, true, THREAD);
 616   } else if (code == Bytecodes::_invokevirtual) {
 617     return resolve_method(link_info, /*require_methodref*/true, THREAD);
 618   } else if (!resolved_klass->is_interface()) {
 619     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 620   } else {
 621     bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
 622     return resolve_interface_method(link_info, nostatics, THREAD);
 623   }
 624 }
 625 
 626 // Check and print a loader constraint violation message for method or interface method
 627 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
 628                                                    const methodHandle& resolved_method,
 629                                                    const char* method_type, TRAPS) {
 630   Handle current_loader(THREAD, link_info.current_klass()->class_loader());
 631   Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
 632 
 633   ResourceMark rm(THREAD);
 634   Symbol* failed_type_symbol =
 635     SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
 636                                               resolved_loader, true, CHECK);
 637   if (failed_type_symbol != NULL) {
 638     const char* msg = "loader constraint violation: when resolving %s"
 639       " \"%s\" the class loader (instance of %s) of the current class, %s,"
 640       " and the class loader (instance of %s) for the method's defining class, %s, have"
 641       " different Class objects for the type %s used in the signature";
 642     char* sig = link_info.method_string();


 760     st = LogHandle(itables)::trace_stream();
 761   } else {
 762     st = LogHandle(vtables)::trace_stream();
 763   }
 764   st->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
 765             prefix,
 766             (klass.is_null() ? "<NULL>" : klass->internal_name()),
 767             (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
 768             Method::name_and_sig_as_C_string(resolved_klass(),
 769                                              method->name(),
 770                                              method->signature()),
 771             method->method_holder()->internal_name());
 772   method->print_linkage_flags(st);
 773   if (index != -1) {
 774     st->print("vtable_index:%d", index);
 775   }
 776   st->cr();
 777 #endif // PRODUCT
 778 }
 779 
 780 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
 781                                                     bool nostatics, TRAPS) {
 782 
 783   KlassHandle resolved_klass = link_info.resolved_klass();
 784 
 785   // check if klass is interface
 786   if (!resolved_klass->is_interface()) {
 787     ResourceMark rm(THREAD);
 788     char buf[200];
 789     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 790     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 791   }
 792 
 793   // lookup method in this interface or its super, java.lang.Object
 794   // JDK8: also look for static methods
 795   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 796 
 797   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 798     // lookup method in all the super-interfaces
 799     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 800   }
 801 


 807                                                     link_info.name(),
 808                                                     link_info.signature()));
 809   }
 810 
 811   if (link_info.check_access()) {
 812     // JDK8 adds non-public interface methods, and accessability check requirement
 813     KlassHandle current_klass = link_info.current_klass();
 814 
 815     assert(current_klass.not_null() , "current_klass should not be null");
 816 
 817     // check if method can be accessed by the referring class
 818     check_method_accessability(current_klass,
 819                                resolved_klass,
 820                                KlassHandle(THREAD, resolved_method->method_holder()),
 821                                resolved_method,
 822                                CHECK_NULL);
 823 
 824     check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
 825   }
 826 
 827   if (nostatics && resolved_method->is_static()) {
 828     ResourceMark rm(THREAD);
 829     char buf[200];
 830     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
 831                  Method::name_and_sig_as_C_string(resolved_klass(),
 832                  resolved_method->name(), resolved_method->signature()));
 833     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 834   }
 835 













 836   if (log_develop_is_enabled(Trace, itables)) {
 837     trace_method_resolution("invokeinterface resolved method: caller-class",
 838                             link_info.current_klass(), resolved_klass,
 839                             resolved_method, true);
 840   }
 841 
 842   return resolved_method;
 843 }
 844 
 845 //------------------------------------------------------------------------------------------------------------------------
 846 // Field resolution
 847 
 848 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
 849                                              KlassHandle resolved_klass,
 850                                              KlassHandle sel_klass,
 851                                              const fieldDescriptor& fd,
 852                                              TRAPS) {
 853   if (!Reflection::verify_field_access(ref_klass(),
 854                                        resolved_klass(),
 855                                        sel_klass(),


 967     resolved_klass->initialize(CHECK);
 968     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
 969     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
 970                       link_info.current_klass(), link_info.check_access());
 971     resolved_method = linktime_resolve_static_method(new_info, CHECK);
 972   }
 973 
 974   assert(save_resolved_method == resolved_method(), "does this change?");
 975   // setup result
 976   result.set_static(resolved_klass, resolved_method, CHECK);
 977 }
 978 
 979 // throws linktime exceptions
 980 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
 981 
 982   KlassHandle resolved_klass = link_info.resolved_klass();
 983   methodHandle resolved_method;
 984   if (!resolved_klass->is_interface()) {
 985     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
 986   } else {
 987     resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
 988   }
 989   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
 990 
 991   // check if static
 992   if (!resolved_method->is_static()) {
 993     ResourceMark rm(THREAD);
 994     char buf[200];
 995     jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
 996                                                       resolved_method->name(),
 997                                                       resolved_method->signature()));
 998     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 999   }
1000   return resolved_method;
1001 }
1002 
1003 
1004 void LinkResolver::resolve_special_call(CallInfo& result,
1005                                         const LinkInfo& link_info,
1006                                         TRAPS) {
1007   methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK);


1010                                  link_info.current_klass(),
1011                                  link_info.check_access(), CHECK);
1012 }
1013 
1014 // throws linktime exceptions
1015 methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info,
1016                                                            TRAPS) {
1017 
1018   // Invokespecial is called for multiple special reasons:
1019   // <init>
1020   // local private method invocation, for classes and interfaces
1021   // superclass.method, which can also resolve to a default method
1022   // and the selected method is recalculated relative to the direct superclass
1023   // superinterface.method, which explicitly does not check shadowing
1024   KlassHandle resolved_klass = link_info.resolved_klass();
1025   methodHandle resolved_method;
1026 
1027   if (!resolved_klass->is_interface()) {
1028     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
1029   } else {
1030     resolved_method = resolve_interface_method(link_info, /*nostatics*/true, CHECK_NULL);
1031   }
1032 
1033   // check if method name is <init>, that it is found in same klass as static type
1034   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1035       resolved_method->method_holder() != resolved_klass()) {
1036     ResourceMark rm(THREAD);
1037     Exceptions::fthrow(
1038       THREAD_AND_LOCATION,
1039       vmSymbols::java_lang_NoSuchMethodError(),
1040       "%s: method %s%s not found",
1041       resolved_klass->external_name(),
1042       resolved_method->name()->as_C_string(),
1043       resolved_method->signature()->as_C_string()
1044     );
1045     return NULL;
1046   }
1047 
1048   // check if invokespecial's interface method reference is in an indirect superinterface
1049   KlassHandle current_klass = link_info.current_klass();
1050   if (!current_klass.is_null() && resolved_klass->is_interface()) {


1285     trace_method_resolution("invokevirtual selected method: receiver-class:",
1286                             recv_klass, resolved_klass, selected_method,
1287                             false, vtable_index);
1288   }
1289   // setup result
1290   result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1291 }
1292 
1293 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
1294                                           const LinkInfo& link_info,
1295                                           bool check_null_and_abstract, TRAPS) {
1296   // throws linktime exceptions
1297   methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1298   runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1299                                    recv, recv_klass, check_null_and_abstract, CHECK);
1300 }
1301 
1302 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
1303                                                              TRAPS) {
1304   // normal interface method resolution
1305   methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL);
1306   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
1307   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
1308 
1309   return resolved_method;
1310 }
1311 
1312 // throws runtime exceptions
1313 void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
1314                                                     const methodHandle& resolved_method,
1315                                                     KlassHandle resolved_klass,
1316                                                     Handle recv,
1317                                                     KlassHandle recv_klass,
1318                                                     bool check_null_and_abstract, TRAPS) {
1319   // check if receiver exists
1320   if (check_null_and_abstract && recv.is_null()) {
1321     THROW(vmSymbols::java_lang_NullPointerException());
1322   }
1323 
1324   // check if private interface method
1325   if (resolved_klass->is_interface() && resolved_method->is_private()) {
1326     ResourceMark rm(THREAD);
1327     char buf[200];
1328     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
1329                  Method::name_and_sig_as_C_string(resolved_klass(),
1330                                                   resolved_method->name(),
1331                                                   resolved_method->signature()));
1332     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1333   }
1334 
1335   // check if receiver klass implements the resolved interface
1336   if (!recv_klass->is_subtype_of(resolved_klass())) {
1337     ResourceMark rm(THREAD);
1338     char buf[200];
1339     jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
1340                  recv_klass()->external_name(),
1341                  resolved_klass()->external_name());
1342     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1343   }
1344 
1345   // do lookup based on receiver klass
1346   // This search must match the linktime preparation search for itable initialization
1347   // to correctly enforce loader constraints for interface method inheritance
1348   methodHandle sel_method = lookup_instance_method_in_klasses(recv_klass,
1349                                                   resolved_method->name(),
1350                                                   resolved_method->signature(), CHECK);
1351   if (sel_method.is_null() && !check_null_and_abstract) {
1352     // In theory this is a harmless placeholder value, but
1353     // in practice leaving in null affects the nsk default method tests.
1354     // This needs further study.




 595     Symbol* method_name = vmSymbols::invoke_name();
 596     Symbol* method_signature = pool->signature_ref_at(index);
 597     KlassHandle  current_klass(THREAD, pool->pool_holder());
 598     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
 599     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 600   }
 601 
 602   LinkInfo link_info(pool, index, CHECK_NULL);
 603   resolved_klass = link_info.resolved_klass();
 604 
 605   if (pool->has_preresolution()
 606       || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
 607           MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
 608     Method* result = ConstantPool::method_at_if_loaded(pool, index);
 609     if (result != NULL) {
 610       return methodHandle(THREAD, result);
 611     }
 612   }
 613 
 614   if (code == Bytecodes::_invokeinterface) {
 615     return resolve_interface_method(link_info, code, THREAD);
 616   } else if (code == Bytecodes::_invokevirtual) {
 617     return resolve_method(link_info, /*require_methodref*/true, THREAD);
 618   } else if (!resolved_klass->is_interface()) {
 619     return resolve_method(link_info, /*require_methodref*/false, THREAD);
 620   } else {
 621     return resolve_interface_method(link_info, code, THREAD);

 622   }
 623 }
 624 
 625 // Check and print a loader constraint violation message for method or interface method
 626 void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
 627                                                    const methodHandle& resolved_method,
 628                                                    const char* method_type, TRAPS) {
 629   Handle current_loader(THREAD, link_info.current_klass()->class_loader());
 630   Handle resolved_loader(THREAD, resolved_method->method_holder()->class_loader());
 631 
 632   ResourceMark rm(THREAD);
 633   Symbol* failed_type_symbol =
 634     SystemDictionary::check_signature_loaders(link_info.signature(), current_loader,
 635                                               resolved_loader, true, CHECK);
 636   if (failed_type_symbol != NULL) {
 637     const char* msg = "loader constraint violation: when resolving %s"
 638       " \"%s\" the class loader (instance of %s) of the current class, %s,"
 639       " and the class loader (instance of %s) for the method's defining class, %s, have"
 640       " different Class objects for the type %s used in the signature";
 641     char* sig = link_info.method_string();


 759     st = LogHandle(itables)::trace_stream();
 760   } else {
 761     st = LogHandle(vtables)::trace_stream();
 762   }
 763   st->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
 764             prefix,
 765             (klass.is_null() ? "<NULL>" : klass->internal_name()),
 766             (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
 767             Method::name_and_sig_as_C_string(resolved_klass(),
 768                                              method->name(),
 769                                              method->signature()),
 770             method->method_holder()->internal_name());
 771   method->print_linkage_flags(st);
 772   if (index != -1) {
 773     st->print("vtable_index:%d", index);
 774   }
 775   st->cr();
 776 #endif // PRODUCT
 777 }
 778 
 779 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS) {

 780 
 781   KlassHandle resolved_klass = link_info.resolved_klass();
 782 
 783   // check if klass is interface
 784   if (!resolved_klass->is_interface()) {
 785     ResourceMark rm(THREAD);
 786     char buf[200];
 787     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 788     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 789   }
 790 
 791   // lookup method in this interface or its super, java.lang.Object
 792   // JDK8: also look for static methods
 793   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 794 
 795   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 796     // lookup method in all the super-interfaces
 797     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 798   }
 799 


 805                                                     link_info.name(),
 806                                                     link_info.signature()));
 807   }
 808 
 809   if (link_info.check_access()) {
 810     // JDK8 adds non-public interface methods, and accessability check requirement
 811     KlassHandle current_klass = link_info.current_klass();
 812 
 813     assert(current_klass.not_null() , "current_klass should not be null");
 814 
 815     // check if method can be accessed by the referring class
 816     check_method_accessability(current_klass,
 817                                resolved_klass,
 818                                KlassHandle(THREAD, resolved_method->method_holder()),
 819                                resolved_method,
 820                                CHECK_NULL);
 821 
 822     check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL);
 823   }
 824 
 825   if (code != Bytecodes::_invokestatic && resolved_method->is_static()) {
 826     ResourceMark rm(THREAD);
 827     char buf[200];
 828     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
 829                  Method::name_and_sig_as_C_string(resolved_klass(),
 830                  resolved_method->name(), resolved_method->signature()));
 831     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 832   }
 833 
 834   if (code == Bytecodes::_invokeinterface && resolved_method->is_private()) {
 835     ResourceMark rm(THREAD);
 836     char buf[200];
 837 
 838     KlassHandle current_klass = link_info.current_klass();
 839     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s, caller-class:%s",
 840                  Method::name_and_sig_as_C_string(resolved_klass(),
 841                                                   resolved_method->name(),
 842                                                   resolved_method->signature()),
 843                                                   (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
 844      THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 845   }
 846 
 847   if (log_develop_is_enabled(Trace, itables)) {
 848     trace_method_resolution("invokeinterface resolved method: caller-class",
 849                             link_info.current_klass(), resolved_klass,
 850                             resolved_method, true);
 851   }
 852 
 853   return resolved_method;
 854 }
 855 
 856 //------------------------------------------------------------------------------------------------------------------------
 857 // Field resolution
 858 
 859 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
 860                                              KlassHandle resolved_klass,
 861                                              KlassHandle sel_klass,
 862                                              const fieldDescriptor& fd,
 863                                              TRAPS) {
 864   if (!Reflection::verify_field_access(ref_klass(),
 865                                        resolved_klass(),
 866                                        sel_klass(),


 978     resolved_klass->initialize(CHECK);
 979     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
 980     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
 981                       link_info.current_klass(), link_info.check_access());
 982     resolved_method = linktime_resolve_static_method(new_info, CHECK);
 983   }
 984 
 985   assert(save_resolved_method == resolved_method(), "does this change?");
 986   // setup result
 987   result.set_static(resolved_klass, resolved_method, CHECK);
 988 }
 989 
 990 // throws linktime exceptions
 991 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
 992 
 993   KlassHandle resolved_klass = link_info.resolved_klass();
 994   methodHandle resolved_method;
 995   if (!resolved_klass->is_interface()) {
 996     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
 997   } else {
 998     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
 999   }
1000   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
1001 
1002   // check if static
1003   if (!resolved_method->is_static()) {
1004     ResourceMark rm(THREAD);
1005     char buf[200];
1006     jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
1007                                                       resolved_method->name(),
1008                                                       resolved_method->signature()));
1009     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1010   }
1011   return resolved_method;
1012 }
1013 
1014 
1015 void LinkResolver::resolve_special_call(CallInfo& result,
1016                                         const LinkInfo& link_info,
1017                                         TRAPS) {
1018   methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK);


1021                                  link_info.current_klass(),
1022                                  link_info.check_access(), CHECK);
1023 }
1024 
1025 // throws linktime exceptions
1026 methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info,
1027                                                            TRAPS) {
1028 
1029   // Invokespecial is called for multiple special reasons:
1030   // <init>
1031   // local private method invocation, for classes and interfaces
1032   // superclass.method, which can also resolve to a default method
1033   // and the selected method is recalculated relative to the direct superclass
1034   // superinterface.method, which explicitly does not check shadowing
1035   KlassHandle resolved_klass = link_info.resolved_klass();
1036   methodHandle resolved_method;
1037 
1038   if (!resolved_klass->is_interface()) {
1039     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
1040   } else {
1041     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
1042   }
1043 
1044   // check if method name is <init>, that it is found in same klass as static type
1045   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
1046       resolved_method->method_holder() != resolved_klass()) {
1047     ResourceMark rm(THREAD);
1048     Exceptions::fthrow(
1049       THREAD_AND_LOCATION,
1050       vmSymbols::java_lang_NoSuchMethodError(),
1051       "%s: method %s%s not found",
1052       resolved_klass->external_name(),
1053       resolved_method->name()->as_C_string(),
1054       resolved_method->signature()->as_C_string()
1055     );
1056     return NULL;
1057   }
1058 
1059   // check if invokespecial's interface method reference is in an indirect superinterface
1060   KlassHandle current_klass = link_info.current_klass();
1061   if (!current_klass.is_null() && resolved_klass->is_interface()) {


1296     trace_method_resolution("invokevirtual selected method: receiver-class:",
1297                             recv_klass, resolved_klass, selected_method,
1298                             false, vtable_index);
1299   }
1300   // setup result
1301   result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1302 }
1303 
1304 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass,
1305                                           const LinkInfo& link_info,
1306                                           bool check_null_and_abstract, TRAPS) {
1307   // throws linktime exceptions
1308   methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1309   runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1310                                    recv, recv_klass, check_null_and_abstract, CHECK);
1311 }
1312 
1313 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info,
1314                                                              TRAPS) {
1315   // normal interface method resolution
1316   methodHandle resolved_method = resolve_interface_method(link_info, Bytecodes::_invokeinterface, CHECK_NULL);
1317   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
1318   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
1319 
1320   return resolved_method;
1321 }
1322 
1323 // throws runtime exceptions
1324 void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
1325                                                     const methodHandle& resolved_method,
1326                                                     KlassHandle resolved_klass,
1327                                                     Handle recv,
1328                                                     KlassHandle recv_klass,
1329                                                     bool check_null_and_abstract, TRAPS) {
1330   // check if receiver exists
1331   if (check_null_and_abstract && recv.is_null()) {
1332     THROW(vmSymbols::java_lang_NullPointerException());
1333   }
1334 











1335   // check if receiver klass implements the resolved interface
1336   if (!recv_klass->is_subtype_of(resolved_klass())) {
1337     ResourceMark rm(THREAD);
1338     char buf[200];
1339     jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
1340                  recv_klass()->external_name(),
1341                  resolved_klass()->external_name());
1342     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1343   }
1344 
1345   // do lookup based on receiver klass
1346   // This search must match the linktime preparation search for itable initialization
1347   // to correctly enforce loader constraints for interface method inheritance
1348   methodHandle sel_method = lookup_instance_method_in_klasses(recv_klass,
1349                                                   resolved_method->name(),
1350                                                   resolved_method->signature(), CHECK);
1351   if (sel_method.is_null() && !check_null_and_abstract) {
1352     // In theory this is a harmless placeholder value, but
1353     // in practice leaving in null affects the nsk default method tests.
1354     // This needs further study.


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