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