< 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 >