# HG changeset patch # User briangoetz # Date 1383156736 14400 # Node ID 403632350961dffa8bc683e9a52a7c6ffb018220 # Parent 6c8a8aadc0809de53ef6359d05c7cc9a40684015 8024930: Re-enable disabled bridging tests Reviewed-by: psandoz, rfield diff -r 6c8a8aadc080 -r 403632350961 langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java --- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java Wed Oct 30 18:09:49 2013 +0000 +++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java Wed Oct 30 14:12:16 2013 -0400 @@ -46,7 +46,7 @@ USECACHE // Keeps results around for reuse. Only use this is // you're sure that each compilation name maps to the // same source code - }; + } private static final AtomicInteger counter = new AtomicInteger(); private static final String targetDir = "gen-separate"; @@ -85,7 +85,7 @@ } public void setFlags(Flags ... flags) { - this.flags = new HashSet(Arrays.asList(flags)); + this.flags = new HashSet<>(Arrays.asList(flags)); } public void addPostprocessor(ClassFilePreprocessor cfp) { @@ -131,17 +131,10 @@ outputDirs.put(type.getName(), outDir); Class superClass = type.getSuperclass(); - if (superClass != null) { - for( Map.Entry each : compileHierarchy(superClass).entrySet()) { - outputDirs.put(each.getKey(), each.getValue()); - } - } - for (Extends ext : type.getSupertypes()) { - Type iface = ext.getType(); - for( Map.Entry each : compileHierarchy(iface).entrySet()) { - outputDirs.put(each.getKey(), each.getValue()); - } - } + if (superClass != null) + outputDirs.putAll(compileHierarchy(superClass)); + for (Extends ext : type.getSupertypes()) + outputDirs.putAll(compileHierarchy(ext.getType())); return outputDirs; } @@ -157,8 +150,12 @@ SourceProcessor accum = (name, src) -> { files.add(new SourceFile(name, src)); }; - for (Type dep : type.typeDependencies()) { - dep.generateAsDependency(accum, type.methodDependencies()); + Collection deps = type.typeDependencies(type.isFullCompilation()); + for (Type dep : deps) { + if (type.isFullCompilation()) + dep.generate(accum); + else + dep.generateAsDependency(accum, type.methodDependencies()); } type.generate(accum); @@ -185,7 +182,7 @@ StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir)); } catch (IOException e) { throw new RuntimeException( - "IOException encountered during compilation"); + "IOException encountered during compilation", e); } Boolean result = ct.call(); if (result == Boolean.FALSE) { diff -r 6c8a8aadc080 -r 403632350961 langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java --- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java Wed Oct 30 18:09:49 2013 +0000 +++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java Wed Oct 30 14:12:16 2013 -0400 @@ -48,7 +48,7 @@ generate(pw); return sw.toString(); } - }; + } public static class AccessFlag extends Element { private String flag; @@ -125,6 +125,7 @@ // (and thus will be present in stubs) private Set methodDependencies; private List typeDependencies; + private boolean fullCompilation; protected Type(String name, List flags, List params, @@ -214,6 +215,14 @@ methodDependencies.add(m); } + public boolean isFullCompilation() { + return fullCompilation; + } + + public void setFullCompilation(boolean fullCompilation) { + this.fullCompilation = fullCompilation; + } + // Convenience method for creating an Extends object using this // class and specified type arguments. public Extends with(String ... args) { @@ -255,14 +264,23 @@ pw.println("}"); } - public Collection typeDependencies() { + public Collection typeDependencies(boolean recursive) { HashMap dependencies = new HashMap<>(); Type superclass = getSuperclass(); if (superclass != null) { dependencies.put(superclass.getName(), superclass); + if (recursive) { + for (Type t : superclass.typeDependencies(true)) + dependencies.put(t.getName(), t); + } } - for (Extends e : getSupertypes()) + for (Extends e : getSupertypes()) { dependencies.put(e.getType().getName(), e.getType()); + if (recursive) { + for (Type t : e.getType().typeDependencies(true)) + dependencies.put(t.getName(), t); + } + } // Do these last so that they override for (Type t : this.typeDependencies) dependencies.put(t.getName(), t); diff -r 6c8a8aadc080 -r 403632350961 langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java --- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java Wed Oct 30 18:09:49 2013 +0000 +++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java Wed Oct 30 14:12:16 2013 -0400 @@ -198,7 +198,7 @@ assertEquals(res, value); } } catch (InvocationTargetException | IllegalAccessException e) { - fail("Unexpected exception thrown: " + e.getCause()); + fail("Unexpected exception thrown: " + e.getCause(), e.getCause()); } } @@ -227,8 +227,7 @@ * a return type of 'int', and no arguments. */ public void assertInvokeVirtualEquals(int value, Class target) { - assertInvokeVirtualEquals( - new Integer(value), target, stdCM, "-1"); + assertInvokeVirtualEquals(value, target, stdCM, "-1"); } /** @@ -260,12 +259,31 @@ Compiler compiler = compilerLocal.get(); compiler.setFlags(compilerFlags()); - assertInvokeInterfaceEquals( - new Integer(value), target, new Extends(iface), stdAM); + assertInvokeInterfaceEquals(value, target, new Extends(iface), stdAM); compiler.cleanup(); } + protected void assertInvokeInterfaceThrows(java.lang.Class errorClass, + Class target, Extends iface, AbstractMethod method, + String... args) { + try { + assertInvokeInterfaceEquals(0, target, iface, method, args); + fail("Expected exception: " + errorClass); + } + catch (AssertionError e) { + Throwable cause = e.getCause(); + if (cause == null) + throw e; + else if ((errorClass.isAssignableFrom(cause.getClass()))) { + // this is success + return; + } + else + throw e; + } + } + /** * Creates a class which calls target::method(args) via invokevirtual, * compiles and loads both the new class and 'target', and then invokes diff -r 6c8a8aadc080 -r 403632350961 langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java --- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Wed Oct 30 18:09:49 2013 +0000 +++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Wed Oct 30 14:12:16 2013 -0400 @@ -25,18 +25,22 @@ package org.openjdk.tests.vm; -import java.lang.reflect.*; -import java.util.*; -import java.io.File; -import java.io.IOException; - +import org.openjdk.tests.separate.Compiler; +import org.openjdk.tests.separate.TestHarness; import org.testng.annotations.Test; -import org.openjdk.tests.separate.*; -import org.openjdk.tests.separate.Compiler; -import static org.testng.Assert.*; -import static org.openjdk.tests.separate.SourceModel.*; +import static org.openjdk.tests.separate.SourceModel.AbstractMethod; +import static org.openjdk.tests.separate.SourceModel.AccessFlag; import static org.openjdk.tests.separate.SourceModel.Class; +import static org.openjdk.tests.separate.SourceModel.ConcreteMethod; +import static org.openjdk.tests.separate.SourceModel.DefaultMethod; +import static org.openjdk.tests.separate.SourceModel.Extends; +import static org.openjdk.tests.separate.SourceModel.Interface; +import static org.openjdk.tests.separate.SourceModel.MethodParameter; +import static org.openjdk.tests.separate.SourceModel.TypeParameter; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.fail; @Test(groups = "vm") public class DefaultMethodsTest extends TestHarness { @@ -186,7 +190,7 @@ * TEST: D d = new D(); d.m() == 22; * TEST: I i = new D(); i.m() == 22; */ - void testExistingInheritedOverride() { + public void testExistingInheritedOverride() { Interface I = new Interface("I", DefaultMethod.std("99")); Class C = new Class("C", I, ConcreteMethod.std("11")); Class D = new Class("D", C, ConcreteMethod.std("22")); @@ -258,7 +262,6 @@ * TEST: C c = new C(); c.m() throws ICCE */ public void testConflict() { - // debugTest(); Interface I = new Interface("I", DefaultMethod.std("99")); Interface J = new Interface("J", DefaultMethod.std("88")); Class C = new Class("C", I, J); @@ -390,19 +393,16 @@ /** * interface I { default int m(T t) { return 99; } } - * Class C implements I { public int m() { return 88; } } + * Class C implements I { public int m(String s) { return 88; } } * - * TEST: C c = new C(); c.m() == 88; - * TEST: I i = new C(); i.m() == 88; + * TEST: C c = new C(); c.m("string") == 88; + * TEST: I i = new C(); i.m("string") == 88; */ - @Test(enabled=false) public void testSelfFill() { // This test ensures that a concrete method overrides a default method // that matches at the language-level, but has a different method // signature due to erasure. - // debugTest(); - DefaultMethod dm = new DefaultMethod( "int", "m", "return 99;", new MethodParameter("T", "t")); ConcreteMethod cm = new ConcreteMethod( @@ -415,9 +415,11 @@ AbstractMethod pm = new AbstractMethod( "int", "m", new MethodParameter("T", "t")); - assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\""); - assertInvokeInterfaceEquals( - new Integer(88), C, I.with("String"), pm, "\"string\""); + assertInvokeVirtualEquals(88, C, cm, "-1", "\"string\""); + assertInvokeInterfaceEquals(99, C, I.with("String"), pm, "\"string\""); + + C.setFullCompilation(true); // Force full bridge generation + assertInvokeInterfaceEquals(88, C, I.with("String"), pm, "\"string\""); } /** @@ -485,7 +487,6 @@ * TEST: J j = new C(); j.m("A","B","C") == 88; * TEST: K k = new C(); k.m("A","B","C") == 88; */ - @Test(enabled=false) public void testBridges() { DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", new MethodParameter("T", "t"), new MethodParameter("V", "v"), @@ -518,13 +519,17 @@ J.with("String", "T"), pm2); Class C = new Class("C", K.with("String"), cm); + // First, without compiler bridges String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" }; - assertInvokeInterfaceEquals(new Integer(88), C, - I.with("String", "String", "String"), pm0, args); - assertInvokeInterfaceEquals(new Integer(88), C, - J.with("String", "String"), pm1, args); - assertInvokeInterfaceEquals(new Integer(88), C, - K.with("String"), pm2, args); + assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), pm0, args); + assertInvokeInterfaceThrows(AbstractMethodError.class, C, J.with("String", "String"), pm1, args); + assertInvokeInterfaceThrows(AbstractMethodError.class, C, K.with("String"), pm2, args); + + // Then with compiler bridges + C.setFullCompilation(true); + assertInvokeInterfaceEquals(88, C, I.with("String", "String", "String"), pm0, args); + assertInvokeInterfaceEquals(88, C, J.with("String", "String"), pm1, args); + assertInvokeInterfaceEquals(88, C, K.with("String"), pm2, args); } /** @@ -536,8 +541,6 @@ * TEST: I i = new C(); i.m() == 88; */ public void testSuperBasic() { - // debugTest(); - Interface J = new Interface("J", DefaultMethod.std("88")); Interface I = new Interface("I", J, new DefaultMethod( "int", stdMethodName, "return J.super.m();")); @@ -559,8 +562,6 @@ * TODO: add case for K k = new C(); k.m() throws ICCE */ public void testSuperConflict() { - // debugTest(); - Interface K = new Interface("K", DefaultMethod.std("99")); Interface L = new Interface("L", DefaultMethod.std("101")); Interface J = new Interface("J", K, L); @@ -635,8 +636,7 @@ AbstractMethod pm = new AbstractMethod("int", stdMethodName, new MethodParameter("String", "s")); - assertInvokeInterfaceEquals( - new Integer(88), C, new Extends(I), pm, "\"\""); + assertInvokeInterfaceEquals(88, C, new Extends(I), pm, "\"\""); } /** @@ -674,7 +674,6 @@ * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; * TEST: S s = new S(); s.foo() == new Integer(99) */ - @Test(enabled=false) public void testCovarBridge() { Interface I = new Interface("I", new DefaultMethod( "Integer", "m", "return new Integer(88);")); @@ -692,7 +691,8 @@ S.addCompilationDependency(Dstub); S.addCompilationDependency(DstubMethod); - assertInvokeVirtualEquals(new Integer(99), S, toCall, "null"); + // NEGATIVE test for separate compilation -- dispatches to I, not C + assertInvokeVirtualEquals(88, S, toCall, "null"); } /** @@ -719,7 +719,7 @@ S.addCompilationDependency(Dstub); S.addCompilationDependency(DstubMethod); - assertInvokeVirtualEquals(new Integer(88), S, toCall, "null"); + assertInvokeVirtualEquals(88, S, toCall, "null"); } /** @@ -757,7 +757,6 @@ * Test that a erased-signature-matching method does not implement * non-language-level matching methods */ - @Test(enabled=false) public void testNonConcreteFill() { AbstractMethod ipm = new AbstractMethod("int", "m", new MethodParameter("T", "t"), @@ -781,13 +780,14 @@ new MethodParameter("T", "t"), new MethodParameter("String", "s"), new MethodParameter("String", "w")); + DefaultMethod kdm = new DefaultMethod("int", "m", "return 99;", + new MethodParameter("T", "t"), + new MethodParameter("String", "v"), + new MethodParameter("String", "w")); Interface K = new Interface("K", new TypeParameter("T"), J.with("T", "String"), - new DefaultMethod("int", "m", "return 99;", - new MethodParameter("T", "t"), - new MethodParameter("String", "v"), - new MethodParameter("String", "w"))); + kdm); Class C = new Class("C", K.with("String"), @@ -797,13 +797,18 @@ new MethodParameter("Object", "v"), new MethodParameter("String", "w"))); + // First, without compiler bridges String a = "\"\""; - assertInvokeInterfaceEquals(99, C, - K.with("String"), kpm, a, a, a); - assertInvokeInterfaceEquals(77, C, - J.with("String", "String"), jpm, a, a, a); - assertInvokeInterfaceEquals(99, C, - I.with("String", "String", "String"), ipm, a, a, a); + assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); + assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); + assertInvokeInterfaceThrows(AbstractMethodError.class, C, I.with("String", "String", "String"), ipm, a, a, a); + + // Now, with bridges + J.setFullCompilation(true); + K.setFullCompilation(true); + assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); + assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); + assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), ipm, a, a, a); } public void testStrictfpDefault() {