1 /* 2 * Copyright (c) 2014, 2019, 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 org.graalvm.compiler.nodes.StructuredGraph; 28 import org.graalvm.compiler.replacements.StringSubstitutions; 29 import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode; 30 import org.graalvm.compiler.serviceprovider.JavaVersionUtil; 31 import org.junit.Test; 32 33 import jdk.vm.ci.code.InstalledCode; 34 import jdk.vm.ci.meta.ResolvedJavaMethod; 35 36 /** 37 * Tests {@link StringSubstitutions}. 38 */ 39 public class StringSubstitutionsTest extends MethodSubstitutionTest { 40 41 public void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, boolean optional, Object[] args1, Object[] args2) { 42 ResolvedJavaMethod realMethod = getResolvedJavaMethod(holder, methodName); 43 ResolvedJavaMethod testMethod = getResolvedJavaMethod(testMethodName); 44 StructuredGraph graph = testGraph(testMethodName); 45 46 // Check to see if the resulting graph contains the expected node 47 StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null, graph.getOptions()); 48 if (replacement == null && !optional) { 49 assertInGraph(graph, intrinsicClass); 50 } 51 52 // Force compilation 53 InstalledCode code = getCode(testMethod); 54 assert optional || code != null; 55 56 for (int i = 0; i < args1.length; i++) { 57 Object arg1 = args1[i]; 58 Object arg2 = args2[i]; 59 Object expected = invokeSafe(realMethod, arg1, arg2); 60 // Verify that the original method and the substitution produce the same value 61 assertDeepEquals(expected, invokeSafe(testMethod, null, arg1, arg2)); 62 // Verify that the generated code and the original produce the same value 63 assertDeepEquals(expected, executeVarargsSafe(code, arg1, arg2)); 64 } 65 } 66 67 @Test 68 public void testEquals() { 69 if (JavaVersionUtil.JAVA_SPEC > 8) { 70 // StringSubstitutions are disabled in 1.9 71 return; 72 } 73 74 final int n = 1000; 75 Object[] args1 = new Object[n]; 76 Object[] args2 = new Object[n]; 77 78 // equal strings 79 String s1 = ""; 80 String s2 = ""; 81 for (int i = 0; i < n / 2; i++) { 82 args1[i] = s1; 83 args2[i] = s2; 84 s1 = s1 + "0"; 85 s2 = s2 + "0"; 86 } 87 88 // non-equal strings 89 s1 = ""; 90 s2 = ""; 91 for (int i = n / 2; i < n; i++) { 92 args1[i] = s1; 93 args2[i] = s2; 94 s2 = s1 + "1"; 95 s1 = s1 + "0"; 96 } 97 98 testSubstitution("stringEquals", ArrayEqualsNode.class, String.class, "equals", false, args1, args2); 99 } 100 101 @SuppressWarnings("all") 102 public static boolean stringEquals(String a, String b) { 103 return a.equals(b); 104 } 105 106 @Test 107 public void testIndexOfConstant() { 108 test("indexOfConstant"); 109 } 110 111 public int indexOfConstant() { 112 String foobar = "foobar"; 113 String bar = "bar"; 114 return foobar.indexOf(bar); 115 } 116 117 @Test 118 public void testIndexOfConstantUTF16() { 119 test("indexOfConstantUTF16case1"); 120 test("indexOfConstantUTF16case2"); 121 test("indexOfConstantUTF16case3"); 122 } 123 124 public int indexOfConstantUTF16case1() { 125 return ("grga " + ((char) 0x10D) + "varak").indexOf(((char) 0x10D) + "varak"); 126 } 127 128 public int indexOfConstantUTF16case2() { 129 int index = ("grga " + ((char) 0xD) + "varak").indexOf(((char) 0x10D) + "varak"); 130 return index; 131 } 132 133 public int indexOfConstantUTF16case3() { 134 int index = ("grga " + ((char) 0x100) + "varak").indexOf(((char) 0x10D) + "varak"); 135 return index; 136 } 137 138 @Test 139 public void testCompareTo() { 140 test("compareTo"); 141 } 142 143 public int compareTo() { 144 return "ofar".compareTo("rafo"); 145 } 146 }