src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java
changeset 58299 6df94ce3ab2f
parent 55509 d58442b8abc1
child 58679 9c3209ff7550
equal deleted inserted replaced
58298:0152ad7b38b8 58299:6df94ce3ab2f
     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 }