14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 package org.graalvm.compiler.replacements;
26
27 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
28
29 import org.graalvm.compiler.api.replacements.Fold;
30 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
31 import org.graalvm.compiler.api.replacements.Snippet;
32 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
33 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
34 import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider;
35 import org.graalvm.compiler.debug.DebugHandlersFactory;
36 import org.graalvm.compiler.nodes.StructuredGraph;
37 import org.graalvm.compiler.nodes.spi.LoweringTool;
38 import org.graalvm.compiler.options.OptionValues;
39 import org.graalvm.compiler.phases.util.Providers;
40 import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
41 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
42 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
43 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
44
45 import jdk.vm.ci.code.TargetDescription;
46 import jdk.vm.ci.meta.JavaKind;
47
48 public class ConstantStringIndexOfSnippets implements Snippets {
49 public static class Templates extends AbstractTemplates {
50
51 private final SnippetInfo indexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "indexOfConstant");
52 private final SnippetInfo latin1IndexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "latin1IndexOfConstant");
53 private final SnippetInfo utf16IndexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "utf16IndexOfConstant");
54
55 public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
56 super(options, factories, providers, snippetReflection, target);
57 }
58
59 public void lower(SnippetLowerableMemoryNode stringIndexOf, LoweringTool tool) {
60 StructuredGraph graph = stringIndexOf.graph();
61 Arguments args = new Arguments(indexOfConstant, graph.getGuardsStage(), tool.getLoweringStage());
62 args.add("source", stringIndexOf.getArgument(0));
63 args.add("sourceOffset", stringIndexOf.getArgument(1));
64 args.add("sourceCount", stringIndexOf.getArgument(2));
65 args.addConst("target", stringIndexOf.getArgument(3));
66 args.add("targetOffset", stringIndexOf.getArgument(4));
78 args.add("source", latin1IndexOf.getArgument(0));
79 args.add("sourceCount", latin1IndexOf.getArgument(1));
80 args.addConst("target", latin1IndexOf.getArgument(2));
81 args.add("targetCount", latin1IndexOf.getArgument(3));
82 args.add("origFromIndex", latin1IndexOf.getArgument(4));
83 byte[] targetByteArray = snippetReflection.asObject(byte[].class, latin1IndexOf.getArgument(2).asJavaConstant());
84 args.addConst("md2", md2(targetByteArray));
85 args.addConst("cache", computeCache(targetByteArray));
86 template(latin1IndexOf, args).instantiate(providers.getMetaAccess(), latin1IndexOf, DEFAULT_REPLACER, args);
87 }
88
89 public void lowerUTF16(SnippetLowerableMemoryNode utf16IndexOf, LoweringTool tool) {
90 StructuredGraph graph = utf16IndexOf.graph();
91 Arguments args = new Arguments(utf16IndexOfConstant, graph.getGuardsStage(), tool.getLoweringStage());
92 args.add("source", utf16IndexOf.getArgument(0));
93 args.add("sourceCount", utf16IndexOf.getArgument(1));
94 args.addConst("target", utf16IndexOf.getArgument(2));
95 args.add("targetCount", utf16IndexOf.getArgument(3));
96 args.add("origFromIndex", utf16IndexOf.getArgument(4));
97 byte[] targetByteArray = snippetReflection.asObject(byte[].class, utf16IndexOf.getArgument(2).asJavaConstant());
98 args.addConst("md2", md2Utf16(targetByteArray));
99 args.addConst("cache", computeCacheUtf16(targetByteArray));
100 template(utf16IndexOf, args).instantiate(providers.getMetaAccess(), utf16IndexOf, DEFAULT_REPLACER, args);
101 }
102 }
103
104 static int md2(char[] target) {
105 int c = target.length;
106 if (c == 0) {
107 return 0;
108 }
109 char lastChar = target[c - 1];
110 int md2 = c;
111 for (int i = 0; i < c - 1; i++) {
112 if (target[i] == lastChar) {
113 md2 = (c - 1) - i;
114 }
115 }
116 return md2;
117 }
118
119 static long computeCache(char[] s) {
134 byte lastByte = target[c - 1];
135 int md2 = c;
136 for (int i = 0; i < c - 1; i++) {
137 if (target[i] == lastByte) {
138 md2 = (c - 1) - i;
139 }
140 }
141 return md2;
142 }
143
144 static long computeCache(byte[] s) {
145 int c = s.length;
146 int cache = 0;
147 int i;
148 for (i = 0; i < c - 1; i++) {
149 cache |= (1 << (s[i] & 63));
150 }
151 return cache;
152 }
153
154 static int md2Utf16(byte[] target) {
155 int c = target.length / 2;
156 if (c == 0) {
157 return 0;
158 }
159 long base = UnsafeAccess.UNSAFE.arrayBaseOffset(byte[].class);
160 char lastChar = UnsafeAccess.UNSAFE.getChar(target, base + (c - 1) * 2);
161 int md2 = c;
162 for (int i = 0; i < c - 1; i++) {
163 char currChar = UnsafeAccess.UNSAFE.getChar(target, base + i * 2);
164 if (currChar == lastChar) {
165 md2 = (c - 1) - i;
166 }
167 }
168 return md2;
169 }
170
171 static long computeCacheUtf16(byte[] s) {
172 int c = s.length / 2;
173 int cache = 0;
174 int i;
175 long base = UnsafeAccess.UNSAFE.arrayBaseOffset(byte[].class);
176 for (i = 0; i < c - 1; i++) {
177 char currChar = UnsafeAccess.UNSAFE.getChar(s, base + i * 2);
178 cache |= (1 << (currChar & 63));
179 }
180 return cache;
181 }
182
183 @Fold
184 static int byteArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) {
185 return arrayOffsetProvider.arrayBaseOffset(JavaKind.Byte);
186 }
187
188 @Fold
189 static int charArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) {
190 return arrayOffsetProvider.arrayBaseOffset(JavaKind.Char);
191 }
192
193 /** Marker value for the {@link InjectedParameter} injected parameter. */
194 static final ArrayOffsetProvider INJECTED = null;
195
196 @Snippet
197 public static int indexOfConstant(char[] source, int sourceOffset, int sourceCount,
198 @ConstantParameter char[] target, int targetOffset, int targetCount,
199 int origFromIndex, @ConstantParameter int md2, @ConstantParameter long cache) {
200 int fromIndex = origFromIndex;
201 if (fromIndex >= sourceCount) {
202 return (targetCount == 0 ? sourceCount : -1);
203 }
204 if (fromIndex < 0) {
205 fromIndex = 0;
206 }
207 if (targetCount == 0) {
208 return fromIndex;
209 }
210
211 int targetCountLess1 = targetCount - 1;
212 int sourceEnd = sourceCount - targetCountLess1;
213
214 long base = charArrayBaseOffset(INJECTED);
|
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 package org.graalvm.compiler.replacements;
26
27 import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
28
29 import org.graalvm.compiler.api.replacements.Fold;
30 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
31 import org.graalvm.compiler.api.replacements.Snippet;
32 import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
33 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
34 import org.graalvm.compiler.debug.DebugHandlersFactory;
35 import org.graalvm.compiler.nodes.StructuredGraph;
36 import org.graalvm.compiler.nodes.spi.LoweringTool;
37 import org.graalvm.compiler.options.OptionValues;
38 import org.graalvm.compiler.phases.util.Providers;
39 import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
40 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
41 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
42 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
43
44 import jdk.vm.ci.code.TargetDescription;
45 import jdk.vm.ci.meta.JavaKind;
46 import jdk.vm.ci.meta.MetaAccessProvider;
47
48 public class ConstantStringIndexOfSnippets implements Snippets {
49 public static class Templates extends AbstractTemplates {
50
51 private final SnippetInfo indexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "indexOfConstant");
52 private final SnippetInfo latin1IndexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "latin1IndexOfConstant");
53 private final SnippetInfo utf16IndexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "utf16IndexOfConstant");
54
55 public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
56 super(options, factories, providers, snippetReflection, target);
57 }
58
59 public void lower(SnippetLowerableMemoryNode stringIndexOf, LoweringTool tool) {
60 StructuredGraph graph = stringIndexOf.graph();
61 Arguments args = new Arguments(indexOfConstant, graph.getGuardsStage(), tool.getLoweringStage());
62 args.add("source", stringIndexOf.getArgument(0));
63 args.add("sourceOffset", stringIndexOf.getArgument(1));
64 args.add("sourceCount", stringIndexOf.getArgument(2));
65 args.addConst("target", stringIndexOf.getArgument(3));
66 args.add("targetOffset", stringIndexOf.getArgument(4));
78 args.add("source", latin1IndexOf.getArgument(0));
79 args.add("sourceCount", latin1IndexOf.getArgument(1));
80 args.addConst("target", latin1IndexOf.getArgument(2));
81 args.add("targetCount", latin1IndexOf.getArgument(3));
82 args.add("origFromIndex", latin1IndexOf.getArgument(4));
83 byte[] targetByteArray = snippetReflection.asObject(byte[].class, latin1IndexOf.getArgument(2).asJavaConstant());
84 args.addConst("md2", md2(targetByteArray));
85 args.addConst("cache", computeCache(targetByteArray));
86 template(latin1IndexOf, args).instantiate(providers.getMetaAccess(), latin1IndexOf, DEFAULT_REPLACER, args);
87 }
88
89 public void lowerUTF16(SnippetLowerableMemoryNode utf16IndexOf, LoweringTool tool) {
90 StructuredGraph graph = utf16IndexOf.graph();
91 Arguments args = new Arguments(utf16IndexOfConstant, graph.getGuardsStage(), tool.getLoweringStage());
92 args.add("source", utf16IndexOf.getArgument(0));
93 args.add("sourceCount", utf16IndexOf.getArgument(1));
94 args.addConst("target", utf16IndexOf.getArgument(2));
95 args.add("targetCount", utf16IndexOf.getArgument(3));
96 args.add("origFromIndex", utf16IndexOf.getArgument(4));
97 byte[] targetByteArray = snippetReflection.asObject(byte[].class, utf16IndexOf.getArgument(2).asJavaConstant());
98 args.addConst("md2", md2Utf16(tool.getMetaAccess(), targetByteArray));
99 args.addConst("cache", computeCacheUtf16(tool.getMetaAccess(), targetByteArray));
100 template(utf16IndexOf, args).instantiate(providers.getMetaAccess(), utf16IndexOf, DEFAULT_REPLACER, args);
101 }
102 }
103
104 static int md2(char[] target) {
105 int c = target.length;
106 if (c == 0) {
107 return 0;
108 }
109 char lastChar = target[c - 1];
110 int md2 = c;
111 for (int i = 0; i < c - 1; i++) {
112 if (target[i] == lastChar) {
113 md2 = (c - 1) - i;
114 }
115 }
116 return md2;
117 }
118
119 static long computeCache(char[] s) {
134 byte lastByte = target[c - 1];
135 int md2 = c;
136 for (int i = 0; i < c - 1; i++) {
137 if (target[i] == lastByte) {
138 md2 = (c - 1) - i;
139 }
140 }
141 return md2;
142 }
143
144 static long computeCache(byte[] s) {
145 int c = s.length;
146 int cache = 0;
147 int i;
148 for (i = 0; i < c - 1; i++) {
149 cache |= (1 << (s[i] & 63));
150 }
151 return cache;
152 }
153
154 static int md2Utf16(MetaAccessProvider metaAccess, byte[] target) {
155 int c = target.length / 2;
156 if (c == 0) {
157 return 0;
158 }
159 long base = metaAccess.getArrayBaseOffset(JavaKind.Byte);
160 char lastChar = UnsafeAccess.UNSAFE.getChar(target, base + (c - 1) * 2);
161 int md2 = c;
162 for (int i = 0; i < c - 1; i++) {
163 char currChar = UnsafeAccess.UNSAFE.getChar(target, base + i * 2);
164 if (currChar == lastChar) {
165 md2 = (c - 1) - i;
166 }
167 }
168 return md2;
169 }
170
171 static long computeCacheUtf16(MetaAccessProvider metaAccess, byte[] s) {
172 int c = s.length / 2;
173 int cache = 0;
174 int i;
175 long base = metaAccess.getArrayBaseOffset(JavaKind.Byte);
176 for (i = 0; i < c - 1; i++) {
177 char currChar = UnsafeAccess.UNSAFE.getChar(s, base + i * 2);
178 cache |= (1 << (currChar & 63));
179 }
180 return cache;
181 }
182
183 @Fold
184 static int byteArrayBaseOffset(@InjectedParameter MetaAccessProvider metaAccess) {
185 return metaAccess.getArrayBaseOffset(JavaKind.Byte);
186 }
187
188 @Fold
189 static int charArrayBaseOffset(@InjectedParameter MetaAccessProvider metaAccess) {
190 return metaAccess.getArrayBaseOffset(JavaKind.Char);
191 }
192
193 /** Marker value for the {@link InjectedParameter} injected parameter. */
194 static final MetaAccessProvider INJECTED = null;
195
196 @Snippet
197 public static int indexOfConstant(char[] source, int sourceOffset, int sourceCount,
198 @ConstantParameter char[] target, int targetOffset, int targetCount,
199 int origFromIndex, @ConstantParameter int md2, @ConstantParameter long cache) {
200 int fromIndex = origFromIndex;
201 if (fromIndex >= sourceCount) {
202 return (targetCount == 0 ? sourceCount : -1);
203 }
204 if (fromIndex < 0) {
205 fromIndex = 0;
206 }
207 if (targetCount == 0) {
208 return fromIndex;
209 }
210
211 int targetCountLess1 = targetCount - 1;
212 int sourceEnd = sourceCount - targetCountLess1;
213
214 long base = charArrayBaseOffset(INJECTED);
|