1 /* |
1 /* |
2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. |
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. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
120 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfUnsafe invalid args: targetCount <= 0"); |
120 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfUnsafe invalid args: targetCount <= 0"); |
121 ReplacementsUtil.runtimeAssert(targetCount <= length(target), "StringUTF16.indexOfUnsafe invalid args: targetCount > length(target)"); |
121 ReplacementsUtil.runtimeAssert(targetCount <= length(target), "StringUTF16.indexOfUnsafe invalid args: targetCount > length(target)"); |
122 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount"); |
122 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount"); |
123 if (targetCount == 1) { |
123 if (targetCount == 1) { |
124 return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0)); |
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 { |
125 } else { |
128 int haystackLength = sourceCount - (targetCount - 2); |
126 int haystackLength = sourceCount - (targetCount - 2); |
129 int offset = fromIndex; |
127 int offset = fromIndex; |
130 while (offset < haystackLength) { |
128 while (offset < haystackLength) { |
131 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, StringUTF16Substitutions.getChar(target, 0), |
129 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, StringUTF16Substitutions.getChar(target, 0), |
134 return -1; |
132 return -1; |
135 } |
133 } |
136 offset = indexOfResult; |
134 offset = indexOfResult; |
137 Pointer cmpSourcePointer = charOffsetPointer(source, offset); |
135 Pointer cmpSourcePointer = charOffsetPointer(source, offset); |
138 Pointer targetPointer = pointer(target); |
136 Pointer targetPointer = pointer(target); |
139 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { |
137 if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { |
140 return offset; |
138 return offset; |
141 } |
139 } |
142 offset++; |
140 offset++; |
143 } |
141 } |
144 return -1; |
142 return -1; |
151 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount <= 0"); |
149 ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount <= 0"); |
152 ReplacementsUtil.runtimeAssert(targetCount <= target.length, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount > length(target)"); |
150 ReplacementsUtil.runtimeAssert(targetCount <= target.length, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount > length(target)"); |
153 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount"); |
151 ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount"); |
154 if (targetCount == 1) { |
152 if (targetCount == 1) { |
155 return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0])); |
153 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 { |
154 } else { |
159 int haystackLength = sourceCount - (targetCount - 2); |
155 int haystackLength = sourceCount - (targetCount - 2); |
160 int offset = fromIndex; |
156 int offset = fromIndex; |
161 while (offset < haystackLength) { |
157 while (offset < haystackLength) { |
162 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1])); |
158 int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1])); |
164 return -1; |
160 return -1; |
165 } |
161 } |
166 offset = indexOfResult; |
162 offset = indexOfResult; |
167 Pointer cmpSourcePointer = charOffsetPointer(source, offset); |
163 Pointer cmpSourcePointer = charOffsetPointer(source, offset); |
168 Pointer targetPointer = pointer(target); |
164 Pointer targetPointer = pointer(target); |
169 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) { |
165 if (targetCount == 2 || ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) { |
170 return offset; |
166 return offset; |
171 } |
167 } |
172 offset++; |
168 offset++; |
173 } |
169 } |
174 return -1; |
170 return -1; |
183 * public static int compress(char[] src, int src_indx, byte[] dst, int dst_indx, int len) |
179 * public static int compress(char[] src, int src_indx, byte[] dst, int dst_indx, int len) |
184 * </pre> |
180 * </pre> |
185 */ |
181 */ |
186 @MethodSubstitution |
182 @MethodSubstitution |
187 public static int compress(char[] src, int srcIndex, byte[] dest, int destIndex, int len) { |
183 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)) { |
184 checkLimits(src.length, srcIndex, dest.length, destIndex, len); |
189 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException); |
|
190 } |
|
191 |
185 |
192 Pointer srcPointer = Word.objectToTrackedPointer(src).add(charArrayBaseOffset(INJECTED)).add(srcIndex * charArrayIndexScale(INJECTED)); |
186 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)); |
187 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED)); |
194 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Char); |
188 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Char); |
195 } |
189 } |
206 * {@code srcIndex} and {@code len} are in terms of char elements and have to be scaled by 2 |
200 * {@code srcIndex} and {@code len} are in terms of char elements and have to be scaled by 2 |
207 * when referring to {@code src}. |
201 * when referring to {@code src}. |
208 */ |
202 */ |
209 @MethodSubstitution |
203 @MethodSubstitution |
210 public static int compress(byte[] src, int srcIndex, byte[] dest, int destIndex, int len) { |
204 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)) { |
205 checkLimits(src.length >> 1, srcIndex, dest.length, destIndex, len); |
212 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException); |
|
213 } |
|
214 |
206 |
215 Pointer srcPointer = Word.objectToTrackedPointer(src).add(byteArrayBaseOffset(INJECTED)).add(srcIndex * 2 * byteArrayIndexScale(INJECTED)); |
207 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)); |
208 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * byteArrayIndexScale(INJECTED)); |
217 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Byte); |
209 return AMD64StringUTF16CompressNode.compress(srcPointer, destPointer, len, JavaKind.Byte); |
218 } |
210 } |
219 |
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 |
220 } |
218 } |