changeset 7244:02e2c04a3289

8065366: Better private method resolution Reviewed-by: hseigel, lfoltan, coleenp, ahgross
author acorn
date Thu, 18 Dec 2014 17:59:15 -0800
parents 7622232b7efa
children eff80b90c3ad
files src/share/vm/classfile/defaultMethods.cpp src/share/vm/oops/klassVtable.cpp
diffstat 2 files changed, 34 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/defaultMethods.cpp	Wed Dec 17 09:10:57 2014 -0800
+++ b/src/share/vm/classfile/defaultMethods.cpp	Thu Dec 18 17:59:15 2014 -0800
@@ -731,10 +731,12 @@
     Method* m = iklass->find_method(_method_name, _method_signature);
     // private interface methods are not candidates for default methods
     // invokespecial to private interface methods doesn't use default method logic
+    // private class methods are not candidates for default methods,
+    // private methods do not override default methods, so need to perform
+    // default method inheritance without including private methods
     // The overpasses are your supertypes' errors, we do not include them
     // future: take access controls into account for superclass methods
-    if (m != NULL && !m->is_static() && !m->is_overpass() &&
-         (!iklass->is_interface() || m->is_public())) {
+    if (m != NULL && !m->is_static() && !m->is_overpass() && !m->is_private()) {
       if (_family == NULL) {
         _family = new StatefulMethodFamily();
       }
@@ -745,6 +747,9 @@
       } else {
         // This is the rule that methods in classes "win" (bad word) over
         // methods in interfaces. This works because of single inheritance
+        // private methods in classes do not "win", they will be found
+        // first on searching, but overriding for invokevirtual needs
+        // to find default method candidates for the same signature
         _family->set_target_if_empty(m);
       }
     }
--- a/src/share/vm/oops/klassVtable.cpp	Wed Dec 17 09:10:57 2014 -0800
+++ b/src/share/vm/oops/klassVtable.cpp	Thu Dec 18 17:59:15 2014 -0800
@@ -401,13 +401,15 @@
       // get super_klass for method_holder for the found method
       InstanceKlass* super_klass =  super_method->method_holder();
 
-      if (is_default
+      // private methods are also never overridden
+      if (!super_method->is_private() &&
+          (is_default
           || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD))
           || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
           && ((super_klass = find_transitive_override(super_klass,
                              target_method, i, target_loader,
                              target_classname, THREAD))
-                             != (InstanceKlass*)NULL))))
+                             != (InstanceKlass*)NULL)))))
         {
         // Package private methods always need a new entry to root their own
         // overriding. They may also override other methods.
@@ -689,9 +691,15 @@
 // check if a method is a miranda method, given a class's methods table,
 // its default_method table  and its super
 // Miranda methods are calculated twice:
-// first: before vtable size calculation: including abstract and default
+// first: before vtable size calculation: including abstract and superinterface default
+// We include potential default methods to give them space in the vtable.
+// During the first run, the default_methods list is empty
 // This is seen by default method creation
-// Second: recalculated during vtable initialization: only abstract
+// Second: recalculated during vtable initialization: only include abstract methods.
+// During the second run, default_methods is set up, so concrete methods from
+// superinterfaces with matching names/signatures to default_methods are already
+// in the default_methods list and do not need to be appended to the vtable
+// as mirandas
 // This is seen by link resolution and selection.
 // "miranda" means not static, not defined by this class.
 // private methods in interfaces do not belong in the miranda list.
@@ -706,8 +714,9 @@
   }
   Symbol* name = m->name();
   Symbol* signature = m->signature();
+  Method* mo;
 
-  if (InstanceKlass::find_instance_method(class_methods, name, signature) == NULL) {
+  if ((mo = InstanceKlass::find_instance_method(class_methods, name, signature)) == NULL) {
     // did not find it in the method table of the current class
     if ((default_methods == NULL) ||
         InstanceKlass::find_method(default_methods, name, signature) == NULL) {
@@ -716,7 +725,7 @@
         return true;
       }
 
-      Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature);
+      mo = InstanceKlass::cast(super)->lookup_method(name, signature);
       while (mo != NULL && mo->access_flags().is_static()
              && mo->method_holder() != NULL
              && mo->method_holder()->super() != NULL)
@@ -728,6 +737,18 @@
         return true;
       }
     }
+  } else {
+     // if the local class has a private method, the miranda will not
+     // override it, so a vtable slot is needed
+     if (mo->access_flags().is_private()) {
+
+       // Second round, weed out any superinterface methods that turned
+       // into default methods, i.e. were concrete not abstract in the end
+       if ((default_methods == NULL) ||
+         InstanceKlass::find_method(default_methods, name, signature) == NULL) {
+         return true;
+       }
+    }
   }
 
   return false;