8098557: Only init superintf if subclass, not sub interface inits.
Summary: must exclude jck lang exec05001m311_rt until fixed.
Reviewed-by: lfoltan, hseigel, dholmes
--- 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) {