1 /*
  2  * Copyright (c) 2023, 2025, 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 8301007
 27  * @key randomness
 28  * @summary Verify that mismatches of the preload attribute are properly handled in the calling convention.
 29  * @library /test/lib /compiler/whitebox /
 30  * @enablePreview
 31  * @compile TestMismatchHandling.jcod TestMismatchHandling.java
 32  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 33  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 34  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 35  *                   -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile
 36  *                   -XX:CompileCommand=compileonly,compiler.valhalla.inlinetypes.TestMismatchHandling::test*
 37  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 38  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 39  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 40  *                   -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile
 41  *                   -XX:CompileCommand=compileonly,*::method
 42  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 43  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 44  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 45  *                   -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile
 46  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 47  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 48  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 49  *                   -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile
 50  *                   -XX:-InlineTypePassFieldsAsArgs
 51  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 52  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 53  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 54  *                   -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile
 55  *                   -XX:-InlineTypeReturnedAsFields
 56  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 57  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 58  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 59  *                   -XX:+DeoptimizeNMethodBarriersALot
 60  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 61  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 62  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 63  *                   compiler.valhalla.inlinetypes.TestMismatchHandling
 64  */
 65 
 66 // ##################################### WARNING ######################################
 67 // Use below script to re-generate TestMismatchHandling.jcod, don't modify it manually.
 68 // Be careful when changing anything (even the order) in this test and related files.
 69 // ##################################### WARNING ######################################
 70 
 71 /*
 72   #!/bin/bash
 73   export PATH=/oracle/valhalla/build/fastdebug/jdk/bin/:$PATH
 74   ASMTOOLS=/oracle/valhalla/open/test/lib
 75 
 76   # With preload attribute
 77   javac --enable-preview --source 26 TestMismatchHandlingGenerator.java
 78   java -cp $ASMTOOLS org.openjdk.asmtools.Main jdec MyValue1Mismatch.class MyValue2Mismatch.class MyValue3Mismatch.class MyValue4Mismatch.class MyValue5Mismatch.class MyValue6Mismatch.class MyValue7Mismatch.class Verifiable.class B.class I3.class I4.class E.class G.class J.class K.class L.class P.class Q.class R.class S.class TestMismatchHandlingHelper.class > TestMismatchHandling.jcod
 79 
 80   # Without preload attribute
 81   sed -i 's/value class MyValue/class MyValue/g' TestMismatchHandlingGenerator.java
 82   javac TestMismatchHandlingGenerator.java
 83   java -cp $ASMTOOLS org.openjdk.asmtools.Main jdec A.class C.class I1.class I2.class D.class F.class H.class I5.class M.class N.class O.class I6.class P.class >> TestMismatchHandling.jcod
 84 
 85   sed -i 's/class MyValue/value class MyValue/g' TestMismatchHandlingGenerator.java
 86 */
 87 
 88 package compiler.valhalla.inlinetypes;
 89 
 90 import java.lang.reflect.Method;
 91 import java.util.ArrayList;
 92 import java.util.Collections;
 93 
 94 import jdk.test.lib.Utils;
 95 import jdk.test.whitebox.WhiteBox;
 96 
 97 public class TestMismatchHandling {
 98     public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
 99 
100     public static void main(String[] args) throws Exception {
101         M m = new M();
102         // Make sure M::method is C1 compiled once with unloaded MyValue4 and not re-compiled
103         for (int i = 0; i < 1000; ++i) {
104             TestMismatchHandlingHelper.test4(m, true);
105         }
106         Method disable = M.class.getDeclaredMethod("method", boolean.class);
107         WHITE_BOX.makeMethodNotCompilable(disable, 1, false);
108         WHITE_BOX.makeMethodNotCompilable(disable, 2, false);
109         WHITE_BOX.makeMethodNotCompilable(disable, 3, false);
110         WHITE_BOX.makeMethodNotCompilable(disable, 4, false);
111 
112         // Sometimes, exclude some methods from compilation with C2 to stress test the calling convention
113         // WARNING: This triggers class loading of argument/return types of all methods!
114         if (Utils.getRandomInstance().nextBoolean()) {
115             ArrayList<Method> methods = new ArrayList<Method>();
116             Collections.addAll(methods, TestMismatchHandlingHelper.class.getDeclaredMethods());
117             Collections.addAll(methods, A.class.getDeclaredMethods());
118             Collections.addAll(methods, B.class.getDeclaredMethods());
119             Collections.addAll(methods, C.class.getDeclaredMethods());
120             Collections.addAll(methods, E.class.getDeclaredMethods());
121             Collections.addAll(methods, F.class.getDeclaredMethods());
122             Collections.addAll(methods, G.class.getDeclaredMethods());
123             Collections.addAll(methods, H.class.getDeclaredMethods());
124             Collections.addAll(methods, J.class.getDeclaredMethods());
125             Collections.addAll(methods, K.class.getDeclaredMethods());
126             Collections.addAll(methods, L.class.getDeclaredMethods());
127             // Don't do this because it would load MyValue5
128             // Collections.addAll(methods, N.class.getDeclaredMethods());
129             System.out.println("Excluding methods from C2 compilation:");
130             for (Method method : methods) {
131                 if (Utils.getRandomInstance().nextBoolean()) {
132                     System.out.println(method);
133                     WHITE_BOX.makeMethodNotCompilable(method, 4, false);
134                 }
135             }
136         }
137 
138         A a = new A();
139         B b = new B();
140         C c = new C();
141         D d = new D();
142         E e = new E();
143         H h = new H();
144         J j = new J();
145         K k = new K();
146         N n = new N();
147         O o = new O();
148         P p = new P();
149         Q q = new Q();
150         R r = new R();
151 
152         // Warmup
153         for (int i = 0; i < 50_000; ++i) {
154             TestMismatchHandlingHelper.test1(a, a, a, b, c, b, b, c);
155             TestMismatchHandlingHelper.test1(b, a, a, b, c, b, b, c);
156             TestMismatchHandlingHelper.test1(c, b, a, b, c, c, b, c);
157             TestMismatchHandlingHelper.test2(d, d, d, d, d, d,  d, d, d, d, d, d,  e, e, e, e, e, e,  e, e, e, e, e, e,  d, e);
158             TestMismatchHandlingHelper.test2(d, d, d, d, d, d,  d, d, d, d, d, d,  e, e, e, e, e, e,  e, e, e, e, e, e,  d, e);
159             TestMismatchHandlingHelper.test3(h, h, h,  j, k, j, k, j,  h, k);
160             TestMismatchHandlingHelper.test3(h, h, h,  j, k, j, k, k,  h, k);
161             TestMismatchHandlingHelper.test4(m, true);
162             TestMismatchHandlingHelper.test5(n, true);
163             TestMismatchHandlingHelper.test7(o, true);
164             TestMismatchHandlingHelper.test8(p, p, p,  q, r, q, r, q,  p, r);
165             TestMismatchHandlingHelper.test8(p, p, p,  q, r, q, r, r,  p, r);
166         }
167 
168         // Only load these now
169         F f = new F();
170         G g = new G();
171         L l = new L();
172         S s = new S();
173 
174         for (int i = 0; i < 50_000; ++i) {
175             TestMismatchHandlingHelper.test1(a, a, a, b, c, b, b, c);
176             TestMismatchHandlingHelper.test1(b, a, a, b, c, b, b, c);
177             TestMismatchHandlingHelper.test1(c, b, a, b, c, c, b, c);
178             TestMismatchHandlingHelper.test2(d, f, g, d, f, d,  d, f, g, d, f, d,  e, f, g, e, f, g,  e, f, g, e, f, g,  d, e);
179             TestMismatchHandlingHelper.test2(d, f, g, d, f, f,  d, f, g, d, f, f,  e, f, g, e, f, f,  e, f, g, e, f, f,  d, e);
180             TestMismatchHandlingHelper.test2(d, f, g, f, g, g,  d, f, g, f, g, g,  e, f, g, f, g, g,  e, f, g, f, g, g,  d, e);
181             TestMismatchHandlingHelper.test3(h, l, h,  j, k, j, k, j,  h, k);
182             TestMismatchHandlingHelper.test3(h, l, h,  j, k, k, k, k,  h, k);
183             TestMismatchHandlingHelper.test3(h, l, l,  j, k, k, l, l,  h, l);
184             TestMismatchHandlingHelper.test4(m, false);
185             TestMismatchHandlingHelper.test5(n, false);
186             TestMismatchHandlingHelper.test6(f, g, l);
187             TestMismatchHandlingHelper.test7TriggerCalleeCompilation(o);
188             TestMismatchHandlingHelper.test8(p, s, p,  q, r, q, r, q,  p, r);
189             TestMismatchHandlingHelper.test8(p, s, p,  q, r, r, r, r,  p, r);
190             TestMismatchHandlingHelper.test8(p, s, s,  q, r, r, s, s,  p, s);
191         }
192         TestMismatchHandlingHelper.test7(o, false).verify();
193 
194         switch (Utils.getRandomInstance().nextInt() % 3) {
195         case 0:
196             TestMismatchHandlingHelper.test2(d, d, d, d, d, d,  d, d, d, d, d, d,  e, e, e, e, e, e,  e, e, e, e, e, e,  d, e);
197             TestMismatchHandlingHelper.test3(l, h, l,  k, l, l, j, j,  h, l);
198             TestMismatchHandlingHelper.test8(s, p, s,  r, s, s, q, q,  p, s);
199             break;
200         case 1:
201             TestMismatchHandlingHelper.test2(f, f, f, f, f, f,  f, f, f, f, f, f,  f, f, f, f, f, f,  f, f, f, f, f, f,  d, e);
202             TestMismatchHandlingHelper.test3(l, h, l,  l, j, j, k, l,  h, l);
203             TestMismatchHandlingHelper.test8(s, p, s,  s, q, q, r, s,  p, s);
204             break;
205         case 2:
206             TestMismatchHandlingHelper.test2(g, g, g, g, g, g,  g, g, g, g, g, g,  g, g, g, g, g, g,  g, g, g, g, g, g,  d, e);
207             TestMismatchHandlingHelper.test3(l, h, l,  j, k, k, l, j,  h, l);
208             TestMismatchHandlingHelper.test8(s, p, s,  q, r, r, s, q,  p, s);
209             break;
210         }
211     }
212 }