diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 2245792999a..b6e3805653a 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -2444,7 +2444,8 @@ public final class String * {@code -1} if the character does not occur. */ public int indexOf(int ch) { - return indexOf(ch, 0); + return isLatin1() ? StringLatin1.indexOf(value, ch, 0, value.length) + : StringUTF16.indexOf(value, ch, 0, value.length >> 1); } /** @@ -2500,8 +2501,9 @@ public final class String * {@code fromIndex} were larger than the string length, or were negative. */ public int indexOf(int ch, int fromIndex) { - return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex, length()) - : StringUTF16.indexOf(value, ch, fromIndex, length()); + fromIndex = Math.max(fromIndex, 0); + return isLatin1() ? StringLatin1.indexOf(value, ch, Math.min(fromIndex, value.length), value.length) + : StringUTF16.indexOf(value, ch, Math.min(fromIndex, value.length >> 1), value.length >> 1); } /** diff --git a/src/java.base/share/classes/java/lang/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index a83cf65e140..0bb90617263 100644 --- a/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/src/java.base/share/classes/java/lang/StringLatin1.java @@ -310,15 +310,11 @@ final class StringLatin1 { }; } + // Caller must ensure that from- and toIndex are within bounds public static int indexOf(byte[] value, int ch, int fromIndex, int toIndex) { if (!canEncode(ch)) { return -1; } - fromIndex = Math.max(fromIndex, 0); - toIndex = Math.min(toIndex, value.length); - if (fromIndex >= toIndex) { - return -1; - } return indexOfChar(value, ch, fromIndex, toIndex); } diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index b94b583962d..13bfff55d6f 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -604,12 +604,8 @@ final class StringUTF16 { }; } + // Caller must ensure that from- and toIndex are within bounds public static int indexOf(byte[] value, int ch, int fromIndex, int toIndex) { - fromIndex = Math.max(fromIndex, 0); - toIndex = Math.min(toIndex, value.length >> 1); - if (fromIndex >= toIndex) { - return -1; - } if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { // handle most cases here (ch is a BMP code point or a // negative value (invalid code point)) @@ -716,11 +712,6 @@ final class StringUTF16 { @IntrinsicCandidate private static int indexOfChar(byte[] value, int ch, int fromIndex, int max) { - checkBoundsBeginEnd(fromIndex, max, value); - return indexOfCharUnsafe(value, ch, fromIndex, max); - } - - private static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) { for (int i = fromIndex; i < max; i++) { if (getChar(value, i) == ch) { return i; diff --git a/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java b/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java index 1f98261c608..deaa7d69975 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java +++ b/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java @@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit; @State(Scope.Thread) @Warmup(iterations = 5, time = 1) @Measurement(iterations = 5, time = 1) -@Fork(value = 1) +@Fork(value = 3) public class StringIndexOf { private String dataString; @@ -111,6 +111,21 @@ public class StringIndexOf { return string16Short.indexOf(searchChar16); } + @Benchmark + public int searchCharLongWithOffsetSuccess() { + return dataStringBig.indexOf(searchChar, 3); + } + + @Benchmark + public int searchCharMediumWithOffsetSuccess() { + return searchStringBig.indexOf(searchChar, 3); + } + + @Benchmark + public int searchCharShortWithOffsetSuccess() { + return searchString.indexOf(searchChar, 1); + } + @Benchmark public int searchChar16LongWithOffsetSuccess() { return string16Long.indexOf(searchChar16, 3);