hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 21912 8d2924674592
parent 21768 b7dba4cde1c6
child 21913 0e2fd7282ac6
equal deleted inserted replaced
21911:f7a77bce0bcf 21912:8d2924674592
   240 //
   240 //
   241 // According to JVM spec. $5.4.3c & $5.4.3d
   241 // According to JVM spec. $5.4.3c & $5.4.3d
   242 
   242 
   243 // Look up method in klasses, including static methods
   243 // Look up method in klasses, including static methods
   244 // Then look up local default methods
   244 // Then look up local default methods
   245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
   245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) {
   246   Method* result_oop = klass->uncached_lookup_method(name, signature);
   246   Method* result_oop = klass->uncached_lookup_method(name, signature);
   247   if (result_oop == NULL) {
   247   if (result_oop == NULL) {
   248     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
   248     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
   249     if (default_methods != NULL) {
   249     if (default_methods != NULL) {
   250       result_oop = InstanceKlass::find_method(default_methods, name, signature);
   250       result_oop = InstanceKlass::find_method(default_methods, name, signature);
   251     }
   251     }
   252   }
   252   }
   253 
   253 
   254   if (EnableInvokeDynamic && result_oop != NULL) {
   254   if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
   255     vmIntrinsics::ID iid = result_oop->intrinsic_id();
   255     vmIntrinsics::ID iid = result_oop->intrinsic_id();
   256     if (MethodHandles::is_signature_polymorphic(iid)) {
   256     if (MethodHandles::is_signature_polymorphic(iid)) {
   257       // Do not link directly to these.  The VM must produce a synthetic one using lookup_polymorphic_method.
   257       // Do not link directly to these.  The VM must produce a synthetic one using lookup_polymorphic_method.
   258       return;
   258       return;
   259     }
   259     }
   501       return;
   501       return;
   502     }
   502     }
   503   }
   503   }
   504 
   504 
   505   if (code == Bytecodes::_invokeinterface) {
   505   if (code == Bytecodes::_invokeinterface) {
   506     resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   506     resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
   507   } else if (code == Bytecodes::_invokevirtual) {
   507   } else if (code == Bytecodes::_invokevirtual) {
   508     resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
   508     resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
       
   509   } else if (!resolved_klass->is_interface()) {
       
   510     resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
   509   } else {
   511   } else {
   510     resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
   512     bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
       
   513     resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK);
   511   }
   514   }
   512 }
   515 }
   513 
   516 
   514 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   517 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   515                                   Symbol* method_name, Symbol* method_signature,
   518                                   Symbol* method_name, Symbol* method_signature,
   526         resolved_klass()->external_name());
   529         resolved_klass()->external_name());
   527     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   530     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   528   }
   531   }
   529 
   532 
   530   // 2. lookup method in resolved klass and its super klasses
   533   // 2. lookup method in resolved klass and its super klasses
   531   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   534   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
   532 
   535 
   533   if (resolved_method.is_null()) { // not found in the class hierarchy
   536   if (resolved_method.is_null()) { // not found in the class hierarchy
   534     // 3. lookup method in all the interfaces implemented by the resolved klass
   537     // 3. lookup method in all the interfaces implemented by the resolved klass
   535     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   538     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   536 
   539 
   610 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
   613 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
   611                                             KlassHandle resolved_klass,
   614                                             KlassHandle resolved_klass,
   612                                             Symbol* method_name,
   615                                             Symbol* method_name,
   613                                             Symbol* method_signature,
   616                                             Symbol* method_signature,
   614                                             KlassHandle current_klass,
   617                                             KlassHandle current_klass,
   615                                             bool check_access, TRAPS) {
   618                                             bool check_access,
       
   619                                             bool nostatics, TRAPS) {
   616 
   620 
   617  // check if klass is interface
   621  // check if klass is interface
   618   if (!resolved_klass->is_interface()) {
   622   if (!resolved_klass->is_interface()) {
   619     ResourceMark rm(THREAD);
   623     ResourceMark rm(THREAD);
   620     char buf[200];
   624     char buf[200];
   621     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
   625     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
   622     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   626     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   623   }
   627   }
   624 
   628 
   625   // lookup method in this interface or its super, java.lang.Object
   629   // lookup method in this interface or its super, java.lang.Object
   626   lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   630   // JDK8: also look for static methods
       
   631   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
   627 
   632 
   628   if (resolved_method.is_null()) {
   633   if (resolved_method.is_null()) {
   629     // lookup method in all the super-interfaces
   634     // lookup method in all the super-interfaces
   630     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   635     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   631     if (resolved_method.is_null()) {
   636     if (resolved_method.is_null()) {
   635                 Method::name_and_sig_as_C_string(resolved_klass(),
   640                 Method::name_and_sig_as_C_string(resolved_klass(),
   636                                                         method_name,
   641                                                         method_name,
   637                                                         method_signature));
   642                                                         method_signature));
   638     }
   643     }
   639   }
   644   }
       
   645 
       
   646   if (nostatics && resolved_method->is_static()) {
       
   647     ResourceMark rm(THREAD);
       
   648     char buf[200];
       
   649     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
       
   650                                                       resolved_method->name(),
       
   651                                                       resolved_method->signature()));
       
   652     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
       
   653   }
       
   654 
   640 
   655 
   641   if (check_access) {
   656   if (check_access) {
   642     // JDK8 adds non-public interface methods, and accessability check requirement
   657     // JDK8 adds non-public interface methods, and accessability check requirement
   643     assert(current_klass.not_null() , "current_klass should not be null");
   658     assert(current_klass.not_null() , "current_klass should not be null");
   644 
   659 
   862 // throws linktime exceptions
   877 // throws linktime exceptions
   863 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   878 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   864                                                   Symbol* method_name, Symbol* method_signature,
   879                                                   Symbol* method_name, Symbol* method_signature,
   865                                                   KlassHandle current_klass, bool check_access, TRAPS) {
   880                                                   KlassHandle current_klass, bool check_access, TRAPS) {
   866 
   881 
   867   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
   882   if (!resolved_klass->is_interface()) {
       
   883     resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
       
   884   } else {
       
   885     resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
       
   886   }
   868   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   887   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   869 
   888 
   870   // check if static
   889   // check if static
   871   if (!resolved_method->is_static()) {
   890   if (!resolved_method->is_static()) {
   872     ResourceMark rm(THREAD);
   891     ResourceMark rm(THREAD);
   896   // local private method invocation, for classes and interfaces
   915   // local private method invocation, for classes and interfaces
   897   // superclass.method, which can also resolve to a default method
   916   // superclass.method, which can also resolve to a default method
   898   // and the selected method is recalculated relative to the direct superclass
   917   // and the selected method is recalculated relative to the direct superclass
   899   // superinterface.method, which explicitly does not check shadowing
   918   // superinterface.method, which explicitly does not check shadowing
   900 
   919 
   901   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
   920   if (!resolved_klass->is_interface()) {
       
   921     resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
       
   922   } else {
       
   923     resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
       
   924   }
   902 
   925 
   903   // check if method name is <init>, that it is found in same klass as static type
   926   // check if method name is <init>, that it is found in same klass as static type
   904   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   927   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   905       resolved_method->method_holder() != resolved_klass()) {
   928       resolved_method->method_holder() != resolved_klass()) {
   906     ResourceMark rm(THREAD);
   929     ResourceMark rm(THREAD);
  1217 
  1240 
  1218 // throws linktime exceptions
  1241 // throws linktime exceptions
  1219 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
  1242 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
  1220                                                      Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
  1243                                                      Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
  1221   // normal interface method resolution
  1244   // normal interface method resolution
  1222   resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
  1245   resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
  1223 
  1246 
  1224   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
  1247   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
  1225   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
  1248   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
  1226 }
  1249 }
  1227 
  1250