1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package compiler.valhalla.valuetypes; 25 26 import java.util.Random; 27 import jdk.test.lib.Asserts; 28 29 /** 30 * @test 31 * @bug 8209009 32 * @summary Test bimorphic inlining with value receivers. 33 * @library /testlibrary /test/lib 34 * @run main/othervm -XX:+EnableValhalla -Xbatch -XX:TypeProfileLevel=222 35 * -XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.TestBimorphicInlining::test* 36 * -XX:CompileCommand=quiet -XX:CompileCommand=print,compiler.valhalla.valuetypes.TestBimorphicInlining::test* 37 * compiler.valhalla.valuetypes.TestBimorphicInlining 38 * @run main/othervm -XX:+EnableValhalla -Xbatch -XX:TypeProfileLevel=222 39 * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=0 -XX:PerMethodSpecTrapLimit=0 40 * -XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.TestBimorphicInlining::test* 41 * -XX:CompileCommand=quiet -XX:CompileCommand=print,compiler.valhalla.valuetypes.TestBimorphicInlining::test* 42 * compiler.valhalla.valuetypes.TestBimorphicInlining 43 */ 44 45 interface MyInterface { 46 public MyInterface hash(MyInterface arg); 47 } 48 49 value final class TestValue1 implements MyInterface { 50 final int x; 51 52 public TestValue1(int x) { 53 this.x = x; 54 } 55 56 public TestValue1 hash(MyInterface arg) { 57 return new TestValue1(x + ((TestValue1)arg).x); 58 } 59 } 60 61 value final class TestValue2 implements MyInterface { 62 final int x; 63 64 public TestValue2(int x) { 65 this.x = x; 66 } 67 68 public TestValue2 hash(MyInterface arg) { 69 return new TestValue2(x + ((TestValue2)arg).x); 70 } 71 } 72 73 class TestClass implements MyInterface { 74 int x; 75 76 public TestClass(int x) { 77 this.x = x; 78 } 79 80 public MyInterface hash(MyInterface arg) { 81 return new TestClass(x + ((TestClass)arg).x); 82 } 83 } 84 85 public class TestBimorphicInlining { 86 87 public static MyInterface test1(MyInterface i1, MyInterface i2) { 88 MyInterface result = i1.hash(i2); 89 i1.hash(i2); 90 return result; 91 } 92 93 public static MyInterface test2(MyInterface i1, MyInterface i2) { 94 MyInterface result = i1.hash(i2); 95 i1.hash(i2); 96 return result; 97 } 98 99 public static MyInterface test3(MyInterface i1, MyInterface i2) { 100 MyInterface result = i1.hash(i2); 101 i1.hash(i2); 102 return result; 103 } 104 105 public static MyInterface test4(MyInterface i1, MyInterface i2) { 106 MyInterface result = i1.hash(i2); 107 i1.hash(i2); 108 return result; 109 } 110 111 static public void main(String[] args) { 112 Random rand = new Random(); 113 TestClass testObject = new TestClass(rand.nextInt()); 114 TestValue1 testValue1 = new TestValue1(rand.nextInt()); 115 TestValue2 testValue2 = new TestValue2(rand.nextInt()); 116 117 for (int i = 0; i < 10_000; ++i) { 118 // Trigger bimorphic inlining by calling test methods with different arguments 119 MyInterface arg, res; 120 boolean rare = (i % 10 == 0); 121 122 arg = rare ? testValue1 : testObject; 123 res = test1(arg, arg); 124 Asserts.assertEQ(rare ? ((TestValue1)res).x : ((TestClass)res).x, 2 * (rare ? testValue1.x : testObject.x), "test1 failed"); 125 126 arg = rare ? testObject : testValue1; 127 res = test2(arg, arg); 128 Asserts.assertEQ(rare ? ((TestClass)res).x : ((TestValue1)res).x, 2 * (rare ? testObject.x : testValue1.x), "test2 failed"); 129 130 arg = rare ? testValue1 : testValue2; 131 res = test3(arg, arg); 132 Asserts.assertEQ(rare ? ((TestValue1)res).x : ((TestValue2)res).x, 2 * (rare ? testValue1.x : testValue2.x), "test3 failed"); 133 134 arg = rare ? testValue2 : testValue1; 135 res = test4(arg, arg); 136 Asserts.assertEQ(rare ? ((TestValue2)res).x : ((TestValue1)res).x, 2 * (rare ? testValue2.x : testValue1.x), "test4 failed"); 137 } 138 } 139 }