1 /* 2 * Copyright (c) 2011, 2018, 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 package org.graalvm.compiler.replacements.test; 26 27 import java.util.HashMap; 28 29 import org.junit.Assert; 30 import org.junit.Test; 31 32 import org.graalvm.compiler.core.test.GraalCompilerTest; 33 34 /** 35 * Tests the implementation of {@code NEW}. 36 */ 37 public class NewInstanceTest extends GraalCompilerTest { 38 39 @Override assertDeepEquals(Object expected, Object actual)40 protected void assertDeepEquals(Object expected, Object actual) { 41 Assert.assertTrue(expected != null); 42 Assert.assertTrue(actual != null); 43 super.assertDeepEquals(expected.getClass(), actual.getClass()); 44 45 if (expected instanceof Object[]) { 46 Assert.assertTrue(actual instanceof Object[]); 47 Object[] eArr = (Object[]) expected; 48 Object[] aArr = (Object[]) actual; 49 Assert.assertTrue(eArr.length == aArr.length); 50 for (int i = 0; i < eArr.length; i++) { 51 assertDeepEquals(eArr[i], aArr[i]); 52 } 53 } else if (expected.getClass() != Object.class) { 54 try { 55 expected.getClass().getDeclaredMethod("equals", Object.class); 56 super.assertDeepEquals(expected, actual); 57 } catch (Exception e) { 58 } 59 } 60 } 61 62 @Test test1()63 public void test1() { 64 test("newObject"); 65 } 66 67 @Test test2()68 public void test2() { 69 test("newObjectTwice"); 70 } 71 newObject()72 public static Object newObject() { 73 return new Object(); 74 } 75 76 @Test test3()77 public void test3() { 78 test("newObjectLoop", 100); 79 } 80 81 @Test test4()82 public void test4() { 83 test("newBigObject"); 84 } 85 86 @Test test5()87 public void test5() { 88 test("newSomeObject"); 89 } 90 91 @Test test6()92 public void test6() { 93 test("newEmptyString"); 94 } 95 96 @Test test7()97 public void test7() { 98 test("newString", "value"); 99 } 100 101 @Test test8()102 public void test8() { 103 test("newHashMap", 31); 104 } 105 106 @Test test9()107 public void test9() { 108 test("newRegression", true); 109 } 110 newObjectTwice()111 public static Object[] newObjectTwice() { 112 Object[] res = {new Object(), new Object()}; 113 return res; 114 } 115 newObjectLoop(int n)116 public static Object[] newObjectLoop(int n) { 117 Object[] res = new Object[n]; 118 for (int i = 0; i < n; i++) { 119 res[i] = new Object(); 120 } 121 return res; 122 } 123 newBigObject()124 public static BigObject newBigObject() { 125 return new BigObject(); 126 } 127 newSomeObject()128 public static SomeObject newSomeObject() { 129 return new SomeObject(); 130 } 131 newEmptyString()132 public static String newEmptyString() { 133 return new String(); 134 } 135 newString(String value)136 public static String newString(String value) { 137 return new String(value); 138 } 139 newHashMap(int initialCapacity)140 public static HashMap<?, ?> newHashMap(int initialCapacity) { 141 return new HashMap<>(initialCapacity); 142 } 143 144 static class SomeObject { 145 146 String name = "o1"; 147 HashMap<String, Object> map = new HashMap<>(); 148 SomeObject()149 SomeObject() { 150 map.put(name, this.getClass()); 151 } 152 153 @Override equals(Object obj)154 public boolean equals(Object obj) { 155 if (obj instanceof SomeObject) { 156 SomeObject so = (SomeObject) obj; 157 return so.name.equals(name) && so.map.equals(map); 158 } 159 return false; 160 } 161 162 @Override hashCode()163 public int hashCode() { 164 return name.hashCode(); 165 } 166 } 167 168 static class BigObject { 169 170 Object f01; 171 Object f02; 172 Object f03; 173 Object f04; 174 Object f05; 175 Object f06; 176 Object f07; 177 Object f08; 178 Object f09; 179 Object f10; 180 Object f12; 181 Object f13; 182 Object f14; 183 Object f15; 184 Object f16; 185 Object f17; 186 Object f18; 187 Object f19; 188 Object f20; 189 Object f21; 190 Object f22; 191 Object f23; 192 Object f24; 193 Object f25; 194 Object f26; 195 Object f27; 196 Object f28; 197 Object f29; 198 Object f30; 199 Object f31; 200 Object f32; 201 Object f33; 202 Object f34; 203 Object f35; 204 Object f36; 205 Object f37; 206 Object f38; 207 Object f39; 208 Object f40; 209 Object f41; 210 Object f42; 211 Object f43; 212 Object f44; 213 Object f45; 214 } 215 216 /** 217 * Tests that an earlier bug does not occur. The issue was that the loading of the TLAB 'top' 218 * and 'end' values was being GVN'ed from each branch of the 'if' statement. This meant that the 219 * allocated B object in the true branch overwrote the allocated array. The cause is that 220 * RegisterNode was a floating node and the reads from it were UnsafeLoads which are also 221 * floating. The fix was to make RegisterNode a fixed node (which it should have been in the 222 * first place). 223 */ newRegression(boolean condition)224 public static Object newRegression(boolean condition) { 225 Object result; 226 if (condition) { 227 Object[] arr = {0, 1, 2, 3, 4, 5}; 228 result = new B(); 229 for (int i = 0; i < arr.length; ++i) { 230 // If the bug exists, the values of arr will now be deadbeef values 231 // and the virtual dispatch will cause a segfault. This can result in 232 // either a VM crash or a spurious NullPointerException. 233 if (arr[i].equals(Integer.valueOf(i))) { 234 return false; 235 } 236 } 237 } else { 238 result = new B(); 239 } 240 return result; 241 } 242 243 static class B { 244 245 long f1 = 0xdeadbeefdeadbe01L; 246 long f2 = 0xdeadbeefdeadbe02L; 247 long f3 = 0xdeadbeefdeadbe03L; 248 long f4 = 0xdeadbeefdeadbe04L; 249 long f5 = 0xdeadbeefdeadbe05L; 250 } 251 } 252