< prev index next >

src/hotspot/share/oops/klassVtable.cpp

Print this page

        

@@ -636,10 +636,11 @@
   Symbol* signature = target_method()->signature();
   const Klass* k = super;
   Method* super_method = NULL;
   InstanceKlass *holder = NULL;
   Method* recheck_method =  NULL;
+  bool found_pkg_prvt_method = false;
   while (k != NULL) {
     // lookup through the hierarchy for a method with matching name and sign.
     super_method = InstanceKlass::cast(k)->lookup_method(name, signature);
     if (super_method == NULL) {
       break; // we still have to search for a matching miranda method

@@ -657,30 +658,45 @@
        (!super_method->is_private())) {
       if (superk->is_override(super_method, classloader, classname, THREAD)) {
         return false;
       // else keep looking for transitive overrides
       }
+      // If we get here then one of the super classes has a package private method
+      // that will not get overridden because it is in a different package.  But,
+      // that package private method does 'override' any matching methods in super
+      // interfaces.  So, set flag to TRUE for use below where existance of a
+      // miranda method is checked.
+      assert(super_method->is_package_private(), "super_method must be package private");
+      assert(!superk->is_same_class_package(classloader(), classname),
+             "Must be different packages");
+      found_pkg_prvt_method = true;
     }
 
     // Start with lookup result and continue to search up, for versions supporting transitive override
     if (major_version >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) {
       k = superk->super(); // haven't found an override match yet; continue to look
     } else {
       break;
     }
   }
 
+  // Only look for a miranda method if the method was not found in a package
+  // private class because, if it was found in a package private class, then
+  // there will be no miranda method, even if the method is also in a super
+  // interface.
+  if (!found_pkg_prvt_method) {
   // if the target method is public or protected it may have a matching
   // miranda method in the super, whose entry it should re-use.
   // Actually, to handle cases that javac would not generate, we need
   // this check for all access permissions.
   const InstanceKlass *sk = InstanceKlass::cast(super);
   if (sk->has_miranda_methods()) {
     if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) {
       return false;  // found a matching miranda; we do not need a new entry
     }
   }
+  }
   return true; // found no match; we need a new entry
 }
 
 // Support for miranda methods
 
< prev index next >