1 /*
  2  * Copyright (c) 2021, 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 /**
 25  * @test
 26  * @bug 8275825 8289686
 27  * @summary Verify that trivial accessor methods operating on an inline type
 28  *          field are C2 compiled to enable scalarization of the arg/return value.
 29  * @requires vm.compiler2.enabled
 30  * @library /test/lib /compiler/whitebox /
 31  * @enablePreview
 32  * @modules java.base/jdk.internal.value
 33  *          java.base/jdk.internal.vm.annotation
 34  * @build jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 35  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 36  * @run main/othervm -Xbootclasspath/a:.
 37  *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch
 38  *                   -XX:+InlineTypePassFieldsAsArgs -XX:+InlineTypeReturnedAsFields
 39  *                   -XX:+IgnoreUnrecognizedVMOptions -XX:-StressCallingConvention
 40  *                   -XX:CompileCommand=dontinline,*::getter* -XX:CompileCommand=dontinline,*::setter*
 41  *                   -XX:CompileCommand=dontinline,*::constantGetter*
 42  *                   compiler.valhalla.inlinetypes.TestTrivialMethods
 43  */
 44 
 45 package compiler.valhalla.inlinetypes;
 46 
 47 import compiler.whitebox.CompilerWhiteBoxTest;
 48 
 49 import java.lang.reflect.Method;
 50 
 51 import jdk.internal.value.ValueClass;
 52 import jdk.internal.vm.annotation.ImplicitlyConstructible;
 53 import jdk.internal.vm.annotation.LooselyConsistentValue;
 54 import jdk.internal.vm.annotation.NullRestricted;
 55 
 56 import jdk.test.lib.Asserts;
 57 import jdk.test.lib.Utils;
 58 
 59 import jdk.test.whitebox.WhiteBox;
 60 
 61 public class TestTrivialMethods {
 62     public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
 63 
 64     @NullRestricted
 65     static MyValue3 staticField = MyValue3.create();
 66     static MyValue3 staticFieldRef = MyValue3.create();
 67     @NullRestricted
 68     MyValue3 field = MyValue3.create();
 69     MyValue3 fieldRef = MyValue3.create();
 70     Object objField = null;
 71 
 72     public MyValue3 getter1() {
 73         return staticField;
 74     }
 75 
 76     public static MyValue3 getter2() {
 77         return staticField;
 78     }
 79 
 80     public MyValue3 getter3() {
 81         return field;
 82     }
 83 
 84     public Object getter4(MyValue3 unusedArg) {
 85         return objField;
 86     }
 87 
 88     public int constantGetter(MyValue3 unusedArg) {
 89         return 0;
 90     }
 91 
 92     public MyValue3 getter1Ref() {
 93         return staticFieldRef;
 94     }
 95 
 96     public static MyValue3 getter2Ref() {
 97         return staticFieldRef;
 98     }
 99 
100     public MyValue3 getter3Ref() {
101         return fieldRef;
102     }
103 
104     public Object getter4Ref(MyValue3 unusedArg) {
105         return objField;
106     }
107 
108     public int constantGetterRef(MyValue3 unusedArg) {
109         return 0;
110     }
111 
112     public void setter1(MyValue3 val) {
113         staticField = val;
114     }
115 
116     public static void setter2(MyValue3 val) {
117         staticField = val;
118     }
119 
120     public void setter3(MyValue3 val) {
121         field = val;
122     }
123 
124     public void setter1Ref(MyValue3 val) {
125         staticFieldRef = val;
126     }
127 
128     public static void setter2Ref(MyValue3 val) {
129         staticFieldRef = val;
130     }
131 
132     public void setter3Ref(MyValue3 val) {
133         fieldRef = val;
134     }
135 
136     public static void main(String[] args) throws Exception {
137         TestTrivialMethods t = new TestTrivialMethods();
138         // Warmup to trigger compilation
139         for (int i = 0; i < 100_000; ++i) {
140             t.getter1();
141             t.getter2();
142             t.getter3();
143             t.getter4(staticField);
144             t.constantGetter(staticField);
145             t.getter1Ref();
146             t.getter2Ref();
147             t.getter3Ref();
148             t.getter3Ref();
149             t.getter4Ref(null);
150             t.constantGetterRef(null);
151             t.setter1(staticField);
152             t.setter2(staticField);
153             t.setter3(staticField);
154             t.setter1Ref(staticField);
155             t.setter2Ref(staticField);
156             t.setter3Ref(staticField);
157         }
158         Method m = TestTrivialMethods.class.getMethod("getter1");
159         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter1 is not C2 compiled");
160         m = TestTrivialMethods.class.getMethod("getter2");
161         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter2 is not C2 compiled");
162         m = TestTrivialMethods.class.getMethod("getter3");
163         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter3 is not C2 compiled");
164         m = TestTrivialMethods.class.getMethod("setter1", MyValue3.class);
165         m = TestTrivialMethods.class.getMethod("getter4", MyValue3.class);
166         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter4 is not C2 compiled");
167         m = TestTrivialMethods.class.getMethod("constantGetter", MyValue3.class);
168         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "constantGetter is not C2 compiled");
169         m = TestTrivialMethods.class.getMethod("getter1Ref");
170         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter1Ref is not C2 compiled");
171         m = TestTrivialMethods.class.getMethod("getter2Ref");
172         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter2Ref is not C2 compiled");
173         m = TestTrivialMethods.class.getMethod("getter3Ref");
174         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter3Ref is not C2 compiled");
175         m = TestTrivialMethods.class.getMethod("getter4Ref", MyValue3.class);
176         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "getter4Ref is not C2 compiled");
177         m = TestTrivialMethods.class.getMethod("constantGetterRef", MyValue3.class);
178         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "constantGetterRef is not C2 compiled");
179         m = TestTrivialMethods.class.getMethod("setter1", MyValue3.class);
180         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "setter1 is not C2 compiled");
181         m = TestTrivialMethods.class.getMethod("setter2", MyValue3.class);
182         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "setter2 is not C2 compiled");
183         m = TestTrivialMethods.class.getMethod("setter3", MyValue3.class);
184         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "setter3 is not C2 compiled");
185         m = TestTrivialMethods.class.getMethod("setter1Ref", MyValue3.class);
186         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "setter1Ref is not C2 compiled");
187         m = TestTrivialMethods.class.getMethod("setter2Ref", MyValue3.class);
188         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "setter2Ref is not C2 compiled");
189         m = TestTrivialMethods.class.getMethod("setter3Ref", MyValue3.class);
190         Asserts.assertEQ(WHITE_BOX.getMethodCompilationLevel(m, false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "setter3Ref is not C2 compiled");
191     }
192 }