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 // TODO 8325106 Investigate why this suddenly started to throw java.lang.OutOfMemoryError without -Xmx200m
 25 // and -XX:-UseCompressedOops -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=0 -Xmx20m -Xmn1m -XX:G1HeapRegionSize=1m -XX:-ReduceInitialCardMarks
 26 
 27 /**
 28  * @test
 29  * @summary Verify that certain array accesses do not trigger deoptimization.
 30  * @library /test/lib
 31  * @enablePreview
 32  * @modules java.base/jdk.internal.value
 33  *          java.base/jdk.internal.vm.annotation
 34  * @run main/othervm -Xmx200m TestArrayAccessDeopt
 35  */
 36 
 37 import java.io.File;
 38 import jdk.test.lib.Asserts;
 39 import jdk.test.lib.process.OutputAnalyzer;
 40 import jdk.test.lib.process.ProcessTools;
 41 
 42 import jdk.internal.value.ValueClass;
 43 import jdk.internal.vm.annotation.ImplicitlyConstructible;
 44 import jdk.internal.vm.annotation.LooselyConsistentValue;
 45 import jdk.internal.vm.annotation.NullRestricted;
 46 
 47 @ImplicitlyConstructible
 48 @LooselyConsistentValue
 49 value class MyValue1 {
 50     public int x = 0;
 51 }
 52 
 53 public class TestArrayAccessDeopt {
 54 
 55     public static void test1(Object[] va, Object vt) {
 56         va[0] = vt;
 57     }
 58 
 59     public static void test2(Object[] va, MyValue1 vt) {
 60         va[0] = vt;
 61     }
 62 
 63     public static void test3(MyValue1[] va, Object vt) {
 64         va[0] = (MyValue1)vt;
 65     }
 66 
 67     public static void test4(MyValue1[] va, MyValue1 vt) {
 68         va[0] = vt;
 69     }
 70 
 71     public static void test5(Object[] va, MyValue1 vt) {
 72         va[0] = vt;
 73     }
 74 
 75     public static void test6(MyValue1[] va, Object vt) {
 76         va[0] = (MyValue1)vt;
 77     }
 78 
 79     public static void test7(MyValue1[] va, MyValue1 vt) {
 80         va[0] = vt;
 81     }
 82 
 83     public static void test8(MyValue1[] va, MyValue1 vt) {
 84         va[0] = vt;
 85     }
 86 
 87     public static void test9(MyValue1[] va, MyValue1 vt) {
 88         va[0] = (MyValue1)vt;
 89     }
 90 
 91     public static void test10(Object[] va) {
 92         va[0] = null;
 93     }
 94 
 95     public static void test11(MyValue1[] va) {
 96         va[0] = null;
 97     }
 98 
 99     static public void main(String[] args) throws Exception {
100         if (args.length == 0) {
101             // Run test in new VM instance
102             String[] arg = {"--enable-preview", "--add-exports", "java.base/jdk.internal.vm.annotation=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.value=ALL-UNNAMED",
103                             "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,TestArrayAccessDeopt::test*", "-XX:-UseArrayLoadStoreProfile",
104                             "-XX:+TraceDeoptimization", "-Xbatch", "-XX:-MonomorphicArrayCheck", "-Xmixed", "-XX:+ProfileInterpreter", "TestArrayAccessDeopt", "run"};
105             OutputAnalyzer oa = ProcessTools.executeTestJvm(arg);
106             String output = oa.getOutput();
107             oa.shouldNotContain("Uncommon trap occurred");
108         } else {
109             MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
110             MyValue1[] vaB = new MyValue1[1];
111             MyValue1 vt = new MyValue1();
112             for (int i = 0; i < 10_000; ++i) {
113                 test1(va, vt);
114                 test1(vaB, vt);
115                 test1(vaB, null);
116                 test2(va, vt);
117                 test2(vaB, vt);
118                 test2(vaB, null);
119                 test3(va, vt);
120                 test3(vaB, vt);
121                 test3(vaB, null);
122                 test4(va, vt);
123                 test4(vaB, vt);
124                 test4(vaB, null);
125                 test5(va, vt);
126                 test5(vaB, vt);
127                 test6(va, vt);
128                 try {
129                     test6(va, null);
130                     throw new RuntimeException("NullPointerException expected");
131                 } catch (NullPointerException npe) {
132                     // Expected
133                 }
134                 test7(va, vt);
135                 test8(va, vt);
136                 test8(vaB, vt);
137                 test9(va, vt);
138                 try {
139                     test9(va, null);
140                     throw new RuntimeException("NullPointerException expected");
141                 } catch (NullPointerException npe) {
142                     // Expected
143                 }
144                 test10(vaB);
145                 test11(vaB);
146             }
147         }
148     }
149 }