1 /* 2 * Copyright (c) 2019, 2024, 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.inlinetypes; 25 26 import java.util.Random; 27 import jdk.test.lib.Asserts; 28 29 /** 30 * @test 31 * @key randomness 32 * @bug 8209009 33 * @summary Test bimorphic inlining with value object receivers. 34 * @library /testlibrary /test/lib 35 * @enablePreview 36 * @run main/othervm -Xbatch -XX:TypeProfileLevel=222 37 * -XX:CompileCommand=compileonly,compiler.valhalla.inlinetypes.TestBimorphicInlining::test* 38 * -XX:CompileCommand=quiet -XX:CompileCommand=print,compiler.valhalla.inlinetypes.TestBimorphicInlining::test* 39 * compiler.valhalla.inlinetypes.TestBimorphicInlining 40 * @run main/othervm -Xbatch -XX:TypeProfileLevel=222 41 * -XX:+UnlockExperimentalVMOptions -XX:PerMethodTrapLimit=0 -XX:PerMethodSpecTrapLimit=0 42 * -XX:CompileCommand=compileonly,compiler.valhalla.inlinetypes.TestBimorphicInlining::test* 43 * -XX:CompileCommand=quiet -XX:CompileCommand=print,compiler.valhalla.inlinetypes.TestBimorphicInlining::test* 44 * compiler.valhalla.inlinetypes.TestBimorphicInlining 45 */ 46 47 interface MyInterface { 48 public MyInterface hash(MyInterface arg); 49 } 50 51 value class TestValue1 implements MyInterface { 52 int x; 53 54 public TestValue1(int x) { 55 this.x = x; 56 } 57 58 public TestValue1 hash(MyInterface arg) { 59 return new TestValue1(x + ((TestValue1)arg).x); 60 } 61 } 62 63 value class TestValue2 implements MyInterface { 64 int x; 65 66 public TestValue2(int x) { 67 this.x = x; 68 } 69 70 public TestValue2 hash(MyInterface arg) { 71 return new TestValue2(x + ((TestValue2)arg).x); 72 } 73 } 74 75 class TestClass implements MyInterface { 76 int x; 77 78 public TestClass(int x) { 79 this.x = x; 80 } 81 82 public MyInterface hash(MyInterface arg) { 83 return new TestClass(x + ((TestClass)arg).x); 84 } 85 } 86 87 public class TestBimorphicInlining { 88 89 public static MyInterface test1(MyInterface i1, MyInterface i2) { 90 MyInterface result = i1.hash(i2); 91 i1.hash(i2); 92 return result; 93 } 94 95 public static MyInterface test2(MyInterface i1, MyInterface i2) { 96 MyInterface result = i1.hash(i2); 97 i1.hash(i2); 98 return result; 99 } 100 101 public static MyInterface test3(MyInterface i1, MyInterface i2) { 102 MyInterface result = i1.hash(i2); 103 i1.hash(i2); 104 return result; 105 } 106 107 public static MyInterface test4(MyInterface i1, MyInterface i2) { 108 MyInterface result = i1.hash(i2); 109 i1.hash(i2); 110 return result; 111 } 112 113 static public void main(String[] args) { 114 Random rand = new Random(); 115 TestClass testObject = new TestClass(rand.nextInt()); 116 TestValue1 testValue1 = new TestValue1(rand.nextInt()); 117 TestValue2 testValue2 = new TestValue2(rand.nextInt()); 118 119 for (int i = 0; i < 10_000; ++i) { 120 // Trigger bimorphic inlining by calling test methods with different arguments 121 MyInterface arg, res; 122 boolean rare = (i % 10 == 0); 123 124 arg = rare ? testValue1 : testObject; 125 res = test1(arg, arg); 126 Asserts.assertEQ(rare ? ((TestValue1)res).x : ((TestClass)res).x, 2 * (rare ? testValue1.x : testObject.x), "test1 failed"); 127 128 arg = rare ? testObject : testValue1; 129 res = test2(arg, arg); 130 Asserts.assertEQ(rare ? ((TestClass)res).x : ((TestValue1)res).x, 2 * (rare ? testObject.x : testValue1.x), "test2 failed"); 131 132 arg = rare ? testValue1 : testValue2; 133 res = test3(arg, arg); 134 Asserts.assertEQ(rare ? ((TestValue1)res).x : ((TestValue2)res).x, 2 * (rare ? testValue1.x : testValue2.x), "test3 failed"); 135 136 arg = rare ? testValue2 : testValue1; 137 res = test4(arg, arg); 138 Asserts.assertEQ(rare ? ((TestValue2)res).x : ((TestValue1)res).x, 2 * (rare ? testValue2.x : testValue1.x), "test4 failed"); 139 } 140 } 141 }