1 /* 2 * Copyright (c) 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.hotspot.jdk9.test; 26 27 import static org.junit.Assume.assumeFalse; 28 29 import jdk.vm.ci.code.InstalledCode; 30 import jdk.vm.ci.meta.ResolvedJavaMethod; 31 import org.graalvm.compiler.core.common.CompilationIdentifier; 32 import org.graalvm.compiler.hotspot.replacements.StringUTF16Substitutions; 33 import org.graalvm.compiler.nodes.StructuredGraph; 34 import org.graalvm.compiler.nodes.java.NewArrayNode; 35 import org.graalvm.compiler.replacements.arraycopy.ArrayCopyCallNode; 36 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest; 37 import org.graalvm.compiler.test.AddExports; 38 import org.junit.Before; 39 import org.junit.Test; 40 41 /** 42 * Test substitutions for (innate) methods StringUTF16.toBytes and StringUTF16.getChars provided by 43 * {@link StringUTF16Substitutions}. 44 */ 45 @AddExports({"java.base/java.lang"}) 46 public final class StringUTF16ToBytesGetCharsTest extends MethodSubstitutionTest { 47 48 private static final int N = 1000; 49 private static final int N_OVERFLOW = 10; 50 51 @Before 52 public void checkAMD64() { 53 assumeFalse(Java8OrEarlier); 54 } 55 56 @Test 57 public void testStringUTF16ToBytes() throws ClassNotFoundException { 58 Class<?> javaclass = Class.forName("java.lang.StringUTF16"); 59 60 ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "toBytes", char[].class, int.class, int.class); 61 StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); 62 assertInGraph(graph, NewArrayNode.class); 63 assertInGraph(graph, ArrayCopyCallNode.class); 64 65 InstalledCode code = getCode(caller, graph); 66 67 for (int srcOffset = 0; srcOffset < 2; srcOffset++) { 68 for (int i = 0; i < N; i++) { 69 int length = i2sz(i); 70 char[] src = fillUTF16Chars(new char[length]); 71 int copiedLength = Math.max(0, length - srcOffset); 72 int srcDelta = Math.min(srcOffset, copiedLength); 73 byte[] dst = (byte[]) invokeSafe(caller, null, src, srcDelta, copiedLength); 74 assert dst.length == copiedLength * 2; 75 byte[] dst2 = (byte[]) executeVarargsSafe(code, src, srcDelta, copiedLength); 76 assertDeepEquals(dst, dst2); 77 } 78 } 79 for (int srcOff = 0; srcOff < N_OVERFLOW; ++srcOff) { 80 for (int len = 0; len < N_OVERFLOW; ++len) { 81 char[] src = fillUTF16Chars(new char[N_OVERFLOW]); 82 test(caller, null, src, srcOff, len); 83 } 84 } 85 } 86 87 @Test 88 public void testStringUTF16getChars() throws ClassNotFoundException { 89 Class<?> javaclass = Class.forName("java.lang.StringUTF16"); 90 91 ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "getChars", byte[].class, int.class, int.class, char[].class, int.class); 92 StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext()); 93 assertInGraph(graph, ArrayCopyCallNode.class); 94 95 InstalledCode code = getCode(caller, graph); 96 97 for (int dstOffset = 0; dstOffset < 2; dstOffset++) { 98 for (int srcOffset = 0; srcOffset < 2; srcOffset++) { 99 for (int i = 0; i < N; i++) { 100 int length = i2sz(i); 101 byte[] src = fillUTF16Bytes(new byte[length * 2]); 102 char[] dst = new char[length]; 103 int copiedLength = Math.max(0, length - Math.max(dstOffset, srcOffset)); 104 int dstDelta = Math.min(dstOffset, copiedLength); 105 int srcDelta = Math.min(srcOffset, copiedLength); 106 invokeSafe(caller, null, src, srcDelta, srcDelta + copiedLength, dst, dstDelta); 107 char[] dst2 = new char[length]; 108 executeVarargsSafe(code, src, srcDelta, srcDelta + copiedLength, dst2, dstDelta); 109 assertDeepEquals(dst, dst2); 110 } 111 } 112 } 113 for (int srcOff = 0; srcOff < N_OVERFLOW; ++srcOff) { 114 for (int dstOff = 0; dstOff < N_OVERFLOW; ++dstOff) { 115 for (int len = 0; len < N_OVERFLOW; ++len) { 116 byte[] src = fillUTF16Bytes(new byte[N_OVERFLOW]); 117 char[] dst = new char[N_OVERFLOW]; 118 test(caller, null, src, srcOff, len, dst, dstOff); 119 } 120 } 121 } 122 } 123 124 private static char[] fillUTF16Chars(char[] v) { 125 for (int ch = 0, i = 0; i < v.length; i++, ch += 0x101) { 126 v[i] = (char) ch; 127 } 128 return v; 129 } 130 131 private static byte[] fillUTF16Bytes(byte[] v) { 132 for (int ch = 1, i = 0; i < v.length; i += 2, ch++) { 133 v[i] = (byte) (ch - 1); 134 v[i + 1] = (byte) ch; 135 } 136 return v; 137 } 138 139 private static int i2sz(int i) { 140 return i * 3; 141 } 142 }