1 /*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
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.amd64;
26
27 import jdk.vm.ci.meta.JavaKind;
28 import org.graalvm.compiler.api.replacements.ClassSubstitution;
29 import org.graalvm.compiler.api.replacements.Fold;
30 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
31 import org.graalvm.compiler.api.replacements.MethodSubstitution;
32 import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider;
33 import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
34 import org.graalvm.compiler.word.Word;
35 import jdk.internal.vm.compiler.word.Pointer;
36
37 // JaCoCo Exclude
38
39 /**
40 * Substitutions for {@code java.lang.StringLatin1} methods.
41 *
42 * Since JDK 9.
43 */
44 @ClassSubstitution(className = "java.lang.StringLatin1", optional = true)
45 public class AMD64StringLatin1Substitutions {
46
47 @Fold
48 static int byteArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) {
49 return arrayOffsetProvider.arrayBaseOffset(JavaKind.Byte);
50 }
51
52 /** Marker value for the {@link InjectedParameter} injected parameter. */
53 static final ArrayOffsetProvider INJECTED = null;
54
55 /**
56 * @param value is byte[]
57 * @param other is byte[]
58 */
59 @MethodSubstitution
60 public static int compareTo(byte[] value, byte[] other) {
61 return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Byte);
62 }
63
64 /**
65 * @param value is byte[]
66 * @param other is char[]
67 */
68 @MethodSubstitution
69 public static int compareToUTF16(byte[] value, byte[] other) {
70 return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Char);
71 }
72
73 @MethodSubstitution(optional = true)
74 public static int indexOf(byte[] value, int ch, int origFromIndex) {
75 int fromIndex = origFromIndex;
76 if (ch >>> 8 != 0) {
77 // search value must be a byte value
78 return -1;
79 }
80 int length = value.length;
81 if (fromIndex < 0) {
82 fromIndex = 0;
83 } else if (fromIndex >= length) {
84 // Note: fromIndex might be near -1>>>1.
85 return -1;
86 }
87 Pointer sourcePointer = Word.objectToTrackedPointer(value).add(byteArrayBaseOffset(INJECTED)).add(fromIndex);
88 int result = AMD64ArrayIndexOfNode.optimizedArrayIndexOf(sourcePointer, length - fromIndex, (char) ch, JavaKind.Byte);
89 if (result != -1) {
90 return result + fromIndex;
91 }
92 return result;
93 }
94 }
|
1 /*
2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
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.amd64;
26
27 import org.graalvm.compiler.api.replacements.ClassSubstitution;
28 import org.graalvm.compiler.api.replacements.Fold;
29 import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
30 import org.graalvm.compiler.api.replacements.MethodSubstitution;
31 import org.graalvm.compiler.nodes.DeoptimizeNode;
32 import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
33 import org.graalvm.compiler.word.Word;
34 import jdk.internal.vm.compiler.word.Pointer;
35
36 import jdk.vm.ci.meta.DeoptimizationAction;
37 import jdk.vm.ci.meta.DeoptimizationReason;
38 import jdk.vm.ci.meta.JavaKind;
39 import jdk.vm.ci.meta.MetaAccessProvider;
40
41 // JaCoCo Exclude
42
43 /**
44 * Substitutions for {@code java.lang.StringLatin1} methods.
45 *
46 * Since JDK 9.
47 */
48 @ClassSubstitution(className = "java.lang.StringLatin1", optional = true)
49 public class AMD64StringLatin1Substitutions {
50
51 @Fold
52 static int byteArrayBaseOffset(@InjectedParameter MetaAccessProvider metaAccess) {
53 return metaAccess.getArrayBaseOffset(JavaKind.Byte);
54 }
55
56 @Fold
57 static int byteArrayIndexScale(@InjectedParameter MetaAccessProvider metaAccess) {
58 return metaAccess.getArrayIndexScale(JavaKind.Byte);
59 }
60
61 @Fold
62 static int charArrayBaseOffset(@InjectedParameter MetaAccessProvider metaAccess) {
63 return metaAccess.getArrayBaseOffset(JavaKind.Char);
64 }
65
66 @Fold
67 static int charArrayIndexScale(@InjectedParameter MetaAccessProvider metaAccess) {
68 return metaAccess.getArrayIndexScale(JavaKind.Char);
69 }
70
71 /** Marker value for the {@link InjectedParameter} injected parameter. */
72 static final MetaAccessProvider INJECTED = null;
73
74 /**
75 * @param value is byte[]
76 * @param other is byte[]
77 */
78 @MethodSubstitution
79 public static int compareTo(byte[] value, byte[] other) {
80 return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Byte);
81 }
82
83 /**
84 * @param value is byte[]
85 * @param other is char[]
86 */
87 @MethodSubstitution
88 public static int compareToUTF16(byte[] value, byte[] other) {
89 return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Char);
90 }
91
92 @MethodSubstitution(optional = true)
93 public static int indexOf(byte[] value, int ch, int origFromIndex) {
94 int fromIndex = origFromIndex;
95 if (ch >>> 8 != 0) {
96 // search value must be a byte value
97 return -1;
98 }
99 int length = value.length;
100 if (fromIndex < 0) {
101 fromIndex = 0;
102 } else if (fromIndex >= length) {
103 // Note: fromIndex might be near -1>>>1.
104 return -1;
105 }
106 Pointer sourcePointer = Word.objectToTrackedPointer(value).add(byteArrayBaseOffset(INJECTED)).add(fromIndex);
107 int result = AMD64ArrayIndexOf.indexOf1Byte(sourcePointer, length - fromIndex, (byte) ch);
108 if (result != -1) {
109 return result + fromIndex;
110 }
111 return result;
112 }
113
114 /**
115 * Intrinsic for {@code java.lang.StringLatin1.inflate([BI[CII)V}.
116 *
117 * <pre>
118 * @HotSpotIntrinsicCandidate
119 * public static void inflate(byte[] src, int src_indx, char[] dst, int dst_indx, int len)
120 * </pre>
121 */
122 @MethodSubstitution
123 public static void inflate(byte[] src, int srcIndex, char[] dest, int destIndex, int len) {
124 if (len < 0 || srcIndex < 0 || (srcIndex + len > src.length) || destIndex < 0 || (destIndex + len > dest.length)) {
125 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException);
126 }
127
128 // Offset calc. outside of the actual intrinsic.
129 Pointer srcPointer = Word.objectToTrackedPointer(src).add(byteArrayBaseOffset(INJECTED)).add(srcIndex * byteArrayIndexScale(INJECTED));
130 Pointer destPointer = Word.objectToTrackedPointer(dest).add(charArrayBaseOffset(INJECTED)).add(destIndex * charArrayIndexScale(INJECTED));
131 AMD64StringLatin1InflateNode.inflate(srcPointer, destPointer, len, JavaKind.Char);
132 }
133
134 /**
135 * Intrinsic for {@code }java.lang.StringLatin1.inflate([BI[BII)V}.
136 *
137 * <pre>
138 * @HotSpotIntrinsicCandidate
139 * public static void inflate(byte[] src, int src_indx, byte[] dst, int dst_indx, int len)
140 * </pre>
141 *
142 * In this variant {@code dest} refers to a byte array containing 2 byte per char so
143 * {@code destIndex} and {@code len} are in terms of char elements and have to be scaled by 2
144 * when referring to {@code dest}
145 */
146 @MethodSubstitution
147 public static void inflate(byte[] src, int srcIndex, byte[] dest, int destIndex, int len) {
148 if (len < 0 || srcIndex < 0 || (srcIndex + len > src.length) || destIndex < 0 || (destIndex * 2 + len * 2 > dest.length)) {
149 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.BoundsCheckException);
150 }
151
152 // Offset calc. outside of the actual intrinsic.
153 Pointer srcPointer = Word.objectToTrackedPointer(src).add(byteArrayBaseOffset(INJECTED)).add(srcIndex * byteArrayIndexScale(INJECTED));
154 Pointer destPointer = Word.objectToTrackedPointer(dest).add(byteArrayBaseOffset(INJECTED)).add(destIndex * 2 * byteArrayIndexScale(INJECTED));
155 AMD64StringLatin1InflateNode.inflate(srcPointer, destPointer, len, JavaKind.Byte);
156 }
157
158 }
|