< prev index next >
test/compiler/valhalla/valuetypes/ValueTypeTestBench.java
Print this page
*** 86,107 ****
final MyValue2 v1;
final MyValue2 v2;
static final MyValue2 v3 = MyValue2.createWithFieldsInline(ValueTypeTestBench.rI, true);
final int c;
- private MyValue1(int x, long y, short z, Integer o, int[] oa, MyValue2 v1, MyValue2 v2, int c) {
- s = x;
- this.x = x;
- this.y = y;
- this.z = z;
- this.o = o;
- this.oa = oa;
- this.v1 = v1;
- this.v2 = v2;
- this.c = c;
- }
-
private MyValue1() {
s = 0;
this.x = 0;
this.y = 0;
this.z = 0;
--- 86,95 ----
*** 112,142 ****
this.c = 0;
}
@DontInline
__ValueFactory static MyValue1 createDefaultDontInline() {
! return __MakeDefault MyValue1();
}
@ForceInline
__ValueFactory static MyValue1 createDefaultInline() {
return __MakeDefault MyValue1();
}
@DontInline
static MyValue1 createWithFieldsDontInline(int x, long y) {
! MyValue1 v = createDefaultInline();
! v = setX(v, x);
! v = setY(v, y);
! v = setZ(v, (short)x);
! v = setO(v, new Integer(x));
! int[] oa = {x};
! v = setOA(v, oa);
! v = setV1(v, MyValue2.createWithFieldsInline(x, x < y));
! v = setV2(v, MyValue2.createWithFieldsInline(x, x > y));
! v = setC(v, ValueTypeTestBench.rI);
! return v;
}
@ForceInline
static MyValue1 createWithFieldsInline(int x, long y) {
MyValue1 v = createDefaultInline();
--- 100,120 ----
this.c = 0;
}
@DontInline
__ValueFactory static MyValue1 createDefaultDontInline() {
! return createDefaultInline();
}
@ForceInline
__ValueFactory static MyValue1 createDefaultInline() {
return __MakeDefault MyValue1();
}
@DontInline
static MyValue1 createWithFieldsDontInline(int x, long y) {
! return createWithFieldsInline(x, y);
}
@ForceInline
static MyValue1 createWithFieldsInline(int x, long y) {
MyValue1 v = createDefaultInline();
*** 232,248 ****
final int x;
final byte y;
final boolean b;
final long c;
- private MyValue2(int x, byte y, boolean b, long c) {
- this.x = x;
- this.y = y;
- this.b = b;
- this.c = c;
- }
-
private MyValue2() {
this.x = 0;
this.y = 0;
this.b = false;
this.c = 0;
--- 210,219 ----
*** 476,485 ****
--- 447,482 ----
v = setF7(v, r.nextFloat());
v = setF8(v, r.nextDouble());
return v;
}
+ @DontInline
+ public static MyValue3 createDontInline() {
+ return create();
+ }
+
+ @ForceInline
+ public static MyValue3 copy(MyValue3 other) {
+ MyValue3 v = createDefault();
+ v = setC(v, other.c);
+ v = setBB(v, other.bb);
+ v = setS(v, other.s);
+ v = setI(v, other.i);
+ v = setL(v, other.l);
+ v = setO(v, other.o);
+ v = setF1(v, other.f1);
+ v = setF2(v, other.f2);
+ v = setF3(v, other.f3);
+ v = setF4(v, other.f4);
+ v = setF5(v, other.f5);
+ v = setF6(v, other.f6);
+ v = setF7(v, other.f7);
+ v = setF8(v, other.f8);
+ return v;
+ }
+
+ @DontInline
public void verify(MyValue3 other) {
Asserts.assertEQ(c, other.c);
Asserts.assertEQ(bb, other.bb);
Asserts.assertEQ(s, other.s);
Asserts.assertEQ(i, other.i);
*** 2424,2433 ****
--- 2421,2570 ----
test86_mh = lookup.findVirtual(ValueTypeTestBench.class, "test86_target", test86_mt);
} catch (NoSuchMethodException|IllegalAccessException e) {
throw new RuntimeException("method handle lookup fails");
}
}
+
+ static MyValue3 staticVal3;
+ static MyValue3 staticVal3_copy;
+
+ // Check elimination of redundant value type allocations
+ @Test(match = {ALLOC}, matchCount = {1})
+ public MyValue3 test87(MyValue3[] va) {
+ // Create value type and force allocation
+ MyValue3 vt = MyValue3.create();
+ va[0] = vt;
+ staticVal3 = vt;
+ vt.verify(staticVal3);
+
+ // Value type is now allocated, make a copy and force allocation.
+ // Because copy is equal to vt, C2 should remove this redundant allocation.
+ MyValue3 copy = MyValue3.setC(vt, vt.c);
+ va[0] = copy;
+ staticVal3_copy = copy;
+ copy.verify(staticVal3_copy);
+ return copy;
+ }
+
+ @DontCompile
+ public void test87_verifier(boolean warmup) {
+ MyValue3[] va = new MyValue3[1];
+ MyValue3 vt = test87(va);
+ staticVal3.verify(vt);
+ staticVal3.verify(va[0]);
+ staticVal3_copy.verify(vt);
+ staticVal3_copy.verify(va[0]);
+ }
+
+ // Verify that only dominating allocations are re-used
+ @Test()
+ public MyValue3 test88(boolean warmup) {
+ MyValue3 vt = MyValue3.create();
+ if (warmup) {
+ staticVal3 = vt; // Force allocation
+ }
+ // Force allocation to verify that above
+ // non-dominating allocation is not re-used
+ MyValue3 copy = MyValue3.setC(vt, vt.c);
+ staticVal3_copy = copy;
+ copy.verify(vt);
+ return copy;
+ }
+
+ @DontCompile
+ public void test88_verifier(boolean warmup) {
+ MyValue3 vt = test88(warmup);
+ if (warmup) {
+ staticVal3.verify(vt);
+ }
+ }
+
+ // Verify that C2 recognizes value type loads and re-uses the oop to avoid allocations
+ @Test(failOn = ALLOC + ALLOCA + STORE)
+ public MyValue3 test89(MyValue3[] va) {
+ // C2 can re-use the oop of staticVal3 because staticVal3 is equal to copy
+ MyValue3 copy = MyValue3.copy(staticVal3);
+ va[0] = copy;
+ staticVal3 = copy;
+ copy.verify(staticVal3);
+ return copy;
+ }
+
+ @DontCompile
+ public void test89_verifier(boolean warmup) {
+ staticVal3 = MyValue3.create();
+ MyValue3[] va = new MyValue3[1];
+ MyValue3 vt = test89(va);
+ staticVal3.verify(vt);
+ staticVal3.verify(va[0]);
+ }
+
+ // Verify that C2 recognizes value type loads and re-uses the oop to avoid allocations
+ @Test(valid = ValueTypeReturnedAsFieldsOff, failOn = ALLOC + ALLOCA + STORE)
+ @Test(valid = ValueTypeReturnedAsFieldsOn)
+ public MyValue3 test90(MyValue3[] va) {
+ // C2 can re-use the oop returned by createDontInline()
+ // because the corresponding value type is equal to 'copy'.
+ MyValue3 copy = MyValue3.copy(MyValue3.createDontInline());
+ va[0] = copy;
+ staticVal3 = copy;
+ copy.verify(staticVal3);
+ return copy;
+ }
+
+ @DontCompile
+ public void test90_verifier(boolean warmup) {
+ MyValue3[] va = new MyValue3[1];
+ MyValue3 vt = test90(va);
+ staticVal3.verify(vt);
+ staticVal3.verify(va[0]);
+ }
+
+ // Verify that C2 recognizes value type loads and re-uses the oop to avoid allocations
+ @Test(valid = ValueTypePassFieldsAsArgsOff, failOn = ALLOC + ALLOCA + STORE)
+ @Test(valid = ValueTypePassFieldsAsArgsOn)
+ public MyValue3 test91(MyValue3 vt, MyValue3[] va) {
+ // C2 can re-use the oop of vt because vt is equal to 'copy'.
+ MyValue3 copy = MyValue3.copy(vt);
+ va[0] = copy;
+ staticVal3 = copy;
+ copy.verify(staticVal3);
+ return copy;
+ }
+
+ @DontCompile
+ public void test91_verifier(boolean warmup) {
+ MyValue3 vt = MyValue3.create();
+ MyValue3[] va = new MyValue3[1];
+ MyValue3 result = test91(vt, va);
+ staticVal3.verify(vt);
+ va[0].verify(vt);
+ result.verify(vt);
+ }
+
+ // Test correct identification of value type copies
+ @Test()
+ public MyValue3 test92(MyValue3[] va) {
+ MyValue3 vt = MyValue3.copy(staticVal3);
+ vt = MyValue3.setI(vt, (int)vt.c);
+ // vt is not equal to staticVal3, so C2 should not re-use the oop
+ va[0] = vt;
+ staticVal3 = vt;
+ vt.verify(staticVal3);
+ return vt;
+ }
+
+ @DontCompile
+ public void test92_verifier(boolean warmup) {
+ staticVal3 = MyValue3.create();
+ MyValue3[] va = new MyValue3[1];
+ MyValue3 vt = test92(va);
+ Asserts.assertEQ(staticVal3.i, (int)staticVal3.c);
+ Asserts.assertEQ(va[0].i, (int)staticVal3.c);
+ Asserts.assertEQ(vt.i, (int)staticVal3.c);
+ }
+
// ========== Test infrastructure ==========
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final int ValueTypePassFieldsAsArgsOn = 0x1;
private static final int ValueTypePassFieldsAsArgsOff = 0x2;
*** 2647,2661 ****
--- 2784,2802 ----
}
System.out.format("rI = %d, rL = %d\n", rI, rL);
setup(this.getClass().getDeclaredMethods());
setup(MyValue1.class.getDeclaredMethods());
setup(MyValue2.class.getDeclaredMethods());
+ setup(MyValue3.class.getDeclaredMethods());
+ setup(MyValue4.class.getDeclaredMethods());
// Compile class initializers
WHITE_BOX.enqueueInitializerForCompilation(this.getClass(), COMP_LEVEL_FULL_OPTIMIZATION);
WHITE_BOX.enqueueInitializerForCompilation(MyValue1.class, COMP_LEVEL_FULL_OPTIMIZATION);
WHITE_BOX.enqueueInitializerForCompilation(MyValue2.class, COMP_LEVEL_FULL_OPTIMIZATION);
+ WHITE_BOX.enqueueInitializerForCompilation(MyValue3.class, COMP_LEVEL_FULL_OPTIMIZATION);
+ WHITE_BOX.enqueueInitializerForCompilation(MyValue4.class, COMP_LEVEL_FULL_OPTIMIZATION);
// Execute tests
for (Method test : tests.values()) {
Method verifier = getClass().getDeclaredMethod(test.getName() + "_verifier", boolean.class);
// Warmup using verifier method
< prev index next >