hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 22219 4bfd5df70189
parent 22218 71cff6a30ec1
child 22232 26acfad336c0
equal deleted inserted replaced
22218:71cff6a30ec1 22219:4bfd5df70189
   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, bool checkpolymorphism, TRAPS) {
   245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
   246   Method* result_oop = klass->uncached_lookup_method(name, signature);
   246   Method* result_oop = klass->uncached_lookup_method(name, signature);
       
   247 
       
   248   // JDK 8, JVMS 5.4.3.4: Interface method resolution should
       
   249   // ignore static and non-public methods of java.lang.Object,
       
   250   // like clone, finalize, registerNatives.
       
   251   if (in_imethod_resolve &&
       
   252       result_oop != NULL &&
       
   253       klass->is_interface() &&
       
   254       (result_oop->is_static() || !result_oop->is_public()) &&
       
   255       result_oop->method_holder() == SystemDictionary::Object_klass()) {
       
   256     result_oop = NULL;
       
   257   }
       
   258 
   247   if (result_oop == NULL) {
   259   if (result_oop == NULL) {
   248     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
   260     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
   249     if (default_methods != NULL) {
   261     if (default_methods != NULL) {
   250       result_oop = InstanceKlass::find_method(default_methods, name, signature);
   262       result_oop = InstanceKlass::find_method(default_methods, name, signature);
   251     }
   263     }
   418                                               methodHandle sel_method,
   430                                               methodHandle sel_method,
   419                                               TRAPS) {
   431                                               TRAPS) {
   420 
   432 
   421   AccessFlags flags = sel_method->access_flags();
   433   AccessFlags flags = sel_method->access_flags();
   422 
   434 
   423   // Special case #1:  arrays always override "clone". JVMS 2.15.
   435   // Special case:  arrays always override "clone". JVMS 2.15.
   424   // If the resolved klass is an array class, and the declaring class
   436   // If the resolved klass is an array class, and the declaring class
   425   // is java.lang.Object and the method is "clone", set the flags
   437   // is java.lang.Object and the method is "clone", set the flags
   426   // to public.
   438   // to public.
   427   // Special case #2:  If the resolved klass is an interface, and
       
   428   // the declaring class is java.lang.Object, and the method is
       
   429   // "clone" or "finalize", set the flags to public. If the
       
   430   // resolved interface does not contain "clone" or "finalize"
       
   431   // methods, the method/interface method resolution looks to
       
   432   // the interface's super class, java.lang.Object.  With JDK 8
       
   433   // interface accessability check requirement, special casing
       
   434   // this scenario is necessary to avoid an IAE.
       
   435   //
   439   //
   436   // We'll check for each method name first and then java.lang.Object
   440   // We'll check for the method name first, as that's most likely
   437   // to best short-circuit out of these tests.
   441   // to be false (so we'll short-circuit out of these tests).
   438   if (((sel_method->name() == vmSymbols::clone_name() &&
   442   if (sel_method->name() == vmSymbols::clone_name() &&
   439         (resolved_klass->oop_is_array() || resolved_klass->is_interface())) ||
   443       sel_klass() == SystemDictionary::Object_klass() &&
   440        (sel_method->name() == vmSymbols::finalize_method_name() &&
   444       resolved_klass->oop_is_array()) {
   441         resolved_klass->is_interface())) &&
       
   442       sel_klass() == SystemDictionary::Object_klass()) {
       
   443     // We need to change "protected" to "public".
   445     // We need to change "protected" to "public".
   444     assert(flags.is_protected(), "clone or finalize not protected?");
   446     assert(flags.is_protected(), "clone not protected?");
   445     jint new_flags = flags.as_int();
   447     jint new_flags = flags.as_int();
   446     new_flags = new_flags & (~JVM_ACC_PROTECTED);
   448     new_flags = new_flags & (~JVM_ACC_PROTECTED);
   447     new_flags = new_flags | JVM_ACC_PUBLIC;
   449     new_flags = new_flags | JVM_ACC_PUBLIC;
   448     flags.set_flags(new_flags);
   450     flags.set_flags(new_flags);
   449   }
   451   }
   529         resolved_klass()->external_name());
   531         resolved_klass()->external_name());
   530     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   532     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   531   }
   533   }
   532 
   534 
   533   // 2. lookup method in resolved klass and its super klasses
   535   // 2. lookup method in resolved klass and its super klasses
   534   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
   536   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
   535 
   537 
   536   if (resolved_method.is_null()) { // not found in the class hierarchy
   538   if (resolved_method.is_null()) { // not found in the class hierarchy
   537     // 3. lookup method in all the interfaces implemented by the resolved klass
   539     // 3. lookup method in all the interfaces implemented by the resolved klass
   538     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   540     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   539 
   541 
   626     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   628     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   627   }
   629   }
   628 
   630 
   629   // lookup method in this interface or its super, java.lang.Object
   631   // lookup method in this interface or its super, java.lang.Object
   630   // JDK8: also look for static methods
   632   // JDK8: also look for static methods
   631   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
   633   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
   632 
   634 
   633   if (resolved_method.is_null()) {
   635   if (resolved_method.is_null()) {
   634     // lookup method in all the super-interfaces
   636     // lookup method in all the super-interfaces
   635     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   637     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   636     if (resolved_method.is_null()) {
   638     if (resolved_method.is_null()) {