1 /*
  2  * Copyright (c) 2023, 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 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,TestMismatchHandling::test*
 37  *                   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  *                   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  *                   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  *                   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  *                   TestMismatchHandling
 57  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 58  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 59  *                   -XX:+DeoptimizeNMethodBarriersALot
 60  *                   TestMismatchHandling
 61  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch
 62  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 63  *                   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 22 TestMismatchHandlingGenerator.java
 78   java -cp $ASMTOOLS org.openjdk.asmtools.Main jdec MyValue1.class MyValue2.class MyValue3.class MyValue4.class MyValue5.class MyValue6.class MyValue7.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 import java.lang.reflect.Method;
 89 import java.util.ArrayList;
 90 import java.util.Collections;
 91 
 92 import jdk.test.lib.Utils;
 93 import jdk.test.whitebox.WhiteBox;
 94 
 95 public class TestMismatchHandling {
 96     public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
 97 
 98     public static void main(String[] args) throws Exception {
 99         M m = new M();
100         // Make sure M::method is C1 compiled once with unloaded MyValue4 and not re-compiled
101         for (int i = 0; i < 1000; ++i) {
102             TestMismatchHandlingHelper.test4(m, true);
103         }
104         Method disable = M.class.getDeclaredMethod("method", boolean.class);
105         WHITE_BOX.makeMethodNotCompilable(disable, 1, false);
106         WHITE_BOX.makeMethodNotCompilable(disable, 2, false);
107         WHITE_BOX.makeMethodNotCompilable(disable, 3, false);
108         WHITE_BOX.makeMethodNotCompilable(disable, 4, false);
109 
110         // Sometimes, exclude some methods from compilation with C2 to stress test the calling convention
111         // WARNING: This triggers class loading of argument/return types of all methods!
112         if (Utils.getRandomInstance().nextBoolean()) {
113             ArrayList<Method> methods = new ArrayList<Method>();
114             Collections.addAll(methods, TestMismatchHandlingHelper.class.getDeclaredMethods());
115             Collections.addAll(methods, A.class.getDeclaredMethods());
116             Collections.addAll(methods, B.class.getDeclaredMethods());
117             Collections.addAll(methods, C.class.getDeclaredMethods());
118             Collections.addAll(methods, E.class.getDeclaredMethods());
119             Collections.addAll(methods, F.class.getDeclaredMethods());
120             Collections.addAll(methods, G.class.getDeclaredMethods());
121             Collections.addAll(methods, H.class.getDeclaredMethods());
122             Collections.addAll(methods, J.class.getDeclaredMethods());
123             Collections.addAll(methods, K.class.getDeclaredMethods());
124             Collections.addAll(methods, L.class.getDeclaredMethods());
125             // Don't do this because it would load MyValue5
126             // Collections.addAll(methods, N.class.getDeclaredMethods());
127             System.out.println("Excluding methods from C2 compilation:");
128             for (Method method : methods) {
129                 if (Utils.getRandomInstance().nextBoolean()) {
130                     System.out.println(method);
131                     WHITE_BOX.makeMethodNotCompilable(method, 4, false);
132                 }
133             }
134         }
135 
136         A a = new A();
137         B b = new B();
138         C c = new C();
139         D d = new D();
140         E e = new E();
141         H h = new H();
142         J j = new J();
143         K k = new K();
144         N n = new N();
145         O o = new O();
146         P p = new P();
147         Q q = new Q();
148         R r = new R();
149 
150         // Warmup
151         for (int i = 0; i < 50_000; ++i) {
152             TestMismatchHandlingHelper.test1(a, a, a, b, c, b, b, c);
153             TestMismatchHandlingHelper.test1(b, a, a, b, c, b, b, c);
154             TestMismatchHandlingHelper.test1(c, b, a, b, c, c, b, c);
155             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);
156             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);
157             TestMismatchHandlingHelper.test3(h, h, h,  j, k, j, k, j,  h, k);
158             TestMismatchHandlingHelper.test3(h, h, h,  j, k, j, k, k,  h, k);
159             TestMismatchHandlingHelper.test4(m, true);
160             TestMismatchHandlingHelper.test5(n, true);
161             TestMismatchHandlingHelper.test7(o, true);
162             TestMismatchHandlingHelper.test8(p, p, p,  q, r, q, r, q,  p, r);
163             TestMismatchHandlingHelper.test8(p, p, p,  q, r, q, r, r,  p, r);
164         }
165 
166         // Only load these now
167         F f = new F();
168         G g = new G();
169         L l = new L();
170         S s = new S();
171 
172         for (int i = 0; i < 50_000; ++i) {
173             TestMismatchHandlingHelper.test1(a, a, a, b, c, b, b, c);
174             TestMismatchHandlingHelper.test1(b, a, a, b, c, b, b, c);
175             TestMismatchHandlingHelper.test1(c, b, a, b, c, c, b, c);
176             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);
177             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);
178             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);
179             TestMismatchHandlingHelper.test3(h, l, h,  j, k, j, k, j,  h, k);
180             TestMismatchHandlingHelper.test3(h, l, h,  j, k, k, k, k,  h, k);
181             TestMismatchHandlingHelper.test3(h, l, l,  j, k, k, l, l,  h, l);
182             TestMismatchHandlingHelper.test4(m, false);
183             TestMismatchHandlingHelper.test5(n, false);
184             TestMismatchHandlingHelper.test6(f, g, l);
185             TestMismatchHandlingHelper.test7TriggerCalleeCompilation(o);
186             TestMismatchHandlingHelper.test8(p, s, p,  q, r, q, r, q,  p, r);
187             TestMismatchHandlingHelper.test8(p, s, p,  q, r, r, r, r,  p, r);
188             TestMismatchHandlingHelper.test8(p, s, s,  q, r, r, s, s,  p, s);
189         }
190         TestMismatchHandlingHelper.test7(o, false).verify();
191 
192         switch (Utils.getRandomInstance().nextInt() % 3) {
193         case 0:
194             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);
195             TestMismatchHandlingHelper.test3(l, h, l,  k, l, l, j, j,  h, l);
196             TestMismatchHandlingHelper.test8(s, p, s,  r, s, s, q, q,  p, s);
197             break;
198         case 1:
199             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);
200             TestMismatchHandlingHelper.test3(l, h, l,  l, j, j, k, l,  h, l);
201             TestMismatchHandlingHelper.test8(s, p, s,  s, q, q, r, s,  p, s);
202             break;
203         case 2:
204             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);
205             TestMismatchHandlingHelper.test3(l, h, l,  j, k, k, l, j,  h, l);
206             TestMismatchHandlingHelper.test8(s, p, s,  q, r, r, s, q,  p, s);
207             break;
208         }
209     }
210 }