xref: /aosp_15_r20/art/test/536-checker-intrinsic-optimization/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
18*795d594fSAndroid Build Coastguard Worker   public static String smallString = generateString(100);
19*795d594fSAndroid Build Coastguard Worker   public static String mediumString = generateString(300);
20*795d594fSAndroid Build Coastguard Worker   public static String largeString = generateString(2000);
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker   public static String smallNonAsciiString = generateNonAsciiString(100);
23*795d594fSAndroid Build Coastguard Worker   public static String mediumNonAsciiString = generateNonAsciiString(300);
24*795d594fSAndroid Build Coastguard Worker   public static String largeNonAsciiString = generateNonAsciiString(2000);
25*795d594fSAndroid Build Coastguard Worker 
generateString(int length)26*795d594fSAndroid Build Coastguard Worker   public static String generateString(int length) {
27*795d594fSAndroid Build Coastguard Worker     // Generate a string in the ASCII range that will
28*795d594fSAndroid Build Coastguard Worker     // use string compression.
29*795d594fSAndroid Build Coastguard Worker     StringBuilder sb = new StringBuilder();
30*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < length; i++) {
31*795d594fSAndroid Build Coastguard Worker       // Generate repeating alphabet.
32*795d594fSAndroid Build Coastguard Worker       sb.append(Character.valueOf((char)('a' + (i % 26))));
33*795d594fSAndroid Build Coastguard Worker     }
34*795d594fSAndroid Build Coastguard Worker     return sb.toString();
35*795d594fSAndroid Build Coastguard Worker   }
36*795d594fSAndroid Build Coastguard Worker 
generateNonAsciiString(int length)37*795d594fSAndroid Build Coastguard Worker   public static String generateNonAsciiString(int length) {
38*795d594fSAndroid Build Coastguard Worker     StringBuilder sb = new StringBuilder();
39*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < length; i++) {
40*795d594fSAndroid Build Coastguard Worker       sb.append(Character.valueOf('\uFFFF'));
41*795d594fSAndroid Build Coastguard Worker     }
42*795d594fSAndroid Build Coastguard Worker     return sb.toString();
43*795d594fSAndroid Build Coastguard Worker   }
44*795d594fSAndroid Build Coastguard Worker 
assertIntEquals(int expected, int result)45*795d594fSAndroid Build Coastguard Worker   public static void assertIntEquals(int expected, int result) {
46*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
47*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
48*795d594fSAndroid Build Coastguard Worker     }
49*795d594fSAndroid Build Coastguard Worker   }
50*795d594fSAndroid Build Coastguard Worker 
assertBooleanEquals(boolean expected, boolean result)51*795d594fSAndroid Build Coastguard Worker   public static void assertBooleanEquals(boolean expected, boolean result) {
52*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
53*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
54*795d594fSAndroid Build Coastguard Worker     }
55*795d594fSAndroid Build Coastguard Worker   }
56*795d594fSAndroid Build Coastguard Worker 
assertCharEquals(char expected, char result)57*795d594fSAndroid Build Coastguard Worker   public static void assertCharEquals(char expected, char result) {
58*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
59*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
60*795d594fSAndroid Build Coastguard Worker     }
61*795d594fSAndroid Build Coastguard Worker   }
62*795d594fSAndroid Build Coastguard Worker 
assertStringEquals(String expected, String result)63*795d594fSAndroid Build Coastguard Worker   public static void assertStringEquals(String expected, String result) {
64*795d594fSAndroid Build Coastguard Worker     if (!expected.equals(result)) {
65*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
66*795d594fSAndroid Build Coastguard Worker     }
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker 
assertStringContains(String searchTerm, String result)69*795d594fSAndroid Build Coastguard Worker   public static void assertStringContains(String searchTerm, String result) {
70*795d594fSAndroid Build Coastguard Worker     if (result == null || !result.contains(searchTerm)) {
71*795d594fSAndroid Build Coastguard Worker       throw new Error("Search term: " + searchTerm + ", not found in: " + result);
72*795d594fSAndroid Build Coastguard Worker     }
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker 
main(String[] args)75*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
76*795d594fSAndroid Build Coastguard Worker     stringEqualsSame();
77*795d594fSAndroid Build Coastguard Worker     stringArgumentNotNull("Foo");
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker     assertIntEquals(0, $opt$noinline$getStringLength(""));
80*795d594fSAndroid Build Coastguard Worker     assertIntEquals(3, $opt$noinline$getStringLength("abc"));
81*795d594fSAndroid Build Coastguard Worker     assertIntEquals(10, $opt$noinline$getStringLength("0123456789"));
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker     assertBooleanEquals(true, $opt$noinline$isStringEmpty(""));
84*795d594fSAndroid Build Coastguard Worker     assertBooleanEquals(false, $opt$noinline$isStringEmpty("abc"));
85*795d594fSAndroid Build Coastguard Worker     assertBooleanEquals(false, $opt$noinline$isStringEmpty("0123456789"));
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker     assertCharEquals('a', $opt$noinline$stringCharAt("a", 0));
88*795d594fSAndroid Build Coastguard Worker     assertCharEquals('a', $opt$noinline$stringCharAt("abc", 0));
89*795d594fSAndroid Build Coastguard Worker     assertCharEquals('b', $opt$noinline$stringCharAt("abc", 1));
90*795d594fSAndroid Build Coastguard Worker     assertCharEquals('c', $opt$noinline$stringCharAt("abc", 2));
91*795d594fSAndroid Build Coastguard Worker     assertCharEquals('7', $opt$noinline$stringCharAt("0123456789", 7));
92*795d594fSAndroid Build Coastguard Worker 
93*795d594fSAndroid Build Coastguard Worker     // Single character.
94*795d594fSAndroid Build Coastguard Worker     assertStringEquals("a", stringGetCharsAndBack("a"));
95*795d594fSAndroid Build Coastguard Worker     // Strings < 8 characters.
96*795d594fSAndroid Build Coastguard Worker     assertStringEquals("foobar", stringGetCharsAndBack("foobar"));
97*795d594fSAndroid Build Coastguard Worker     // Strings > 8 characters of various lengths.
98*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallString, stringGetCharsAndBack(smallString));
99*795d594fSAndroid Build Coastguard Worker     assertStringEquals(mediumString, stringGetCharsAndBack(mediumString));
100*795d594fSAndroid Build Coastguard Worker     assertStringEquals(largeString, stringGetCharsAndBack(largeString));
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker     // Get only a substring:
103*795d594fSAndroid Build Coastguard Worker     // Substring < 8 characters.
104*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallString.substring(5, 10), stringGetCharsRange(smallString, 5, 10, 0));
105*795d594fSAndroid Build Coastguard Worker     // Substring > 8 characters.
106*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallString.substring(7, 28), stringGetCharsRange(smallString, 7, 28, 0));
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker     // Get full string with offset in the char array.
109*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallString, stringGetCharsAndBackOffset(smallString, 17));
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker     // Get a substring with an offset in the char array.
112*795d594fSAndroid Build Coastguard Worker     // Substring < 8 characters.
113*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallString.substring(5, 10), stringGetCharsRange(smallString, 5, 10, 17));
114*795d594fSAndroid Build Coastguard Worker     // Substring > 8 characters.
115*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallString.substring(7, 28), stringGetCharsRange(smallString, 7, 28, 17));
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker     // Single character.
118*795d594fSAndroid Build Coastguard Worker     assertStringEquals("\uFFFF", stringGetCharsAndBack("\uFFFF"));
119*795d594fSAndroid Build Coastguard Worker 
120*795d594fSAndroid Build Coastguard Worker     // Strings < 8 characters.
121*795d594fSAndroid Build Coastguard Worker     assertStringEquals("\uFFFF\uFFFF\uFFFF\uFFFF\uFFFF",
122*795d594fSAndroid Build Coastguard Worker                        stringGetCharsAndBack("\uFFFF\uFFFF\uFFFF\uFFFF\uFFFF"));
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker     // Strings > 8 characters of various lengths.
125*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallNonAsciiString, stringGetCharsAndBack(smallNonAsciiString));
126*795d594fSAndroid Build Coastguard Worker     assertStringEquals(mediumNonAsciiString, stringGetCharsAndBack(mediumNonAsciiString));
127*795d594fSAndroid Build Coastguard Worker     assertStringEquals(largeNonAsciiString, stringGetCharsAndBack(largeNonAsciiString));
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker     // Get only a substring:
130*795d594fSAndroid Build Coastguard Worker     // Substring < 8 characters.
131*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallNonAsciiString.substring(5, 10),
132*795d594fSAndroid Build Coastguard Worker                        stringGetCharsRange(smallNonAsciiString, 5, 10, 0));
133*795d594fSAndroid Build Coastguard Worker     // Substring > 8 characters.
134*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallNonAsciiString.substring(7, 28),
135*795d594fSAndroid Build Coastguard Worker                        stringGetCharsRange(smallNonAsciiString, 7, 28, 0));
136*795d594fSAndroid Build Coastguard Worker 
137*795d594fSAndroid Build Coastguard Worker     // Get full string with offset in the char array.
138*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallNonAsciiString,
139*795d594fSAndroid Build Coastguard Worker                        stringGetCharsAndBackOffset(smallNonAsciiString, 17));
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker     // Get a substring with an offset in the char array.
142*795d594fSAndroid Build Coastguard Worker     // Substring < 8 characters.
143*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallNonAsciiString.substring(5, 10),
144*795d594fSAndroid Build Coastguard Worker                        stringGetCharsRange(smallNonAsciiString, 5, 10, 17));
145*795d594fSAndroid Build Coastguard Worker     // Substring > 8 characters.
146*795d594fSAndroid Build Coastguard Worker     assertStringEquals(smallNonAsciiString.substring(7, 28),
147*795d594fSAndroid Build Coastguard Worker                        stringGetCharsRange(smallNonAsciiString, 7, 28, 17));
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker     try {
150*795d594fSAndroid Build Coastguard Worker       $opt$noinline$stringCharAt("abc", -1);
151*795d594fSAndroid Build Coastguard Worker       throw new Error("Should throw SIOOB.");
152*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException sioob) {
153*795d594fSAndroid Build Coastguard Worker       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
154*795d594fSAndroid Build Coastguard Worker       assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
155*795d594fSAndroid Build Coastguard Worker     }
156*795d594fSAndroid Build Coastguard Worker     try {
157*795d594fSAndroid Build Coastguard Worker       $opt$noinline$stringCharAt("abc", 3);
158*795d594fSAndroid Build Coastguard Worker       throw new Error("Should throw SIOOB.");
159*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException sioob) {
160*795d594fSAndroid Build Coastguard Worker       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
161*795d594fSAndroid Build Coastguard Worker       assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
162*795d594fSAndroid Build Coastguard Worker     }
163*795d594fSAndroid Build Coastguard Worker     try {
164*795d594fSAndroid Build Coastguard Worker       $opt$noinline$stringCharAt("abc", Integer.MAX_VALUE);
165*795d594fSAndroid Build Coastguard Worker       throw new Error("Should throw SIOOB.");
166*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException sioob) {
167*795d594fSAndroid Build Coastguard Worker       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
168*795d594fSAndroid Build Coastguard Worker       assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
169*795d594fSAndroid Build Coastguard Worker     }
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker     assertCharEquals('7', $opt$noinline$stringCharAtCatch("0123456789", 7));
172*795d594fSAndroid Build Coastguard Worker     assertCharEquals('\0', $opt$noinline$stringCharAtCatch("0123456789", 10));
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker     assertCharEquals('7', $opt$noinline$stringCharAtCatchPhiReturn("0123456789", 7));
175*795d594fSAndroid Build Coastguard Worker     assertCharEquals('\0', $opt$noinline$stringCharAtCatchPhiReturn("0123456789", 10));
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker     assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumChars("abc"));
178*795d594fSAndroid Build Coastguard Worker     assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumLeadingChars("abcdef", 3));
179*795d594fSAndroid Build Coastguard Worker     try {
180*795d594fSAndroid Build Coastguard Worker       $opt$noinline$stringSumLeadingChars("abcdef", 7);
181*795d594fSAndroid Build Coastguard Worker       throw new Error("Should throw SIOOB.");
182*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException sioob) {
183*795d594fSAndroid Build Coastguard Worker       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
184*795d594fSAndroid Build Coastguard Worker       assertStringContains("Main.$opt$noinline$stringSumLeadingChars",
185*795d594fSAndroid Build Coastguard Worker                            sioob.getStackTrace()[1].toString());
186*795d594fSAndroid Build Coastguard Worker     }
187*795d594fSAndroid Build Coastguard Worker     assertIntEquals('a' + 'b' + 'c' + 'd', $opt$noinline$stringSum4LeadingChars("abcdef"));
188*795d594fSAndroid Build Coastguard Worker     try {
189*795d594fSAndroid Build Coastguard Worker       $opt$noinline$stringSum4LeadingChars("abc");
190*795d594fSAndroid Build Coastguard Worker       throw new Error("Should throw SIOOB.");
191*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException sioob) {
192*795d594fSAndroid Build Coastguard Worker       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
193*795d594fSAndroid Build Coastguard Worker       assertStringContains("Main.$opt$noinline$stringSum4LeadingChars",
194*795d594fSAndroid Build Coastguard Worker                            sioob.getStackTrace()[1].toString());
195*795d594fSAndroid Build Coastguard Worker     }
196*795d594fSAndroid Build Coastguard Worker   }
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) builder (after)
199*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
200*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
201*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
202*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Return [<<Length>>]
203*795d594fSAndroid Build Coastguard Worker 
204*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) builder (after)
205*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
206*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$getStringLength(String s)207*795d594fSAndroid Build Coastguard Worker   static public int $opt$noinline$getStringLength(String s) {
208*795d594fSAndroid Build Coastguard Worker     return s.length();
209*795d594fSAndroid Build Coastguard Worker   }
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) builder (after)
212*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
213*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Const0:i\d+>>   IntConstant 0
214*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
215*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
216*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<IsEmpty:z\d+>>  Equal [<<Length>>,<<Const0>>]
217*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Return [<<IsEmpty>>]
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) builder (after)
220*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
221*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$isStringEmpty(String s)222*795d594fSAndroid Build Coastguard Worker   static public boolean $opt$noinline$isStringEmpty(String s) {
223*795d594fSAndroid Build Coastguard Worker     return s.isEmpty();
224*795d594fSAndroid Build Coastguard Worker   }
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) builder (after)
227*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
228*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
229*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
230*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
231*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
232*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
233*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Return [<<Char>>]
234*795d594fSAndroid Build Coastguard Worker 
235*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) builder (after)
236*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
237*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$stringCharAt(String s, int pos)238*795d594fSAndroid Build Coastguard Worker   static public char $opt$noinline$stringCharAt(String s, int pos) {
239*795d594fSAndroid Build Coastguard Worker     return s.charAt(pos);
240*795d594fSAndroid Build Coastguard Worker   }
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) builder (after)
243*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
244*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
245*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
246*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
247*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
248*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
249*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Return [{{(c|i)\d+}}]
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) builder (after)
252*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
253*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$stringCharAtCatch(String s, int pos)254*795d594fSAndroid Build Coastguard Worker   static public char $opt$noinline$stringCharAtCatch(String s, int pos) {
255*795d594fSAndroid Build Coastguard Worker     try {
256*795d594fSAndroid Build Coastguard Worker       return s.charAt(pos);
257*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException ignored) {
258*795d594fSAndroid Build Coastguard Worker       return '\0';
259*795d594fSAndroid Build Coastguard Worker     }
260*795d594fSAndroid Build Coastguard Worker   }
261*795d594fSAndroid Build Coastguard Worker 
262*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatchPhiReturn(java.lang.String, int) builder (after)
263*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
264*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
265*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Int:i\d+>>      IntConstant 0
266*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
267*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
268*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
269*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
270*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:  <<Phi:i\d+>>      Phi [<<Char>>,<<Int>>]
271*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Return [<<Phi>>]
272*795d594fSAndroid Build Coastguard Worker 
273*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatchPhiReturn(java.lang.String, int) instruction_simplifier (after)
274*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
275*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$stringCharAtCatchPhiReturn(String s, int pos)276*795d594fSAndroid Build Coastguard Worker   static public char $opt$noinline$stringCharAtCatchPhiReturn(String s, int pos) {
277*795d594fSAndroid Build Coastguard Worker     char result;
278*795d594fSAndroid Build Coastguard Worker     try {
279*795d594fSAndroid Build Coastguard Worker       result = s.charAt(pos);
280*795d594fSAndroid Build Coastguard Worker     } catch (StringIndexOutOfBoundsException ignored) {
281*795d594fSAndroid Build Coastguard Worker       result = '\0';
282*795d594fSAndroid Build Coastguard Worker     }
283*795d594fSAndroid Build Coastguard Worker     return result;
284*795d594fSAndroid Build Coastguard Worker   }
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) builder (after)
287*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
288*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
289*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
290*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) builder (after)
293*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) GVN (after)
296*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
297*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    ArrayLength is_string_length:true
298*795d594fSAndroid Build Coastguard Worker 
299*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) BCE (after)
300*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    BoundsCheck
301*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$stringSumChars(String s)302*795d594fSAndroid Build Coastguard Worker   static public int $opt$noinline$stringSumChars(String s) {
303*795d594fSAndroid Build Coastguard Worker     int sum = 0;
304*795d594fSAndroid Build Coastguard Worker     int len = s.length();
305*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < len; ++i) {
306*795d594fSAndroid Build Coastguard Worker       sum += s.charAt(i);
307*795d594fSAndroid Build Coastguard Worker     }
308*795d594fSAndroid Build Coastguard Worker     return sum;
309*795d594fSAndroid Build Coastguard Worker   }
310*795d594fSAndroid Build Coastguard Worker 
311*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) builder (after)
312*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
313*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
314*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
315*795d594fSAndroid Build Coastguard Worker 
316*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) builder (after)
317*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
318*795d594fSAndroid Build Coastguard Worker 
319*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
320*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
323*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    BoundsCheck is_string_char_at:true
324*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$stringSumLeadingChars(String s, int n)325*795d594fSAndroid Build Coastguard Worker   static public int $opt$noinline$stringSumLeadingChars(String s, int n) {
326*795d594fSAndroid Build Coastguard Worker     int sum = 0;
327*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; ++i) {
328*795d594fSAndroid Build Coastguard Worker       sum += s.charAt(i);
329*795d594fSAndroid Build Coastguard Worker     }
330*795d594fSAndroid Build Coastguard Worker     return sum;
331*795d594fSAndroid Build Coastguard Worker   }
332*795d594fSAndroid Build Coastguard Worker 
333*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) builder (after)
334*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
335*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
336*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
337*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
338*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
339*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
340*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
341*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
342*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
343*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayLength is_string_length:true
344*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
345*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) builder (after)
348*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    InvokeVirtual
349*795d594fSAndroid Build Coastguard Worker 
350*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
351*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]
352*795d594fSAndroid Build Coastguard Worker 
353*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
354*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                    BoundsCheck is_string_char_at:true
355*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$stringSum4LeadingChars(String s)356*795d594fSAndroid Build Coastguard Worker   static public int $opt$noinline$stringSum4LeadingChars(String s) {
357*795d594fSAndroid Build Coastguard Worker     int sum = s.charAt(0) + s.charAt(1) + s.charAt(2) + s.charAt(3);
358*795d594fSAndroid Build Coastguard Worker     return sum;
359*795d594fSAndroid Build Coastguard Worker   }
360*795d594fSAndroid Build Coastguard Worker 
361*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: boolean Main.stringEqualsSame() instruction_simplifier (before)
362*795d594fSAndroid Build Coastguard Worker   /// CHECK:      InvokeStaticOrDirect
363*795d594fSAndroid Build Coastguard Worker 
364*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: boolean Main.stringEqualsSame() register (before)
365*795d594fSAndroid Build Coastguard Worker   /// CHECK:      <<Const1:i\d+>> IntConstant 1
366*795d594fSAndroid Build Coastguard Worker   /// CHECK:      Return [<<Const1>>]
367*795d594fSAndroid Build Coastguard Worker 
368*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: boolean Main.stringEqualsSame() register (before)
369*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:  InvokeStaticOrDirect
stringEqualsSame()370*795d594fSAndroid Build Coastguard Worker   public static boolean stringEqualsSame() {
371*795d594fSAndroid Build Coastguard Worker     return $inline$callStringEquals("obj", "obj");
372*795d594fSAndroid Build Coastguard Worker   }
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: boolean Main.stringEqualsNull() register (after)
375*795d594fSAndroid Build Coastguard Worker   /// CHECK:      <<Invoke:z\d+>> InvokeVirtual
376*795d594fSAndroid Build Coastguard Worker   /// CHECK:      Return [<<Invoke>>]
stringEqualsNull()377*795d594fSAndroid Build Coastguard Worker   public static boolean stringEqualsNull() {
378*795d594fSAndroid Build Coastguard Worker     String o = (String)myObject;
379*795d594fSAndroid Build Coastguard Worker     return $inline$callStringEquals(o, o);
380*795d594fSAndroid Build Coastguard Worker   }
381*795d594fSAndroid Build Coastguard Worker 
$inline$callStringEquals(String a, String b)382*795d594fSAndroid Build Coastguard Worker   public static boolean $inline$callStringEquals(String a, String b) {
383*795d594fSAndroid Build Coastguard Worker     return a.equals(b);
384*795d594fSAndroid Build Coastguard Worker   }
385*795d594fSAndroid Build Coastguard Worker 
386*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-X86: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
387*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
388*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      test
389*795d594fSAndroid Build Coastguard Worker 
390*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-X86_64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
391*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
392*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      test
393*795d594fSAndroid Build Coastguard Worker 
394*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
395*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
396*795d594fSAndroid Build Coastguard Worker   // CompareAndBranchIfZero() may emit either CBZ or CMP+BEQ.
397*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      cbz
398*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      cmp {{r\d+}}, #0
399*795d594fSAndroid Build Coastguard Worker   // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
400*795d594fSAndroid Build Coastguard Worker   // whichever comes first.
401*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp {{r\d+}}, {{r\d+}}
402*795d594fSAndroid Build Coastguard Worker 
403*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
404*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
405*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      cbz
406*795d594fSAndroid Build Coastguard Worker   // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
407*795d594fSAndroid Build Coastguard Worker   // whichever comes first.
408*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp {{w.*,}} {{w.*|#.*}}
stringArgumentNotNull(Object obj)409*795d594fSAndroid Build Coastguard Worker   public static boolean stringArgumentNotNull(Object obj) {
410*795d594fSAndroid Build Coastguard Worker     obj.getClass();
411*795d594fSAndroid Build Coastguard Worker     return "foo".equals(obj);
412*795d594fSAndroid Build Coastguard Worker   }
413*795d594fSAndroid Build Coastguard Worker 
414*795d594fSAndroid Build Coastguard Worker   // Test is very brittle as it depends on the order we emit instructions.
415*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-X86: boolean Main.stringArgumentIsString() disassembly (after)
416*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual intrinsic:StringEquals
417*795d594fSAndroid Build Coastguard Worker   /// CHECK:          test
418*795d594fSAndroid Build Coastguard Worker   /// CHECK:          jz/eq
419*795d594fSAndroid Build Coastguard Worker   // Check that we don't try to compare the classes.
420*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      mov
421*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp
422*795d594fSAndroid Build Coastguard Worker 
423*795d594fSAndroid Build Coastguard Worker   // Test is very brittle as it depends on the order we emit instructions.
424*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-X86_64: boolean Main.stringArgumentIsString() disassembly (after)
425*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual intrinsic:StringEquals
426*795d594fSAndroid Build Coastguard Worker   /// CHECK:          test
427*795d594fSAndroid Build Coastguard Worker   /// CHECK:          jz/eq
428*795d594fSAndroid Build Coastguard Worker   // Check that we don't try to compare the classes.
429*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      mov
430*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp
431*795d594fSAndroid Build Coastguard Worker 
432*795d594fSAndroid Build Coastguard Worker   // Test is brittle as it depends on the class offset being 0.
433*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: boolean Main.stringArgumentIsString() disassembly (after)
434*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual intrinsic:StringEquals
435*795d594fSAndroid Build Coastguard Worker   /// CHECK:          {{cbz|cmp}}
436*795d594fSAndroid Build Coastguard Worker   // Check that we don't try to compare the classes.
437*795d594fSAndroid Build Coastguard Worker   // The dissassembler currently explicitly emits the offset 0 but don't rely on it.
438*795d594fSAndroid Build Coastguard Worker   // We want to terminate the CHECK-NOT search after two CMPs, one for reference
439*795d594fSAndroid Build Coastguard Worker   // equality and one for length comparison but these may be emitted in different order,
440*795d594fSAndroid Build Coastguard Worker   // so repeat the check twice.
441*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
442*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
443*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp {{r\d+}}, {{r\d+}}
444*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
445*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
446*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp {{r\d+}}, {{r\d+}}
447*795d594fSAndroid Build Coastguard Worker 
448*795d594fSAndroid Build Coastguard Worker   // Test is brittle as it depends on the class offset being 0.
449*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: boolean Main.stringArgumentIsString() disassembly (after)
450*795d594fSAndroid Build Coastguard Worker   /// CHECK:          InvokeVirtual intrinsic:StringEquals
451*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cbz
452*795d594fSAndroid Build Coastguard Worker   // Check that we don't try to compare the classes.
453*795d594fSAndroid Build Coastguard Worker   // The dissassembler currently does not explicitly emits the offset 0 but don't rely on it.
454*795d594fSAndroid Build Coastguard Worker   // We want to terminate the CHECK-NOT search after two CMPs, one for reference
455*795d594fSAndroid Build Coastguard Worker   // equality and one for length comparison but these may be emitted in different order,
456*795d594fSAndroid Build Coastguard Worker   // so repeat the check twice.
457*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
458*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
459*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
460*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
461*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
462*795d594fSAndroid Build Coastguard Worker   /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
stringArgumentIsString()463*795d594fSAndroid Build Coastguard Worker   public static boolean stringArgumentIsString() {
464*795d594fSAndroid Build Coastguard Worker     return "foo".equals(myString);
465*795d594fSAndroid Build Coastguard Worker   }
466*795d594fSAndroid Build Coastguard Worker 
467*795d594fSAndroid Build Coastguard Worker   static String myString;
468*795d594fSAndroid Build Coastguard Worker   static Object myObject;
469*795d594fSAndroid Build Coastguard Worker 
stringGetCharsAndBack(String src)470*795d594fSAndroid Build Coastguard Worker   public static String stringGetCharsAndBack(String src) {
471*795d594fSAndroid Build Coastguard Worker     char[] dst = new char[src.length()];
472*795d594fSAndroid Build Coastguard Worker     src.getChars(0, src.length(), dst, 0);
473*795d594fSAndroid Build Coastguard Worker     return new String(dst);
474*795d594fSAndroid Build Coastguard Worker   }
475*795d594fSAndroid Build Coastguard Worker 
stringGetCharsAndBackOffset(String src, int offset)476*795d594fSAndroid Build Coastguard Worker   public static String stringGetCharsAndBackOffset(String src, int offset) {
477*795d594fSAndroid Build Coastguard Worker     char[] dst = new char[src.length() + offset];
478*795d594fSAndroid Build Coastguard Worker     src.getChars(0, src.length(), dst, offset);
479*795d594fSAndroid Build Coastguard Worker     return new String(dst, offset, src.length());
480*795d594fSAndroid Build Coastguard Worker   }
481*795d594fSAndroid Build Coastguard Worker 
stringGetCharsRange(String src, int srcBegin, int srcEnd, int offset)482*795d594fSAndroid Build Coastguard Worker   public static String stringGetCharsRange(String src, int srcBegin, int srcEnd, int offset) {
483*795d594fSAndroid Build Coastguard Worker     char[] dst = new char[srcEnd - srcBegin + offset];
484*795d594fSAndroid Build Coastguard Worker     src.getChars(srcBegin, srcEnd, dst, offset);
485*795d594fSAndroid Build Coastguard Worker     return new String(dst, offset, srcEnd - srcBegin);
486*795d594fSAndroid Build Coastguard Worker   }
487*795d594fSAndroid Build Coastguard Worker }
488