< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java

Print this page

        

*** 22,50 **** */ package org.graalvm.compiler.replacements.amd64; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.nodes.DeoptimizeNode; import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode; import org.graalvm.compiler.word.Word; import jdk.internal.vm.compiler.word.Pointer; - import jdk.vm.ci.meta.DeoptimizationAction; - import jdk.vm.ci.meta.DeoptimizationReason; - import jdk.vm.ci.meta.JavaKind; - import jdk.vm.ci.meta.MetaAccessProvider; - // JaCoCo Exclude /** * Substitutions for {@code java.lang.StringUTF16} methods. ! * * Since JDK 9. */ @ClassSubstitution(className = "java.lang.StringUTF16", optional = true) public class AMD64StringUTF16Substitutions { --- 22,52 ---- */ package org.graalvm.compiler.replacements.amd64; + import jdk.vm.ci.meta.DeoptimizationAction; + import jdk.vm.ci.meta.DeoptimizationReason; + import jdk.vm.ci.meta.JavaKind; + import jdk.vm.ci.meta.MetaAccessProvider; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.nodes.DeoptimizeNode; + import org.graalvm.compiler.replacements.ReplacementsUtil; + import org.graalvm.compiler.replacements.StringUTF16Substitutions; import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode; + import org.graalvm.compiler.replacements.nodes.ArrayRegionEqualsNode; import org.graalvm.compiler.word.Word; import jdk.internal.vm.compiler.word.Pointer; // JaCoCo Exclude /** * Substitutions for {@code java.lang.StringUTF16} methods. ! * <p> * Since JDK 9. */ @ClassSubstitution(className = "java.lang.StringUTF16", optional = true) public class AMD64StringUTF16Substitutions {
*** 66,78 **** @Fold static int charArrayIndexScale(@InjectedParameter MetaAccessProvider metaAccess) { return metaAccess.getArrayIndexScale(JavaKind.Char); } ! /** Marker value for the {@link InjectedParameter} injected parameter. */ static final MetaAccessProvider INJECTED = null; /** * @param value is char[] * @param other is char[] */ @MethodSubstitution --- 68,86 ---- @Fold static int charArrayIndexScale(@InjectedParameter MetaAccessProvider metaAccess) { return metaAccess.getArrayIndexScale(JavaKind.Char); } ! /** ! * Marker value for the {@link InjectedParameter} injected parameter. ! */ static final MetaAccessProvider INJECTED = null; + public static int length(byte[] value) { + return value.length >> 1; + } + /** * @param value is char[] * @param other is char[] */ @MethodSubstitution
*** 91,110 **** * arguments stay in original order. */ return ArrayCompareToNode.compareTo(other, value, other.length, value.length, JavaKind.Char, JavaKind.Byte); } ! @MethodSubstitution(optional = true) public static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) { ! Pointer sourcePointer = Word.objectToTrackedPointer(value).add(byteArrayBaseOffset(INJECTED)).add(fromIndex * charArrayIndexScale(INJECTED)); int result = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, max - fromIndex, (char) ch); if (result != -1) { return result + fromIndex; } return result; } /** * Intrinsic for {@code java.lang.StringUTF16.compress([CI[BII)I}. * * <pre> * @HotSpotIntrinsicCandidate --- 99,212 ---- * arguments stay in original order. */ return ArrayCompareToNode.compareTo(other, value, other.length, value.length, JavaKind.Char, JavaKind.Byte); } ! @MethodSubstitution public static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) { ! Pointer sourcePointer = charOffsetPointer(value, fromIndex); int result = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, max - fromIndex, (char) ch); if (result != -1) { return result + fromIndex; } return result; } + private static Word pointer(byte[] target) { + return Word.objectToTrackedPointer(target).add(byteArrayBaseOffset(INJECTED)); + } + + private static Word charOffsetPointer(byte[] value, int offset) { + return pointer(value).add(offset * charArrayIndexScale(INJECTED)); + } + + @MethodSubstitution + public static int indexOfUnsafe(byte[] source, int sourceCount, byte[] target, int targetCount, int fromIndex) { + ReplacementsUtil.runtimeAssert(fromIndex >= 0, "StringUTF16.indexOfUnsafe invalid args: fromIndex negative"); + ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfUnsafe invalid args: targetCount <= 0"); + ReplacementsUtil.runtimeAssert(targetCount <= length(target), "StringUTF16.indexOfUnsafe invalid args: targetCount > length(target)"); + ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount"); + int totalOffset = fromIndex; + if (targetCount == 1) { + Pointer sourcePointer = charOffsetPointer(source, totalOffset); + int indexOfResult = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, sourceCount - fromIndex, StringUTF16Substitutions.getChar(target, 0)); + if (indexOfResult >= 0) { + return indexOfResult + totalOffset; + } + return indexOfResult; + } else if (targetCount == 2) { + Pointer sourcePointer = charOffsetPointer(source, totalOffset); + int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, sourceCount - fromIndex, StringUTF16Substitutions.getChar(target, 0), + StringUTF16Substitutions.getChar(target, 1)); + if (indexOfResult >= 0) { + return indexOfResult + totalOffset; + } + return indexOfResult; + } else { + int haystackLength = sourceCount - (fromIndex + (targetCount - 2)); + while (haystackLength > 0) { + Pointer sourcePointer = charOffsetPointer(source, totalOffset); + int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, haystackLength, StringUTF16Substitutions.getChar(target, 0), + StringUTF16Substitutions.getChar(target, 1)); + if (indexOfResult < 0) { + return -1; + } + totalOffset += indexOfResult; + haystackLength -= (indexOfResult + 1); + Pointer cmpSourcePointer = charOffsetPointer(source, totalOffset); + Pointer targetPointer = pointer(target); + if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) { + return totalOffset; + } + totalOffset++; + } + return -1; + } + } + + @MethodSubstitution + public static int indexOfLatin1Unsafe(byte[] source, int sourceCount, byte[] target, int targetCount, int fromIndex) { + ReplacementsUtil.runtimeAssert(fromIndex >= 0, "StringUTF16.indexOfLatin1Unsafe invalid args: fromIndex negative"); + ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount <= 0"); + ReplacementsUtil.runtimeAssert(targetCount <= target.length, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount > length(target)"); + ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount"); + int totalOffset = fromIndex; + if (targetCount == 1) { + Pointer sourcePointer = charOffsetPointer(source, totalOffset); + int indexOfResult = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, sourceCount - fromIndex, (char) Byte.toUnsignedInt(target[0])); + if (indexOfResult >= 0) { + return indexOfResult + totalOffset; + } + return indexOfResult; + } else if (targetCount == 2) { + Pointer sourcePointer = charOffsetPointer(source, totalOffset); + int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, sourceCount - fromIndex, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1])); + if (indexOfResult >= 0) { + return indexOfResult + totalOffset; + } + return indexOfResult; + } else { + int haystackLength = sourceCount - (fromIndex + (targetCount - 2)); + while (haystackLength > 0) { + Pointer sourcePointer = charOffsetPointer(source, totalOffset); + int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, haystackLength, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1])); + if (indexOfResult < 0) { + return -1; + } + totalOffset += indexOfResult; + haystackLength -= (indexOfResult + 1); + Pointer cmpSourcePointer = charOffsetPointer(source, totalOffset); + Pointer targetPointer = pointer(target); + if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) { + return totalOffset; + } + totalOffset++; + } + return -1; + } + } + /** * Intrinsic for {@code java.lang.StringUTF16.compress([CI[BII)I}. * * <pre> * @HotSpotIntrinsicCandidate
*** 127,137 **** * * <pre> * @HotSpotIntrinsicCandidate * public static int compress(byte[] src, int src_indx, byte[] dst, int dst_indx, int len) * </pre> ! * * In this variant {@code dest} refers to a byte array containing 2 byte per char so * {@code srcIndex} and {@code len} are in terms of char elements and have to be scaled by 2 * when referring to {@code src}. */ @MethodSubstitution --- 229,239 ---- * * <pre> * @HotSpotIntrinsicCandidate * public static int compress(byte[] src, int src_indx, byte[] dst, int dst_indx, int len) * </pre> ! * <p> * In this variant {@code dest} refers to a byte array containing 2 byte per char so * {@code srcIndex} and {@code len} are in terms of char elements and have to be scaled by 2 * when referring to {@code src}. */ @MethodSubstitution
< prev index next >