hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 38719 133bf85c3f36
parent 38139 cf6f5c1b7205
child 38939 c1b1d1d0e89b
equal deleted inserted replaced
38708:8c27a4f8b242 38719:133bf85c3f36
   229   _resolved_klass = KlassHandle(THREAD, result);
   229   _resolved_klass = KlassHandle(THREAD, result);
   230 
   230 
   231   // Get name, signature, and static klass
   231   // Get name, signature, and static klass
   232   _name          = pool->name_ref_at(index);
   232   _name          = pool->name_ref_at(index);
   233   _signature     = pool->signature_ref_at(index);
   233   _signature     = pool->signature_ref_at(index);
       
   234   _tag           = pool->tag_ref_at(index);
   234   _current_klass = KlassHandle(THREAD, pool->pool_holder());
   235   _current_klass = KlassHandle(THREAD, pool->pool_holder());
   235 
   236 
   236   // Coming from the constant pool always checks access
   237   // Coming from the constant pool always checks access
   237   _check_access  = true;
   238   _check_access  = true;
   238 }
   239 }
   571     resolved_klass = SystemDictionary::MethodHandle_klass();
   572     resolved_klass = SystemDictionary::MethodHandle_klass();
   572     Symbol* method_name = vmSymbols::invoke_name();
   573     Symbol* method_name = vmSymbols::invoke_name();
   573     Symbol* method_signature = pool->signature_ref_at(index);
   574     Symbol* method_signature = pool->signature_ref_at(index);
   574     KlassHandle  current_klass(THREAD, pool->pool_holder());
   575     KlassHandle  current_klass(THREAD, pool->pool_holder());
   575     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
   576     LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass);
   576     return resolve_method(link_info, /*require_methodref*/false, THREAD);
   577     return resolve_method(link_info, code, THREAD);
   577   }
   578   }
   578 
   579 
   579   LinkInfo link_info(pool, index, CHECK_NULL);
   580   LinkInfo link_info(pool, index, CHECK_NULL);
   580   resolved_klass = link_info.resolved_klass();
   581   resolved_klass = link_info.resolved_klass();
   581 
   582 
   589   }
   590   }
   590 
   591 
   591   if (code == Bytecodes::_invokeinterface) {
   592   if (code == Bytecodes::_invokeinterface) {
   592     return resolve_interface_method(link_info, code, THREAD);
   593     return resolve_interface_method(link_info, code, THREAD);
   593   } else if (code == Bytecodes::_invokevirtual) {
   594   } else if (code == Bytecodes::_invokevirtual) {
   594     return resolve_method(link_info, /*require_methodref*/true, THREAD);
   595     return resolve_method(link_info, code, THREAD);
   595   } else if (!resolved_klass->is_interface()) {
   596   } else if (!resolved_klass->is_interface()) {
   596     return resolve_method(link_info, /*require_methodref*/false, THREAD);
   597     return resolve_method(link_info, code, THREAD);
   597   } else {
   598   } else {
   598     return resolve_interface_method(link_info, code, THREAD);
   599     return resolve_interface_method(link_info, code, THREAD);
   599   }
   600   }
   600 }
   601 }
   601 
   602 
   661     THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   662     THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   662   }
   663   }
   663 }
   664 }
   664 
   665 
   665 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
   666 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
   666                                           bool require_methodref, TRAPS) {
   667                                           Bytecodes::Code code, TRAPS) {
   667 
   668 
   668   Handle nested_exception;
   669   Handle nested_exception;
   669   KlassHandle resolved_klass = link_info.resolved_klass();
   670   KlassHandle resolved_klass = link_info.resolved_klass();
   670 
   671 
   671   // 1. check if methodref required, that resolved_klass is not interfacemethodref
   672   // 1. For invokevirtual, cannot call an interface method
   672   if (require_methodref && resolved_klass->is_interface()) {
   673   if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) {
   673     ResourceMark rm(THREAD);
   674     ResourceMark rm(THREAD);
   674     char buf[200];
   675     char buf[200];
   675     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
   676     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
   676         resolved_klass()->external_name());
   677         resolved_klass()->external_name());
   677     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   678     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   678   }
   679   }
   679 
   680 
   680   // 2. lookup method in resolved klass and its super klasses
   681   // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref
       
   682   if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) {
       
   683     ResourceMark rm(THREAD);
       
   684     char buf[200];
       
   685     jio_snprintf(buf, sizeof(buf), "Method %s must be Methodref constant", link_info.method_string());
       
   686     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
       
   687   }
       
   688 
       
   689 
       
   690   // 3. lookup method in resolved klass and its super klasses
   681   methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
   691   methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
   682 
   692 
       
   693   // 4. lookup method in all the interfaces implemented by the resolved klass
   683   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
   694   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
   684     // 3. lookup method in all the interfaces implemented by the resolved klass
       
   685     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
   695     resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
   686 
   696 
   687     if (resolved_method.is_null()) {
   697     if (resolved_method.is_null()) {
   688       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
   698       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
   689       resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
   699       resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
   692         CLEAR_PENDING_EXCEPTION;
   702         CLEAR_PENDING_EXCEPTION;
   693       }
   703       }
   694     }
   704     }
   695   }
   705   }
   696 
   706 
       
   707   // 5. method lookup failed
   697   if (resolved_method.is_null()) {
   708   if (resolved_method.is_null()) {
   698     // 4. method lookup failed
       
   699     ResourceMark rm(THREAD);
   709     ResourceMark rm(THREAD);
   700     THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(),
   710     THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(),
   701                     Method::name_and_sig_as_C_string(resolved_klass(),
   711                     Method::name_and_sig_as_C_string(resolved_klass(),
   702                                                      link_info.name(),
   712                                                      link_info.name(),
   703                                                      link_info.signature()),
   713                                                      link_info.signature()),
   704                     nested_exception, NULL);
   714                     nested_exception, NULL);
   705   }
   715   }
   706 
   716 
   707   // 5. access checks, access checking may be turned off when calling from within the VM.
   717   // 6. access checks, access checking may be turned off when calling from within the VM.
   708   KlassHandle current_klass = link_info.current_klass();
   718   KlassHandle current_klass = link_info.current_klass();
   709   if (link_info.check_access()) {
   719   if (link_info.check_access()) {
   710     assert(current_klass.not_null() , "current_klass should not be null");
   720     assert(current_klass.not_null() , "current_klass should not be null");
   711 
   721 
   712     // check if method can be accessed by the referring class
   722     // check if method can be accessed by the referring class
   764     char buf[200];
   774     char buf[200];
   765     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
   775     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
   766     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   776     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   767   }
   777   }
   768 
   778 
       
   779   // check constant pool tag for called method - must be JVM_CONSTANT_InterfaceMethodref
       
   780   if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) {
       
   781     ResourceMark rm(THREAD);
       
   782     char buf[200];
       
   783     jio_snprintf(buf, sizeof(buf), "Method %s must be InterfaceMethodref constant", link_info.method_string());
       
   784     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
       
   785   }
       
   786 
   769   // lookup method in this interface or its super, java.lang.Object
   787   // lookup method in this interface or its super, java.lang.Object
   770   // JDK8: also look for static methods
   788   // JDK8: also look for static methods
   771   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
   789   methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
   772 
   790 
   773   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
   791   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
   954   // Initialize klass (this should only happen if everything is ok)
   972   // Initialize klass (this should only happen if everything is ok)
   955   if (initialize_class && resolved_klass->should_be_initialized()) {
   973   if (initialize_class && resolved_klass->should_be_initialized()) {
   956     resolved_klass->initialize(CHECK);
   974     resolved_klass->initialize(CHECK);
   957     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
   975     // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?)
   958     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
   976     LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
   959                       link_info.current_klass(), link_info.check_access());
   977                       link_info.current_klass(),
       
   978                       link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
   960     resolved_method = linktime_resolve_static_method(new_info, CHECK);
   979     resolved_method = linktime_resolve_static_method(new_info, CHECK);
   961   }
   980   }
   962 
   981 
   963   assert(save_resolved_method == resolved_method(), "does this change?");
   982   assert(save_resolved_method == resolved_method(), "does this change?");
   964   // setup result
   983   // setup result
   969 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
   988 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) {
   970 
   989 
   971   KlassHandle resolved_klass = link_info.resolved_klass();
   990   KlassHandle resolved_klass = link_info.resolved_klass();
   972   methodHandle resolved_method;
   991   methodHandle resolved_method;
   973   if (!resolved_klass->is_interface()) {
   992   if (!resolved_klass->is_interface()) {
   974     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
   993     resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
   975   } else {
   994   } else {
   976     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
   995     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL);
   977   }
   996   }
   978   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   997   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   979 
   998 
  1012   // superinterface.method, which explicitly does not check shadowing
  1031   // superinterface.method, which explicitly does not check shadowing
  1013   KlassHandle resolved_klass = link_info.resolved_klass();
  1032   KlassHandle resolved_klass = link_info.resolved_klass();
  1014   methodHandle resolved_method;
  1033   methodHandle resolved_method;
  1015 
  1034 
  1016   if (!resolved_klass->is_interface()) {
  1035   if (!resolved_klass->is_interface()) {
  1017     resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL);
  1036     resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
  1018   } else {
  1037   } else {
  1019     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
  1038     resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL);
  1020   }
  1039   }
  1021 
  1040 
  1022   // check if method name is <init>, that it is found in same klass as static type
  1041   // check if method name is <init>, that it is found in same klass as static type
  1162 
  1181 
  1163 // throws linktime exceptions
  1182 // throws linktime exceptions
  1164 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
  1183 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info,
  1165                                                            TRAPS) {
  1184                                                            TRAPS) {
  1166   // normal method resolution
  1185   // normal method resolution
  1167   methodHandle resolved_method = resolve_method(link_info, /*require_methodref*/true, CHECK_NULL);
  1186   methodHandle resolved_method = resolve_method(link_info, Bytecodes::_invokevirtual, CHECK_NULL);
  1168 
  1187 
  1169   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
  1188   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
  1170   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
  1189   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
  1171 
  1190 
  1172   // check if private interface method
  1191   // check if private interface method
  1173   KlassHandle resolved_klass = link_info.resolved_klass();
  1192   KlassHandle resolved_klass = link_info.resolved_klass();
  1174   KlassHandle current_klass = link_info.current_klass();
  1193   KlassHandle current_klass = link_info.current_klass();
  1175 
  1194 
       
  1195   // This is impossible, if resolve_klass is an interface, we've thrown icce in resolve_method
  1176   if (resolved_klass->is_interface() && resolved_method->is_private()) {
  1196   if (resolved_klass->is_interface() && resolved_method->is_private()) {
  1177     ResourceMark rm(THREAD);
  1197     ResourceMark rm(THREAD);
  1178     char buf[200];
  1198     char buf[200];
  1179     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
  1199     jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
  1180                  Method::name_and_sig_as_C_string(resolved_klass(),
  1200                  Method::name_and_sig_as_C_string(resolved_klass(),
  1480                              const methodHandle& attached_method,
  1500                              const methodHandle& attached_method,
  1481                              Bytecodes::Code byte, TRAPS) {
  1501                              Bytecodes::Code byte, TRAPS) {
  1482   KlassHandle defc = attached_method->method_holder();
  1502   KlassHandle defc = attached_method->method_holder();
  1483   Symbol* name = attached_method->name();
  1503   Symbol* name = attached_method->name();
  1484   Symbol* type = attached_method->signature();
  1504   Symbol* type = attached_method->signature();
  1485   LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false);
  1505   LinkInfo link_info(defc, name, type);
  1486   switch(byte) {
  1506   switch(byte) {
  1487     case Bytecodes::_invokevirtual:
  1507     case Bytecodes::_invokevirtual:
  1488       resolve_virtual_call(result, recv, recv->klass(), link_info,
  1508       resolve_virtual_call(result, recv, recv->klass(), link_info,
  1489                            /*check_null_and_abstract=*/true, CHECK);
  1509                            /*check_null_and_abstract=*/true, CHECK);
  1490       break;
  1510       break;