001/* 002 * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.replacements.test; 024 025import java.util.*; 026 027import org.junit.*; 028 029import com.oracle.graal.nodes.*; 030import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 031import com.oracle.graal.phases.*; 032import com.oracle.graal.phases.common.*; 033import com.oracle.graal.phases.common.inlining.*; 034import com.oracle.graal.phases.tiers.*; 035import com.oracle.graal.replacements.*; 036import com.oracle.graal.replacements.nodes.*; 037import com.oracle.graal.virtual.phases.ea.*; 038 039/** 040 * Tests {@link ArraysSubstitutions}. 041 */ 042public class ArraysSubstitutionsTest extends MethodSubstitutionTest { 043 044 private static final int N = 10; 045 046 @Test 047 public void testEqualsBoolean() { 048 Object[] args1 = new Object[N]; 049 Object[] args2 = new Object[N]; 050 int n = 0; 051 052 // equal arrays 053 for (int i = 0; i < N / 2; i++, n++) { 054 args1[n] = new boolean[i]; 055 args2[n] = new boolean[i]; 056 } 057 058 // non-equal arrays 059 for (int i = 0; i < N / 2; i++, n++) { 060 boolean[] a2 = new boolean[i]; 061 if (i > 0) { 062 a2[i - 1] = true; 063 } 064 args1[n] = new boolean[i]; 065 args2[n] = a2; 066 } 067 Class<?>[] parameterTypes = new Class<?>[]{boolean[].class, boolean[].class}; 068 testSubstitution("arraysEqualsBoolean", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 069 } 070 071 @SuppressWarnings("all") 072 public static boolean arraysEqualsBoolean(boolean[] a, boolean[] b) { 073 return Arrays.equals(a, b); 074 } 075 076 @Test 077 public void testEqualsByte() { 078 Object[] args1 = new Object[N]; 079 Object[] args2 = new Object[N]; 080 int n = 0; 081 082 // equal arrays 083 for (int i = 0; i < N / 2; i++, n++) { 084 args1[n] = new byte[i]; 085 args2[n] = new byte[i]; 086 } 087 088 // non-equal arrays 089 for (int i = 0; i < N / 2; i++, n++) { 090 byte[] a2 = new byte[i]; 091 if (i > 0) { 092 a2[i - 1] = 1; 093 } 094 args1[n] = new byte[i]; 095 args2[n] = a2; 096 } 097 098 Class<?>[] parameterTypes = new Class<?>[]{byte[].class, byte[].class}; 099 testSubstitution("arraysEqualsByte", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 100 } 101 102 @SuppressWarnings("all") 103 public static boolean arraysEqualsByte(byte[] a, byte[] b) { 104 return Arrays.equals(a, b); 105 } 106 107 @Test 108 public void testEqualsChar() { 109 Object[] args1 = new Object[N]; 110 Object[] args2 = new Object[N]; 111 int n = 0; 112 113 // equal arrays 114 for (int i = 0; i < N / 2; i++, n++) { 115 args1[n] = new char[i]; 116 args2[n] = new char[i]; 117 } 118 119 // non-equal arrays 120 for (int i = 0; i < N / 2; i++, n++) { 121 char[] a2 = new char[i]; 122 if (i > 0) { 123 a2[i - 1] = 1; 124 } 125 args1[n] = new char[i]; 126 args2[n] = a2; 127 } 128 129 Class<?>[] parameterTypes = new Class<?>[]{char[].class, char[].class}; 130 testSubstitution("arraysEqualsChar", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 131 } 132 133 @SuppressWarnings("all") 134 public static boolean arraysEqualsChar(char[] a, char[] b) { 135 return Arrays.equals(a, b); 136 } 137 138 @Test 139 public void testEqualsShort() { 140 Object[] args1 = new Object[N]; 141 Object[] args2 = new Object[N]; 142 int n = 0; 143 144 // equal arrays 145 for (int i = 0; i < N / 2; i++, n++) { 146 args1[n] = new short[i]; 147 args2[n] = new short[i]; 148 } 149 150 // non-equal arrays 151 for (int i = 0; i < N / 2; i++, n++) { 152 short[] a2 = new short[i]; 153 if (i > 0) { 154 a2[i - 1] = 1; 155 } 156 args1[n] = new short[i]; 157 args2[n] = a2; 158 } 159 160 Class<?>[] parameterTypes = new Class<?>[]{short[].class, short[].class}; 161 testSubstitution("arraysEqualsShort", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 162 } 163 164 @SuppressWarnings("all") 165 public static boolean arraysEqualsShort(short[] a, short[] b) { 166 return Arrays.equals(a, b); 167 } 168 169 @Test 170 public void testEqualsInt() { 171 Object[] args1 = new Object[N]; 172 Object[] args2 = new Object[N]; 173 int n = 0; 174 175 // equal arrays 176 for (int i = 0; i < N / 2; i++, n++) { 177 args1[n] = new int[i]; 178 args2[n] = new int[i]; 179 } 180 181 // non-equal arrays 182 for (int i = 0; i < N / 2; i++, n++) { 183 int[] a2 = new int[i]; 184 if (i > 0) { 185 a2[i - 1] = 1; 186 } 187 args1[n] = new int[i]; 188 args2[n] = a2; 189 } 190 191 Class<?>[] parameterTypes = new Class<?>[]{int[].class, int[].class}; 192 testSubstitution("arraysEqualsInt", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 193 } 194 195 @SuppressWarnings("all") 196 public static boolean arraysEqualsInt(int[] a, int[] b) { 197 return Arrays.equals(a, b); 198 } 199 200 @Test 201 public void testEqualsLong() { 202 Object[] args1 = new Object[N]; 203 Object[] args2 = new Object[N]; 204 int n = 0; 205 206 // equal arrays 207 for (int i = 0; i < N / 2; i++, n++) { 208 args1[n] = new long[i]; 209 args2[n] = new long[i]; 210 } 211 212 // non-equal arrays 213 for (int i = 0; i < N / 2; i++, n++) { 214 long[] a2 = new long[i]; 215 if (i > 0) { 216 a2[i - 1] = 1; 217 } 218 args1[n] = new long[i]; 219 args2[n] = a2; 220 } 221 222 Class<?>[] parameterTypes = new Class<?>[]{long[].class, long[].class}; 223 testSubstitution("arraysEqualsLong", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 224 } 225 226 @SuppressWarnings("all") 227 public static boolean arraysEqualsLong(long[] a, long[] b) { 228 return Arrays.equals(a, b); 229 } 230 231 @Test 232 public void testEqualsFloat() { 233 Object[] args1 = new Object[N]; 234 Object[] args2 = new Object[N]; 235 int n = 0; 236 237 // equal arrays 238 for (int i = 0; i < N / 2; i++, n++) { 239 args1[n] = new float[i]; 240 args2[n] = new float[i]; 241 } 242 243 // non-equal arrays 244 for (int i = 0; i < N / 2; i++, n++) { 245 float[] a2 = new float[i]; 246 if (i > 0) { 247 a2[i - 1] = 1; 248 } 249 args1[n] = new float[i]; 250 args2[n] = a2; 251 } 252 253 Class<?>[] parameterTypes = new Class<?>[]{float[].class, float[].class}; 254 testSubstitution("arraysEqualsFloat", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 255 } 256 257 @SuppressWarnings("all") 258 public static boolean arraysEqualsFloat(float[] a, float[] b) { 259 return Arrays.equals(a, b); 260 } 261 262 @Test 263 public void testEqualsDouble() { 264 Object[] args1 = new Object[N]; 265 Object[] args2 = new Object[N]; 266 int n = 0; 267 268 // equal arrays 269 for (int i = 0; i < N / 2; i++, n++) { 270 args1[n] = new double[i]; 271 args2[n] = new double[i]; 272 } 273 274 // non-equal arrays 275 for (int i = 0; i < N / 2; i++, n++) { 276 double[] a2 = new double[i]; 277 if (i > 0) { 278 a2[i - 1] = 1; 279 } 280 args1[n] = new double[i]; 281 args2[n] = a2; 282 } 283 284 Class<?>[] parameterTypes = new Class<?>[]{double[].class, double[].class}; 285 testSubstitution("arraysEqualsDouble", ArrayEqualsNode.class, Arrays.class, "equals", parameterTypes, false, args1, args2); 286 } 287 288 @SuppressWarnings("all") 289 public static boolean arraysEqualsDouble(double[] a, double[] b) { 290 return Arrays.equals(a, b); 291 } 292 293 @Test 294 public void testEqualsNodeGVN() { 295 test("testEqualsNodeGVNSnippet", true); 296 } 297 298 public static int[] intArrayCompare = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; 299 public static int[] intArray; 300 301 public static boolean testEqualsNodeGVNSnippet(boolean b) { 302 int[] newIntArray = new int[]{0, 2, 3, 4, 5, 6, 7, 8, 9}; 303 intArray = newIntArray; 304 305 if (b) { 306 newIntArray[0] = 1; 307 return Arrays.equals(newIntArray, intArrayCompare); 308 } else { 309 newIntArray[0] = 1; 310 return Arrays.equals(newIntArray, intArrayCompare); 311 } 312 } 313 314 @Test 315 public void testConstants() { 316 testGraph("testConstantsSnippet"); 317 } 318 319 public static final int[] constantArray1 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; 320 public static final int[] constantArray2 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; 321 322 public static boolean testConstantsSnippet() { 323 constantArray2[0] = 10; 324 try { 325 return Arrays.equals(constantArray1, constantArray2); 326 } finally { 327 constantArray2[0] = 1; 328 } 329 } 330 331 @Test 332 public void testCanonicalLength() { 333 StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO); 334 HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); 335 new InliningPhase(new CanonicalizerPhase()).apply(graph, context); 336 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 337 338 Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0); 339 } 340 341 public static final int[] constantArray3 = new int[]{1, 2, 3}; 342 343 public static boolean testCanonicalLengthSnippet() { 344 return Arrays.equals(constantArray1, constantArray3); 345 } 346 347 @Test 348 public void testCanonicalEqual() { 349 StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO); 350 HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); 351 new InliningPhase(new CanonicalizerPhase()).apply(graph, context); 352 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 353 354 Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1); 355 } 356 357 public static boolean testCanonicalEqualSnippet() { 358 return Arrays.equals(constantArray1, constantArray1); 359 } 360 361 @Test 362 public void testVirtualEqual() { 363 StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO); 364 HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); 365 new InliningPhase(new CanonicalizerPhase()).apply(graph, context); 366 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 367 new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); 368 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 369 370 Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1); 371 } 372 373 public static boolean testVirtualEqualSnippet() { 374 int[] array1 = new int[]{1, 2, 3, 4}; 375 int[] array2 = new int[]{1, 2, 3, 4}; 376 return Arrays.equals(array1, array2); 377 } 378 379 @Test 380 public void testVirtualNotEqual() { 381 StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO); 382 HighTierContext context = getDefaultHighTierContext(); 383 new InliningPhase(new CanonicalizerPhase()).apply(graph, context); 384 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 385 new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); 386 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 387 388 Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0); 389 } 390 391 public static boolean testVirtualNotEqualSnippet(int x) { 392 int[] array1 = new int[]{1, 2, 100, x}; 393 int[] array2 = new int[]{1, 2, 3, 4}; 394 return Arrays.equals(array1, array2); 395 } 396}