8098557: Only init superintf if subclass, not sub interface inits.
authoracorn
Wed, 25 Nov 2015 09:08:51 -0500
changeset 34303 9e271398a718
parent 34292 e005cf237e46
child 34304 3063f2e58c1b
8098557: Only init superintf if subclass, not sub interface inits. Summary: must exclude jck lang exec05001m311_rt until fixed. Reviewed-by: lfoltan, hseigel, dholmes
hotspot/src/share/vm/oops/instanceKlass.cpp
hotspot/test/runtime/lambda-features/TestInterfaceInit.java
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Nov 25 11:45:26 2015 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Nov 25 09:08:51 2015 -0500
@@ -815,10 +815,13 @@
     }
   }
 
+  // If C is an interface that declares a non-abstract, non-static method,
+  // the initialization of a class (not an interface) that implements C directly or
+  // indirectly.
   // Recursively initialize any superinterfaces that declare default methods
   // Only need to recurse if has_default_methods which includes declaring and
   // inheriting default methods
-  if (this_k->has_default_methods()) {
+  if (!this_k->is_interface() && this_k->has_default_methods()) {
     this_k->initialize_super_interfaces(this_k, CHECK);
   }
 
--- a/hotspot/test/runtime/lambda-features/TestInterfaceInit.java	Wed Nov 25 11:45:26 2015 +0000
+++ b/hotspot/test/runtime/lambda-features/TestInterfaceInit.java	Wed Nov 25 09:08:51 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
 /*
  * @test
  * @bug 8034275
- * @summary [JDK 8u40] Test interface initialization: only for interfaces declaring default methods
+ * @bug 8098557
+ * @summary [JDK 8u40] Test interface init: only for interfaces declaring default methods, when subclass inits
  * @run main TestInterfaceInit
  */
 import java.util.List;
@@ -39,43 +40,59 @@
    // Declares a default method and initializes
    interface I {
        boolean v = TestInterfaceInit.out(I.class);
-        default void x() {}
+        default void ix() {}
    }
 
    // Declares a default method and initializes
    interface J extends I {
        boolean v = TestInterfaceInit.out(J.class);
-       default void x() {}
+       default void jx() {}
    }
-   // No default method, does not initialize
+   // No default method, has an abstract method, does not initialize
    interface JN extends J {
        boolean v = TestInterfaceInit.out(JN.class);
+       public abstract void jnx();
    }
 
    // Declares a default method and initializes
    interface K extends I {
        boolean v = TestInterfaceInit.out(K.class);
-        default void x() {}
+        default void kx() {}
    }
 
-   // No default method, does not initialize
+   // No default method, has a static method, does not initialize
    interface KN extends K {
        boolean v = TestInterfaceInit.out(KN.class);
+       static void knx() {}
    }
 
    interface L extends JN, KN {
        boolean v = TestInterfaceInit.out(L.class);
-        default void x() {}
+        default void lx() {}
+   }
+
+   static class ChildClass implements JN, KN {
+       boolean v = TestInterfaceInit.out(ChildClass.class);
+       public void jnx() {}
    }
 
    public static void main(String[] args) {
        // Trigger initialization
        boolean v = L.v;
 
-       List<Class<?>> expectedCInitOrder = Arrays.asList(I.class,J.class,K.class,L.class);
+       List<Class<?>> expectedCInitOrder = Arrays.asList(L.class);
        if (!cInitOrder.equals(expectedCInitOrder)) {
          throw new RuntimeException(String.format("Class initialization array %s not equal to expected array %s", cInitOrder, expectedCInitOrder));
        }
+
+       ChildClass myC = new ChildClass();
+       boolean w = myC.v;
+
+       expectedCInitOrder = Arrays.asList(L.class,I.class,J.class,K.class,ChildClass.class);
+       if (!cInitOrder.equals(expectedCInitOrder)) {
+         throw new RuntimeException(String.format("Class initialization array %s not equal to expected array %s", cInitOrder, expectedCInitOrder));
+       }
+
    }
 
    static boolean out(Class c) {