21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 package org.graalvm.compiler.replacements.amd64; |
23 package org.graalvm.compiler.replacements.amd64; |
24 |
24 |
25 import org.graalvm.compiler.api.replacements.ClassSubstitution; |
25 import org.graalvm.compiler.api.replacements.ClassSubstitution; |
|
26 import org.graalvm.compiler.api.replacements.Fold; |
|
27 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; |
26 import org.graalvm.compiler.api.replacements.MethodSubstitution; |
28 import org.graalvm.compiler.api.replacements.MethodSubstitution; |
|
29 import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider; |
27 import org.graalvm.compiler.graph.Node.ConstantNodeParameter; |
30 import org.graalvm.compiler.graph.Node.ConstantNodeParameter; |
28 import org.graalvm.compiler.word.Word; |
31 import org.graalvm.compiler.word.Word; |
29 import org.graalvm.word.Pointer; |
32 import org.graalvm.word.Pointer; |
30 |
33 |
31 import sun.misc.Unsafe; |
34 import jdk.vm.ci.meta.JavaKind; |
32 |
35 |
33 // JaCoCo Exclude |
36 // JaCoCo Exclude |
34 |
37 |
35 /** |
38 /** |
36 * Substitutions for {@link java.lang.String} methods. |
39 * Substitutions for {@link java.lang.String} methods. |
37 */ |
40 */ |
38 @ClassSubstitution(String.class) |
41 @ClassSubstitution(String.class) |
39 public class AMD64StringSubstitutions { |
42 public class AMD64StringSubstitutions { |
|
43 |
|
44 @Fold |
|
45 static int charArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { |
|
46 return arrayOffsetProvider.arrayBaseOffset(JavaKind.Char); |
|
47 } |
|
48 |
|
49 @Fold |
|
50 static int charArrayIndexScale(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { |
|
51 return arrayOffsetProvider.arrayScalingFactor(JavaKind.Char); |
|
52 } |
|
53 |
|
54 /** Marker value for the {@link InjectedParameter} injected parameter. */ |
|
55 static final ArrayOffsetProvider INJECTED = null; |
40 |
56 |
41 // Only exists in JDK <= 8 |
57 // Only exists in JDK <= 8 |
42 @MethodSubstitution(isStatic = true, optional = true) |
58 @MethodSubstitution(isStatic = true, optional = true) |
43 public static int indexOf(char[] source, int sourceOffset, int sourceCount, |
59 public static int indexOf(char[] source, int sourceOffset, int sourceCount, |
44 @ConstantNodeParameter char[] target, int targetOffset, int targetCount, |
60 @ConstantNodeParameter char[] target, int targetOffset, int targetCount, |
60 // The empty string contains nothing except the empty string. |
76 // The empty string contains nothing except the empty string. |
61 return -1; |
77 return -1; |
62 } |
78 } |
63 assert sourceCount - fromIndex > 0 && targetCount > 0; |
79 assert sourceCount - fromIndex > 0 && targetCount > 0; |
64 |
80 |
65 Pointer sourcePointer = Word.objectToTrackedPointer(source).add(Unsafe.ARRAY_CHAR_BASE_OFFSET).add(totalOffset * Unsafe.ARRAY_CHAR_INDEX_SCALE); |
81 Pointer sourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED)); |
66 Pointer targetPointer = Word.objectToTrackedPointer(target).add(Unsafe.ARRAY_CHAR_BASE_OFFSET).add(targetOffset * Unsafe.ARRAY_CHAR_INDEX_SCALE); |
82 Pointer targetPointer = Word.objectToTrackedPointer(target).add(charArrayBaseOffset(INJECTED)).add(targetOffset * charArrayIndexScale(INJECTED)); |
67 int result = AMD64StringIndexOfNode.optimizedStringIndexPointer(sourcePointer, sourceCount - fromIndex, targetPointer, targetCount); |
83 int result = AMD64StringIndexOfNode.optimizedStringIndexPointer(sourcePointer, sourceCount - fromIndex, targetPointer, targetCount); |
68 if (result >= 0) { |
84 if (result >= 0) { |
69 return result + totalOffset; |
85 return result + totalOffset; |
70 } |
86 } |
71 return result; |
87 return result; |