< prev index next >

src/share/vm/interpreter/linkResolver.cpp

Print this page




 229   case direct_call: kindstr = "direct"; break;
 230   case vtable_call: kindstr = "vtable"; break;
 231   case itable_call: kindstr = "itable"; break;
 232   }
 233   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 234                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 235 }
 236 #endif
 237 
 238 //------------------------------------------------------------------------------------------------------------------------
 239 // Implementation of LinkInfo
 240 
 241 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
 242    // resolve klass
 243   Klass* result = pool->klass_ref_at(index, CHECK);
 244   _resolved_klass = KlassHandle(THREAD, result);
 245 
 246   // Get name, signature, and static klass
 247   _name          = pool->name_ref_at(index);
 248   _signature     = pool->signature_ref_at(index);

 249   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 250 
 251   // Coming from the constant pool always checks access
 252   _check_access  = true;
 253 }
 254 
 255 char* LinkInfo::method_string() const {
 256   return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
 257 }
 258 
 259 #ifndef PRODUCT
 260 void LinkInfo::print() {
 261   ResourceMark rm;
 262   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 263                 _resolved_klass->name()->as_C_string(),
 264                 _name->as_C_string(),
 265                 _signature->as_C_string(),
 266                 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
 267                 _check_access ? "true" : "false");
 268 }


 665                      failed_type_name);
 666     THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
 667   }
 668 }
 669 
 670 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
 671                                           bool require_methodref, TRAPS) {
 672 
 673   Handle nested_exception;
 674   KlassHandle resolved_klass = link_info.resolved_klass();
 675 
 676   // 1. check if methodref required, that resolved_klass is not interfacemethodref
 677   if (require_methodref && resolved_klass->is_interface()) {
 678     ResourceMark rm(THREAD);
 679     char buf[200];
 680     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
 681         resolved_klass()->external_name());
 682     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 683   }
 684 









 685   // 2. lookup method in resolved klass and its super klasses
 686   methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
 687 
 688   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
 689     // 3. lookup method in all the interfaces implemented by the resolved klass
 690     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 691 
 692     if (resolved_method.is_null()) {
 693       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
 694       resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
 695       if (HAS_PENDING_EXCEPTION) {
 696         nested_exception = Handle(THREAD, PENDING_EXCEPTION);
 697         CLEAR_PENDING_EXCEPTION;
 698       }
 699     }
 700   }
 701 
 702   if (resolved_method.is_null()) {
 703     // 4. method lookup failed
 704     ResourceMark rm(THREAD);


 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);
 751   }
 752 
 753   if (resolved_method.is_null()) {
 754     // no method found
 755     ResourceMark rm(THREAD);
 756     THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
 757                    Method::name_and_sig_as_C_string(resolved_klass(),
 758                                                     link_info.name(),
 759                                                     link_info.signature()));
 760   }
 761 
 762   if (link_info.check_access()) {
 763     // JDK8 adds non-public interface methods, and accessability check requirement


 901 // resolved_method    the specified method (i.e., static receiver specified via constant pool index)
 902 // sel_method         the selected method  (selected via run-time lookup; e.g., based on dynamic receiver class)
 903 // resolved_klass     the specified klass  (i.e., specified via constant pool index)
 904 // recv_klass         the receiver klass
 905 
 906 
 907 void LinkResolver::resolve_static_call(CallInfo& result,
 908                                        const LinkInfo& link_info,
 909                                        bool initialize_class, TRAPS) {
 910   methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
 911 
 912   // The resolved class can change as a result of this resolution.
 913   KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
 914 
 915   Method* save_resolved_method = resolved_method();
 916   // Initialize klass (this should only happen if everything is ok)
 917   if (initialize_class && resolved_klass->should_be_initialized()) {
 918     resolved_klass->initialize(CHECK);
 919     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
 920     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
 921                       link_info.current_klass(), link_info.check_access());

 922     resolved_method = linktime_resolve_static_method(new_info, CHECK);
 923   }
 924 
 925   assert(save_resolved_method == resolved_method(), "does this change?");
 926   // setup result
 927   result.set_static(resolved_klass, resolved_method, CHECK);
 928 }
 929 
 930 // throws linktime exceptions
 931 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
 932 
 933   KlassHandle resolved_klass = link_info.resolved_klass();
 934   methodHandle resolved_method;
 935   if (!resolved_klass->is_interface()) {
 936     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
 937   } else {
 938     resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
 939   }
 940   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
 941 




 229   case direct_call: kindstr = "direct"; break;
 230   case vtable_call: kindstr = "vtable"; break;
 231   case itable_call: kindstr = "itable"; break;
 232   }
 233   tty->print_cr("Call %s@%d %s", kindstr, _call_index,
 234                 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
 235 }
 236 #endif
 237 
 238 //------------------------------------------------------------------------------------------------------------------------
 239 // Implementation of LinkInfo
 240 
 241 LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
 242    // resolve klass
 243   Klass* result = pool->klass_ref_at(index, CHECK);
 244   _resolved_klass = KlassHandle(THREAD, result);
 245 
 246   // Get name, signature, and static klass
 247   _name          = pool->name_ref_at(index);
 248   _signature     = pool->signature_ref_at(index);
 249   _tag           = pool->tag_ref_at(index);
 250   _current_klass = KlassHandle(THREAD, pool->pool_holder());
 251 
 252   // Coming from the constant pool always checks access
 253   _check_access  = true;
 254 }
 255 
 256 char* LinkInfo::method_string() const {
 257   return Method::name_and_sig_as_C_string(_resolved_klass(), _name, _signature);
 258 }
 259 
 260 #ifndef PRODUCT
 261 void LinkInfo::print() {
 262   ResourceMark rm;
 263   tty->print_cr("Link resolved_klass=%s name=%s signature=%s current_klass=%s check_access=%s",
 264                 _resolved_klass->name()->as_C_string(),
 265                 _name->as_C_string(),
 266                 _signature->as_C_string(),
 267                 _current_klass.is_null() ? "(none)" : _current_klass->name()->as_C_string(),
 268                 _check_access ? "true" : "false");
 269 }


 666                      failed_type_name);
 667     THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
 668   }
 669 }
 670 
 671 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
 672                                           bool require_methodref, TRAPS) {
 673 
 674   Handle nested_exception;
 675   KlassHandle resolved_klass = link_info.resolved_klass();
 676 
 677   // 1. check if methodref required, that resolved_klass is not interfacemethodref
 678   if (require_methodref && resolved_klass->is_interface()) {
 679     ResourceMark rm(THREAD);
 680     char buf[200];
 681     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
 682         resolved_klass()->external_name());
 683     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 684   }
 685 
 686   // check tag at call is method
 687   if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
 688     ResourceMark rm(THREAD);
 689     char buf[200];
 690     jio_snprintf(buf, sizeof(buf), "Resolving to non regular method %s", link_info.method_string());
 691     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 692   }
 693 
 694 
 695   // 2. lookup method in resolved klass and its super klasses
 696   methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
 697 
 698   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
 699     // 3. lookup method in all the interfaces implemented by the resolved klass
 700     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 701 
 702     if (resolved_method.is_null()) {
 703       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
 704       resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
 705       if (HAS_PENDING_EXCEPTION) {
 706         nested_exception = Handle(THREAD, PENDING_EXCEPTION);
 707         CLEAR_PENDING_EXCEPTION;
 708       }
 709     }
 710   }
 711 
 712   if (resolved_method.is_null()) {
 713     // 4. method lookup failed
 714     ResourceMark rm(THREAD);


 734     // check loader constraints
 735     check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL);
 736   }
 737 
 738   return resolved_method;
 739 }
 740 
 741 methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
 742                                                     bool nostatics, TRAPS) {
 743 
 744   KlassHandle resolved_klass = link_info.resolved_klass();
 745 
 746   // check if klass is interface
 747   if (!resolved_klass->is_interface()) {
 748     ResourceMark rm(THREAD);
 749     char buf[200];
 750     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 751     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 752   }
 753 
 754   // check tag at call is an interface method
 755   if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) {
 756     ResourceMark rm(THREAD);
 757     char buf[200];
 758     jio_snprintf(buf, sizeof(buf), "Resolving to non interface method %s", link_info.method_string());
 759     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 760   }
 761 
 762   // lookup method in this interface or its super, java.lang.Object
 763   // JDK8: also look for static methods
 764   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
 765 
 766   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
 767     // lookup method in all the super-interfaces
 768     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
 769   }
 770 
 771   if (resolved_method.is_null()) {
 772     // no method found
 773     ResourceMark rm(THREAD);
 774     THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(),
 775                    Method::name_and_sig_as_C_string(resolved_klass(),
 776                                                     link_info.name(),
 777                                                     link_info.signature()));
 778   }
 779 
 780   if (link_info.check_access()) {
 781     // JDK8 adds non-public interface methods, and accessability check requirement


 919 // resolved_method    the specified method (i.e., static receiver specified via constant pool index)
 920 // sel_method         the selected method  (selected via run-time lookup; e.g., based on dynamic receiver class)
 921 // resolved_klass     the specified klass  (i.e., specified via constant pool index)
 922 // recv_klass         the receiver klass
 923 
 924 
 925 void LinkResolver::resolve_static_call(CallInfo& result,
 926                                        const LinkInfo& link_info,
 927                                        bool initialize_class, TRAPS) {
 928   methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK);
 929 
 930   // The resolved class can change as a result of this resolution.
 931   KlassHandle resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
 932 
 933   Method* save_resolved_method = resolved_method();
 934   // Initialize klass (this should only happen if everything is ok)
 935   if (initialize_class && resolved_klass->should_be_initialized()) {
 936     resolved_klass->initialize(CHECK);
 937     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
 938     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
 939                       link_info.current_klass(),
 940                       link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
 941     resolved_method = linktime_resolve_static_method(new_info, CHECK);
 942   }
 943 
 944   assert(save_resolved_method == resolved_method(), "does this change?");
 945   // setup result
 946   result.set_static(resolved_klass, resolved_method, CHECK);
 947 }
 948 
 949 // throws linktime exceptions
 950 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
 951 
 952   KlassHandle resolved_klass = link_info.resolved_klass();
 953   methodHandle resolved_method;
 954   if (!resolved_klass->is_interface()) {
 955     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
 956   } else {
 957     resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL);
 958   }
 959   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
 960 


< prev index next >