1 /* 2 * Copyright (c) 2020, 2021, 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 package compiler.valhalla.inlinetypes; 25 26 import compiler.lib.ir_framework.CompLevel; 27 import compiler.lib.ir_framework.Run; 28 import compiler.lib.ir_framework.Scenario; 29 import compiler.lib.ir_framework.Test; 30 import jdk.test.lib.Asserts; 31 32 33 /* 34 * @test 35 * @key randomness 36 * @summary Verify that chains of getfields on flattened fields are correctly optimized 37 * @library /test/lib / 38 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 39 * @compile GetfieldChains.jcod 40 * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestGetfieldChains 41 */ 42 43 public class TestGetfieldChains { 44 45 public static void main(String[] args) { 46 47 final Scenario[] scenarios = { 48 new Scenario(0, 49 // C1 only 50 "-XX:TieredStopAtLevel=1", 51 "-XX:+TieredCompilation"), 52 new Scenario(1, 53 // C2 only. (Make sure the tests are correctly written) 54 "-XX:TieredStopAtLevel=4", 55 "-XX:-TieredCompilation", 56 "-XX:-OmitStackTraceInFastThrow"), 57 new Scenario(2, 58 // interpreter only 59 "-Xint"), 60 new Scenario(3, 61 // Xcomp Only C1. 62 "-XX:TieredStopAtLevel=1", 63 "-XX:+TieredCompilation", 64 "-Xcomp"), 65 new Scenario(4, 66 // Xcomp Only C2. 67 "-XX:TieredStopAtLevel=4", 68 "-XX:-TieredCompilation", 69 "-XX:-OmitStackTraceInFastThrow", 70 "-Xcomp") 71 }; 72 73 InlineTypes.getFramework() 74 .addScenarios(scenarios) 75 .start(); 76 } 77 78 79 // Simple chain of getfields ending with primitive field 80 @Test(compLevel = CompLevel.C1_SIMPLE) 81 public int test1() { 82 return NamedRectangle.getP1X(new NamedRectangle()); 83 } 84 85 @Run(test = "test1") 86 public void test1_verifier() { 87 int res = test1(); 88 Asserts.assertEQ(res, 4); 89 } 90 91 // Simple chain of getfields ending with a flattened field 92 @Test(compLevel = CompLevel.C1_SIMPLE) 93 public Point test2() { 94 return NamedRectangle.getP1(new NamedRectangle()); 95 } 96 97 @Run(test = "test2") 98 public void test2_verifier() { 99 Point p = test2(); 100 Asserts.assertEQ(p.x, 4); 101 Asserts.assertEQ(p.y, 7); 102 } 103 104 // Chain of getfields but the initial receiver is null 105 @Test(compLevel = CompLevel.C1_SIMPLE) 106 public NullPointerException test3() { 107 NullPointerException npe = null; 108 try { 109 NamedRectangle.getP1X(null); 110 } catch(NullPointerException e) { 111 npe = e; 112 } 113 return npe; 114 } 115 116 @Run(test = "test3") 117 public void test3_verifier() { 118 NullPointerException npe = test3(); 119 Asserts.assertNE(npe, null); 120 StackTraceElement st = npe.getStackTrace()[0]; 121 Asserts.assertEQ(st.getMethodName(), "getP1X"); 122 Asserts.assertEQ(st.getLineNumber(), 31); // line number depends on file NamedRectangle.java 123 } 124 125 // Chain of getfields but one getfield in the middle of the chain trigger an illegal access 126 @Test(compLevel = CompLevel.C1_SIMPLE) 127 public IllegalAccessError test4() { 128 IllegalAccessError iae = null; 129 try { 130 int i = NamedRectangleP.getP1X(new NamedRectangleP()); 131 } catch(IllegalAccessError e) { 132 iae = e; 133 } 134 return iae; 135 } 136 137 @Run(test = "test4") 138 public void test4_verifier() { 139 IllegalAccessError iae = test4(); 140 Asserts.assertNE(iae, null); 141 StackTraceElement st = iae.getStackTrace()[0]; 142 Asserts.assertEQ(st.getMethodName(), "getP1X"); 143 Asserts.assertEQ(st.getLineNumber(), 31); // line number depends on jcod file generated from NamedRectangle.java 144 Asserts.assertTrue(iae.getMessage().contains("class compiler.valhalla.inlinetypes.NamedRectangleP tried to access private field compiler.valhalla.inlinetypes.RectangleP.p1")); 145 } 146 147 // Chain of getfields but the last getfield trigger a NoSuchFieldError 148 @Test(compLevel = CompLevel.C1_SIMPLE) 149 public NoSuchFieldError test5() { 150 NoSuchFieldError nsfe = null; 151 try { 152 int i = NamedRectangleN.getP1X(new NamedRectangleN()); 153 } catch(NoSuchFieldError e) { 154 nsfe = e; 155 } 156 return nsfe; 157 } 158 159 @Run(test = "test5") 160 public void test5_verifier() { 161 NoSuchFieldError nsfe = test5(); 162 Asserts.assertNE(nsfe, null); 163 StackTraceElement st = nsfe.getStackTrace()[0]; 164 Asserts.assertEQ(st.getMethodName(), "getP1X"); 165 Asserts.assertEQ(st.getLineNumber(), 31); // line number depends on jcod file generated from NamedRectangle.java 166 Asserts.assertEQ(nsfe.getMessage(), "x"); 167 } 168 169 static primitive class EmptyType { } 170 static primitive class EmptyContainer { 171 int i = 0; 172 EmptyType et = new EmptyType(); 173 } 174 static primitive class Container { 175 EmptyContainer container0 = new EmptyContainer(); 176 EmptyContainer container1 = new EmptyContainer(); 177 } 178 179 @Test(compLevel = CompLevel.C1_SIMPLE) 180 public EmptyType test6() { 181 Container c = new Container(); 182 return c.container1.et; 183 } 184 185 @Run(test = "test6") 186 public void test6_verifier() { 187 EmptyType et = test6(); 188 Asserts.assertEQ(et, EmptyType.default); 189 } 190 191 @Test(compLevel = CompLevel.C1_SIMPLE) 192 public EmptyType test7() { 193 Container[] ca = new Container[10]; 194 return ca[3].container0.et; 195 } 196 197 @Run(test = "test7") 198 public void test7_verifier() { 199 EmptyType et = test7(); 200 Asserts.assertEQ(et, EmptyType.default); 201 } 202 }