8024930: Re-enable disabled bridging tests
Reviewed-by: psandoz, rfield
This commit is contained in:
parent
9d30f46219
commit
6dcdc5b742
@ -46,7 +46,7 @@ public class Compiler {
|
||||
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 class Compiler {
|
||||
}
|
||||
|
||||
public void setFlags(Flags ... flags) {
|
||||
this.flags = new HashSet<Flags>(Arrays.asList(flags));
|
||||
this.flags = new HashSet<>(Arrays.asList(flags));
|
||||
}
|
||||
|
||||
public void addPostprocessor(ClassFilePreprocessor cfp) {
|
||||
@ -131,17 +131,10 @@ public class Compiler {
|
||||
outputDirs.put(type.getName(), outDir);
|
||||
|
||||
Class superClass = type.getSuperclass();
|
||||
if (superClass != null) {
|
||||
for( Map.Entry<String,File> each : compileHierarchy(superClass).entrySet()) {
|
||||
outputDirs.put(each.getKey(), each.getValue());
|
||||
}
|
||||
}
|
||||
for (Extends ext : type.getSupertypes()) {
|
||||
Type iface = ext.getType();
|
||||
for( Map.Entry<String,File> 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 @@ public class Compiler {
|
||||
SourceProcessor accum =
|
||||
(name, src) -> { files.add(new SourceFile(name, src)); };
|
||||
|
||||
for (Type dep : type.typeDependencies()) {
|
||||
dep.generateAsDependency(accum, type.methodDependencies());
|
||||
Collection<Type> 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 @@ public class Compiler {
|
||||
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) {
|
||||
|
@ -48,7 +48,7 @@ public class SourceModel {
|
||||
generate(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class AccessFlag extends Element {
|
||||
private String flag;
|
||||
@ -125,6 +125,7 @@ public class SourceModel {
|
||||
// (and thus will be present in stubs)
|
||||
private Set<Method> methodDependencies;
|
||||
private List<Type> typeDependencies;
|
||||
private boolean fullCompilation;
|
||||
|
||||
protected Type(String name,
|
||||
List<AccessFlag> flags, List<TypeParameter> params,
|
||||
@ -214,6 +215,14 @@ public class SourceModel {
|
||||
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 @@ public class SourceModel {
|
||||
pw.println("}");
|
||||
}
|
||||
|
||||
public Collection<Type> typeDependencies() {
|
||||
public Collection<Type> typeDependencies(boolean recursive) {
|
||||
HashMap<String,Type> 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);
|
||||
|
@ -198,7 +198,7 @@ public class TestHarness {
|
||||
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 @@ public class TestHarness {
|
||||
* 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 @@ public class TestHarness {
|
||||
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<? extends Throwable> 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
|
||||
|
@ -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.testng.annotations.Test;
|
||||
import org.openjdk.tests.separate.*;
|
||||
import org.openjdk.tests.separate.Compiler;
|
||||
import org.openjdk.tests.separate.TestHarness;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
|
||||
/**
|
||||
* interface I<T> { default int m(T t) { return 99; } }
|
||||
* Class C implements I<String> { public int m() { return 88; } }
|
||||
* Class C implements I<String> { 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* TEST: J<String,String> j = new C(); j.m("A","B","C") == 88;
|
||||
* TEST: K<String> 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
S.addCompilationDependency(Dstub);
|
||||
S.addCompilationDependency(DstubMethod);
|
||||
|
||||
assertInvokeVirtualEquals(new Integer(88), S, toCall, "null");
|
||||
assertInvokeVirtualEquals(88, S, toCall, "null");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -757,7 +757,6 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
* 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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
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 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
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() {
|
||||
|
Loading…
Reference in New Issue
Block a user