1 /*
   2  * Copyright (c) 2017, 2019, Red Hat, Inc. 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 8182997 8214898
  27  * @library /test/lib
  28  * @summary Test the handling of Arrays of unloaded value classes.
  29  * @compile -XDallowWithFieldOperator TestUnloadedValueTypeArray.java
  30  * @run main/othervm -XX:+EnableValhalla -Xcomp
  31  *        -XX:CompileCommand=compileonly,TestUnloadedValueTypeArray::test1
  32  *        -XX:CompileCommand=compileonly,TestUnloadedValueTypeArray::test2
  33  *        -XX:CompileCommand=compileonly,TestUnloadedValueTypeArray::test3
  34  *        -XX:CompileCommand=compileonly,TestUnloadedValueTypeArray::test4
  35  *        -XX:CompileCommand=compileonly,TestUnloadedValueTypeArray::test5
  36  *        -XX:CompileCommand=compileonly,TestUnloadedValueTypeArray::test6
  37  *      TestUnloadedValueTypeArray
  38  */
  39 
  40 import jdk.test.lib.Asserts;
  41 
  42 value final class MyValue {
  43     final int foo;
  44 
  45     private MyValue() {
  46         foo = 0x42;
  47     }
  48 }
  49 
  50 value final class MyValue2 {
  51     final int foo;
  52 
  53     private MyValue2() {
  54         foo = 0x42;
  55     }
  56     static MyValue2 make(int n) {
  57         return __WithField(MyValue2.default.foo, n);
  58     }
  59 }
  60 
  61 value final class MyValue3 {
  62     final int foo;
  63 
  64     private MyValue3() {
  65         foo = 0x42;
  66     }
  67     static MyValue3 make(int n) {
  68         return __WithField(MyValue3.default.foo, n);
  69     }
  70 }
  71 
  72 value final class MyValue4 {
  73     final int foo;
  74 
  75     private MyValue4() {
  76         foo = 0x53;
  77     }
  78     static MyValue4 make(int n) {
  79         return __WithField(MyValue4.default.foo, n);
  80     }
  81 }
  82 
  83 value final class MyValue5 {
  84     final int foo;
  85 
  86     private MyValue5() {
  87         foo = 0x53;
  88     }
  89     static MyValue5 make(int n) {
  90         return __WithField(MyValue5.default.foo, n);
  91     }
  92 }
  93 
  94 value final class MyValue6 {
  95     final int foo = 0;
  96 
  97     static MyValue6 make(int n) {
  98         return __WithField(MyValue6.default.foo, n);
  99     }
 100     static MyValue6 make2(MyValue6 v, MyValue6[] dummy) {
 101         return __WithField(v.foo, v.foo+1);
 102     }
 103 }
 104 
 105 public class TestUnloadedValueTypeArray {
 106 
 107     static MyValue[] target() {
 108         return new MyValue[10];
 109     }
 110 
 111     static void test1() {
 112         target();
 113     }
 114 
 115     static int test2(MyValue2[] arr) {
 116         if (arr != null) {
 117             return arr[1].foo;
 118         } else {
 119             return 1234;
 120         }
 121     }
 122 
 123     static void test2_verifier() {
 124         int n = 50000;
 125 
 126         int m = 9999;
 127         for (int i=0; i<n; i++) {
 128             m = test2(null);
 129         }
 130         Asserts.assertEQ(m, 1234);
 131 
 132         MyValue2[] arr = new MyValue2[2];
 133         arr[1] = MyValue2.make(5678);
 134         m = 9999;
 135         for (int i=0; i<n; i++) {
 136             m = test2(arr);
 137         }
 138         Asserts.assertEQ(m, 5678);
 139     }
 140 
 141     static void test3(MyValue3[] arr) {
 142         if (arr != null) {
 143             arr[1] = MyValue3.make(2345);
 144         }
 145     }
 146 
 147     static void test3_verifier() {
 148         int n = 50000;
 149 
 150         for (int i=0; i<n; i++) {
 151             test3(null);
 152         }
 153 
 154         MyValue3[] arr = new MyValue3[2];
 155         for (int i=0; i<n; i++) {
 156             test3(arr);
 157         }
 158         Asserts.assertEQ(arr[1].foo, 2345);
 159     }
 160 
 161     static MyValue4[] test4(boolean b) {
 162         // range check elimination
 163         if (b) {
 164             MyValue4[] arr = new MyValue4[10];
 165             arr[1] = MyValue4.make(2345);
 166             return arr;
 167         } else {
 168             return null;
 169         }
 170     }
 171 
 172     static void test4_verifier() {
 173         int n = 50000;
 174 
 175         for (int i=0; i<n; i++) {
 176             test4(false);
 177         }
 178 
 179         MyValue4[] arr = null;
 180         for (int i=0; i<n; i++) {
 181           arr = test4(true);
 182         }
 183         Asserts.assertEQ(arr[1].foo, 2345);
 184     }
 185 
 186     static Object[] test5(int n) {
 187         if (n == 0) {
 188             return null;
 189         } else if (n == 1) {
 190             MyValue5[] arr = new MyValue5[10];
 191             arr[1] = MyValue5.make(12345);
 192             return arr;
 193         } else {
 194             MyValue5.box[] arr = new MyValue5.box[10];
 195             arr[1] = MyValue5.make(22345);
 196             return arr;
 197         }
 198     }
 199 
 200     static void test5_verifier() {
 201         int n = 50000;
 202 
 203         for (int i=0; i<n; i++) {
 204             test5(0);
 205         }
 206 
 207         {
 208             MyValue5[] arr = null;
 209             for (int i=0; i<n; i++) {
 210                 arr = (MyValue5[])test5(1);
 211             }
 212             Asserts.assertEQ(arr[1].foo, 12345);
 213         }
 214         {
 215             MyValue5.box[] arr = null;
 216             for (int i=0; i<n; i++) {
 217                 arr = (MyValue5.box[])test5(2);
 218             }
 219             Asserts.assertEQ(arr[1].foo, 22345);
 220         }
 221     }
 222 
 223     static Object test6() {
 224         return MyValue6.make2(MyValue6.make(123), null);
 225     }
 226 
 227     static void test6_verifier() {
 228         Object n = test6();
 229         Asserts.assertEQ(n.toString(), "[MyValue6 foo=124]");
 230     }
 231 
 232     static public void main(String[] args) {
 233         test1();
 234         test2_verifier();
 235         test3_verifier();
 236         test4_verifier();
 237         test5_verifier();
 238         test6_verifier();
 239     }
 240 }