22 */ |
22 */ |
23 package org.graalvm.compiler.replacements; |
23 package org.graalvm.compiler.replacements; |
24 |
24 |
25 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; |
25 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; |
26 |
26 |
|
27 import org.graalvm.compiler.api.replacements.Fold; |
|
28 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; |
27 import org.graalvm.compiler.api.replacements.Snippet; |
29 import org.graalvm.compiler.api.replacements.Snippet; |
28 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; |
30 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; |
|
31 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; |
|
32 import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider; |
29 import org.graalvm.compiler.debug.DebugHandlersFactory; |
33 import org.graalvm.compiler.debug.DebugHandlersFactory; |
30 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; |
|
31 import org.graalvm.compiler.nodes.StructuredGraph; |
34 import org.graalvm.compiler.nodes.StructuredGraph; |
32 import org.graalvm.compiler.nodes.spi.LoweringTool; |
35 import org.graalvm.compiler.nodes.spi.LoweringTool; |
33 import org.graalvm.compiler.options.OptionValues; |
36 import org.graalvm.compiler.options.OptionValues; |
34 import org.graalvm.compiler.phases.util.Providers; |
37 import org.graalvm.compiler.phases.util.Providers; |
35 import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; |
38 import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; |
36 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; |
39 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; |
37 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; |
40 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; |
38 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode; |
41 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode; |
39 |
42 |
40 import jdk.vm.ci.code.TargetDescription; |
43 import jdk.vm.ci.code.TargetDescription; |
41 import sun.misc.Unsafe; |
44 import jdk.vm.ci.meta.JavaKind; |
42 |
45 |
43 public class ConstantStringIndexOfSnippets implements Snippets { |
46 public class ConstantStringIndexOfSnippets implements Snippets { |
44 public static class Templates extends AbstractTemplates { |
47 public static class Templates extends AbstractTemplates { |
45 |
48 |
46 private final SnippetInfo indexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "indexOfConstant"); |
49 private final SnippetInfo indexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "indexOfConstant"); |
89 cache |= (1 << (s[i] & 63)); |
92 cache |= (1 << (s[i] & 63)); |
90 } |
93 } |
91 return cache; |
94 return cache; |
92 } |
95 } |
93 |
96 |
|
97 @Fold |
|
98 static int charArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { |
|
99 return arrayOffsetProvider.arrayBaseOffset(JavaKind.Char); |
|
100 } |
|
101 |
|
102 /** Marker value for the {@link InjectedParameter} injected parameter. */ |
|
103 static final ArrayOffsetProvider INJECTED = null; |
|
104 |
94 @Snippet |
105 @Snippet |
95 public static int indexOfConstant(char[] source, int sourceOffset, int sourceCount, |
106 public static int indexOfConstant(char[] source, int sourceOffset, int sourceCount, |
96 @ConstantParameter char[] target, int targetOffset, int targetCount, |
107 @ConstantParameter char[] target, int targetOffset, int targetCount, |
97 int origFromIndex, @ConstantParameter int md2, @ConstantParameter long cache) { |
108 int origFromIndex, @ConstantParameter int md2, @ConstantParameter long cache) { |
98 int fromIndex = origFromIndex; |
109 int fromIndex = origFromIndex; |
107 } |
118 } |
108 |
119 |
109 int targetCountLess1 = targetCount - 1; |
120 int targetCountLess1 = targetCount - 1; |
110 int sourceEnd = sourceCount - targetCountLess1; |
121 int sourceEnd = sourceCount - targetCountLess1; |
111 |
122 |
112 long base = Unsafe.ARRAY_CHAR_BASE_OFFSET; |
123 long base = charArrayBaseOffset(INJECTED); |
113 int lastChar = UnsafeAccess.UNSAFE.getChar(target, base + targetCountLess1 * 2); |
124 int lastChar = UnsafeAccess.UNSAFE.getChar(target, base + targetCountLess1 * 2); |
114 |
125 |
115 outer_loop: for (long i = sourceOffset + fromIndex; i < sourceEnd;) { |
126 outer_loop: for (long i = sourceOffset + fromIndex; i < sourceEnd;) { |
116 int src = UnsafeAccess.UNSAFE.getChar(source, base + (i + targetCountLess1) * 2); |
127 int src = UnsafeAccess.UNSAFE.getChar(source, base + (i + targetCountLess1) * 2); |
117 if (src == lastChar) { |
128 if (src == lastChar) { |