I take a little time to create a simple test case to reproduce a bug
found by Charles Nutter with c2.
see http://groups.google.com/group/jvm-languages/browse_thread/thread/6c9e05ecd28fdcd4#
Here is the test case,
There is 3 classes A, B, C that inherit from AbstractFoo that implements Foo.
The method test do a virtual call to check() and because
check() is implemented in AbstractFoo we expect that this call should be
de-virtualized then inlined.
c2 fails, foo.check() is compiled as a virtual call :(
With c1, there is no problem, CHA works correctly.
Rémi
------------------------------------------------------------------------------------------------
public class InlineTest {
interface Foo {
public boolean check(int generation);
}
static class AbstractFoo implements Foo {
private final int value;
protected AbstractFoo(int value) {
this.value = value;
}
public boolean check(int generation) {
return this.getClass().hashCode() - value == generation;
}
}
static class A extends AbstractFoo {
public A(int value) {
super(value);
}
}
static class B extends AbstractFoo {
public B(int value) {
super(value);
}
}
static class C extends AbstractFoo {
public C(int value) {
super(value);
}
}
private static final int CONST = A.class.hashCode();
private static int count;
private static void test(Foo foo) {
if (foo.check(0)) {
count += 2;
//System.out.println("foo");
} else {
count += 1;
//System.out.println("bar");
}
}
public static void main(String[] args) {
Foo[] array = new Foo[100000];
int threshold = 20000;
for(int i=0; i<threshold; i++) {
array[i] = new A(CONST);
}
for(int i=threshold; i<array.length; i++) {
array[i] = (i%2 == 0)? new B(0): new C(CONST);
}
for(int i=0; i<array.length; i++) {
test(array[i]);
}
System.out.println(count);
}
}
found by Charles Nutter with c2.
see http://groups.google.com/group/jvm-languages/browse_thread/thread/6c9e05ecd28fdcd4#
Here is the test case,
There is 3 classes A, B, C that inherit from AbstractFoo that implements Foo.
The method test do a virtual call to check() and because
check() is implemented in AbstractFoo we expect that this call should be
de-virtualized then inlined.
c2 fails, foo.check() is compiled as a virtual call :(
With c1, there is no problem, CHA works correctly.
Rémi
------------------------------------------------------------------------------------------------
public class InlineTest {
interface Foo {
public boolean check(int generation);
}
static class AbstractFoo implements Foo {
private final int value;
protected AbstractFoo(int value) {
this.value = value;
}
public boolean check(int generation) {
return this.getClass().hashCode() - value == generation;
}
}
static class A extends AbstractFoo {
public A(int value) {
super(value);
}
}
static class B extends AbstractFoo {
public B(int value) {
super(value);
}
}
static class C extends AbstractFoo {
public C(int value) {
super(value);
}
}
private static final int CONST = A.class.hashCode();
private static int count;
private static void test(Foo foo) {
if (foo.check(0)) {
count += 2;
//System.out.println("foo");
} else {
count += 1;
//System.out.println("bar");
}
}
public static void main(String[] args) {
Foo[] array = new Foo[100000];
int threshold = 20000;
for(int i=0; i<threshold; i++) {
array[i] = new A(CONST);
}
for(int i=threshold; i<array.length; i++) {
array[i] = (i%2 == 0)? new B(0): new C(CONST);
}
for(int i=0; i<array.length; i++) {
test(array[i]);
}
System.out.println(count);
}
}
- relates to
-
JDK-8218406 C1: Redundant nmethod dependency for private method is added
- Closed
-
JDK-8280469 No CHA for interface calls when inlining through method handle linker
- Open
-
JDK-8222413 JTreg test compiler/cha/StrengthReduceInterfaceCall.java fails
- Closed