1 /*
2 * Copyright (c) 2017, 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 */
105 public static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) {
106 return AMD64ArrayIndexOf.indexOf1Char(value, max, fromIndex, (char) ch);
107 }
108
109 private static Word pointer(byte[] target) {
110 return Word.objectToTrackedPointer(target).add(byteArrayBaseOffset(INJECTED));
111 }
112
113 private static Word charOffsetPointer(byte[] value, int offset) {
114 return pointer(value).add(offset * charArrayIndexScale(INJECTED));
115 }
116
117 @MethodSubstitution
118 public static int indexOfUnsafe(byte[] source, int sourceCount, byte[] target, int targetCount, int fromIndex) {
119 ReplacementsUtil.runtimeAssert(fromIndex >= 0, "StringUTF16.indexOfUnsafe invalid args: fromIndex negative");
120 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfUnsafe invalid args: targetCount <= 0");
121 ReplacementsUtil.runtimeAssert(targetCount <= length(target), "StringUTF16.indexOfUnsafe invalid args: targetCount > length(target)");
122 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount");
123 if (targetCount == 1) {
124 return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0));
125 } else if (targetCount == 2) {
126 return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0), StringUTF16Substitutions.getChar(target, 1));
127 } else {
128 int haystackLength = sourceCount - (targetCount - 2);
129 int offset = fromIndex;
130 while (offset < haystackLength) {
131 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, StringUTF16Substitutions.getChar(target, 0),
132 StringUTF16Substitutions.getChar(target, 1));
133 if (indexOfResult < 0) {
134 return -1;
135 }
136 offset = indexOfResult;
137 Pointer cmpSourcePointer = charOffsetPointer(source, offset);
138 Pointer targetPointer = pointer(target);
139 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) {
140 return offset;
141 }
142 offset++;
143 }
144 return -1;
145 }
146 }
147
148 @MethodSubstitution
149 public static int indexOfLatin1Unsafe(byte[] source, int sourceCount, byte[] target, int targetCount, int fromIndex) {
150 ReplacementsUtil.runtimeAssert(fromIndex >= 0, "StringUTF16.indexOfLatin1Unsafe invalid args: fromIndex negative");
151 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount <= 0");
152 ReplacementsUtil.runtimeAssert(targetCount <= target.length, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount > length(target)");
153 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount");
154 if (targetCount == 1) {
155 return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0]));
156 } else if (targetCount == 2) {
157 return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
158 } else {
159 int haystackLength = sourceCount - (targetCount - 2);
160 int offset = fromIndex;
161 while (offset < haystackLength) {
162 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
163 if (indexOfResult < 0) {
164 return -1;
165 }
166 offset = indexOfResult;
167 Pointer cmpSourcePointer = charOffsetPointer(source, offset);
168 Pointer targetPointer = pointer(target);
169 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) {
170 return offset;
171 }
172 offset++;
173 }
174 return -1;
175 }
176 }
177
178 /**
179 * Intrinsic for {@code java.lang.StringUTF16.compress([CI[BII)I}.
180 *
181 * <pre>
182 * @HotSpotIntrinsicCandidate
183 * public static int compress(char[] src, int src_indx, byte[] dst, int dst_indx, int len)
184 * </pre>
185 */
186 @MethodSubstitution
187 public static int compress(char[] src, int srcIndex, byte[] dest, int destIndex, int len) {
188 if (len < 0 || srcIndex < 0 || (srcIndex + len > src.length) || destIndex < 0 || (destIndex + len > dest.length)) {
189 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException);
190 }
191
192 Pointer srcPointer = Word.objectToTrackedPointer(src).add(charArrayBaseOffset(INJECTED)).add(srcIndex * charArrayIndexScale(INJECTED));
193 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED));
194 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Char);
195 }
196
197 /**
198 * Intrinsic for {@code }java.lang.StringUTF16.compress([BI[BII)I}.
199 *
200 * <pre>
201 * @HotSpotIntrinsicCandidate
202 * public static int compress(byte[] src, int src_indx, byte[] dst, int dst_indx, int len)
203 * </pre>
204 * <p>
205 * In this variant {@code dest} refers to a byte array containing 2 byte per char so
206 * {@code srcIndex} and {@code len} are in terms of char elements and have to be scaled by 2
207 * when referring to {@code src}.
208 */
209 @MethodSubstitution
210 public static int compress(byte[] src, int srcIndex, byte[] dest, int destIndex, int len) {
211 if (len < 0 || srcIndex < 0 || (srcIndex * 2 + len * 2 > src.length) || destIndex < 0 || (destIndex + len > dest.length)) {
212 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException);
213 }
214
215 Pointer srcPointer = Word.objectToTrackedPointer(src).add(byteArrayBaseOffset(INJECTED)).add(srcIndex * 2 * byteArrayIndexScale(INJECTED));
216 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED));
217 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Byte);
218 }
219
220 }
|
1 /*
2 * Copyright (c) 2017, 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 */
105 public static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) {
106 return AMD64ArrayIndexOf.indexOf1Char(value, max, fromIndex, (char) ch);
107 }
108
109 private static Word pointer(byte[] target) {
110 return Word.objectToTrackedPointer(target).add(byteArrayBaseOffset(INJECTED));
111 }
112
113 private static Word charOffsetPointer(byte[] value, int offset) {
114 return pointer(value).add(offset * charArrayIndexScale(INJECTED));
115 }
116
117 @MethodSubstitution
118 public static int indexOfUnsafe(byte[] source, int sourceCount, byte[] target, int targetCount, int fromIndex) {
119 ReplacementsUtil.runtimeAssert(fromIndex >= 0, "StringUTF16.indexOfUnsafe invalid args: fromIndex negative");
120 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfUnsafe invalid args: targetCount <= 0");
121 ReplacementsUtil.runtimeAssert(targetCount <= length(target), "StringUTF16.indexOfUnsafe invalid args: targetCount > length(target)");
122 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount");
123 if (targetCount == 1) {
124 return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0));
125 } else {
126 int haystackLength = sourceCount - (targetCount - 2);
127 int offset = fromIndex;
128 while (offset < haystackLength) {
129 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, StringUTF16Substitutions.getChar(target, 0),
130 StringUTF16Substitutions.getChar(target, 1));
131 if (indexOfResult < 0) {
132 return -1;
133 }
134 offset = indexOfResult;
135 Pointer cmpSourcePointer = charOffsetPointer(source, offset);
136 Pointer targetPointer = pointer(target);
137 if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) {
138 return offset;
139 }
140 offset++;
141 }
142 return -1;
143 }
144 }
145
146 @MethodSubstitution
147 public static int indexOfLatin1Unsafe(byte[] source, int sourceCount, byte[] target, int targetCount, int fromIndex) {
148 ReplacementsUtil.runtimeAssert(fromIndex >= 0, "StringUTF16.indexOfLatin1Unsafe invalid args: fromIndex negative");
149 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount <= 0");
150 ReplacementsUtil.runtimeAssert(targetCount <= target.length, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount > length(target)");
151 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount");
152 if (targetCount == 1) {
153 return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0]));
154 } else {
155 int haystackLength = sourceCount - (targetCount - 2);
156 int offset = fromIndex;
157 while (offset < haystackLength) {
158 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
159 if (indexOfResult < 0) {
160 return -1;
161 }
162 offset = indexOfResult;
163 Pointer cmpSourcePointer = charOffsetPointer(source, offset);
164 Pointer targetPointer = pointer(target);
165 if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) {
166 return offset;
167 }
168 offset++;
169 }
170 return -1;
171 }
172 }
173
174 /**
175 * Intrinsic for {@code java.lang.StringUTF16.compress([CI[BII)I}.
176 *
177 * <pre>
178 * @HotSpotIntrinsicCandidate
179 * public static int compress(char[] src, int src_indx, byte[] dst, int dst_indx, int len)
180 * </pre>
181 */
182 @MethodSubstitution
183 public static int compress(char[] src, int srcIndex, byte[] dest, int destIndex, int len) {
184 checkLimits(src.length, srcIndex, dest.length, destIndex, len);
185
186 Pointer srcPointer = Word.objectToTrackedPointer(src).add(charArrayBaseOffset(INJECTED)).add(srcIndex * charArrayIndexScale(INJECTED));
187 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED));
188 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Char);
189 }
190
191 /**
192 * Intrinsic for {@code }java.lang.StringUTF16.compress([BI[BII)I}.
193 *
194 * <pre>
195 * @HotSpotIntrinsicCandidate
196 * public static int compress(byte[] src, int src_indx, byte[] dst, int dst_indx, int len)
197 * </pre>
198 * <p>
199 * In this variant {@code dest} refers to a byte array containing 2 byte per char so
200 * {@code srcIndex} and {@code len} are in terms of char elements and have to be scaled by 2
201 * when referring to {@code src}.
202 */
203 @MethodSubstitution
204 public static int compress(byte[] src, int srcIndex, byte[] dest, int destIndex, int len) {
205 checkLimits(src.length >> 1, srcIndex, dest.length, destIndex, len);
206
207 Pointer srcPointer = Word.objectToTrackedPointer(src).add(byteArrayBaseOffset(INJECTED)).add(srcIndex * 2 * byteArrayIndexScale(INJECTED));
208 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED));
209 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Byte);
210 }
211
212 private static void checkLimits(int srcLen, int srcIndex, int destLen, int destIndex, int len) {
213 if (len < 0 || srcIndex < 0 || (srcIndex + len > srcLen) || destIndex < 0 || (destIndex + len > destLen)) {
214 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException);
215 }
216 }
217
218 }
|