1a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray/*
2a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * Copyright (C) 2015 The Android Open Source Project
3a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray *
4a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * you may not use this file except in compliance with the License.
6a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * You may obtain a copy of the License at
7a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray *
8a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray *
10a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * See the License for the specific language governing permissions and
14a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray * limitations under the License.
15a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray */
16a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
170381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkinimport java.lang.reflect.Method;
18a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
19a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffraypublic class Main {
20dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  public static boolean doThrow = false;
21dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
22dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  public static void assertIntEquals(int expected, int result) {
23dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    if (expected != result) {
24dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko      throw new Error("Expected: " + expected + ", found: " + result);
25dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    }
26dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  }
27dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
28dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  public static void assertBooleanEquals(boolean expected, boolean result) {
29dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    if (expected != result) {
30dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko      throw new Error("Expected: " + expected + ", found: " + result);
31dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    }
32dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  }
33dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
3487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  public static void assertCharEquals(char expected, char result) {
3587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (expected != result) {
3687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Expected: " + expected + ", found: " + result);
3787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
3887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
3987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
4087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  public static void assertStringContains(String searchTerm, String result) {
4187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (result == null || !result.contains(searchTerm)) {
4287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Search term: " + searchTerm + ", not found in: " + result);
4387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
4487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
4587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
46a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  public static void main(String[] args) {
47a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    stringEqualsSame();
48a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    stringArgumentNotNull("Foo");
49dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
50dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    assertIntEquals(0, $opt$noinline$getStringLength(""));
51dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    assertIntEquals(3, $opt$noinline$getStringLength("abc"));
52dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    assertIntEquals(10, $opt$noinline$getStringLength("0123456789"));
53dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
54dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    assertBooleanEquals(true, $opt$noinline$isStringEmpty(""));
55dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    assertBooleanEquals(false, $opt$noinline$isStringEmpty("abc"));
56dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    assertBooleanEquals(false, $opt$noinline$isStringEmpty("0123456789"));
5787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
5887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('a', $opt$noinline$stringCharAt("a", 0));
5987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('a', $opt$noinline$stringCharAt("abc", 0));
6087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('b', $opt$noinline$stringCharAt("abc", 1));
6187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('c', $opt$noinline$stringCharAt("abc", 2));
6287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('7', $opt$noinline$stringCharAt("0123456789", 7));
6387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
6487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    try {
6587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      $opt$noinline$stringCharAt("abc", -1);
6687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Should throw SIOOB.");
6787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    } catch (StringIndexOutOfBoundsException sioob) {
6887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
6987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
7087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
7187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    try {
7287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      $opt$noinline$stringCharAt("abc", 3);
7387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Should throw SIOOB.");
7487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    } catch (StringIndexOutOfBoundsException sioob) {
7587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
7687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
7787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
7887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    try {
7987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      $opt$noinline$stringCharAt("abc", Integer.MAX_VALUE);
8087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Should throw SIOOB.");
8187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    } catch (StringIndexOutOfBoundsException sioob) {
8287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
8387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
8487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
8587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
8687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('7', $opt$noinline$stringCharAtCatch("0123456789", 7));
870381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin    assertCharEquals('7', $noinline$runSmaliTest("stringCharAtCatch", "0123456789", 7));
8887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertCharEquals('\0', $opt$noinline$stringCharAtCatch("0123456789", 10));
890381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin    assertCharEquals('\0', $noinline$runSmaliTest("stringCharAtCatch","0123456789", 10));
9087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
9187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumChars("abc"));
9287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumLeadingChars("abcdef", 3));
9387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    try {
9487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      $opt$noinline$stringSumLeadingChars("abcdef", 7);
9587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Should throw SIOOB.");
9687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    } catch (StringIndexOutOfBoundsException sioob) {
9787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
9887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("Main.$opt$noinline$stringSumLeadingChars",
9987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko                           sioob.getStackTrace()[1].toString());
10087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
10187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    assertIntEquals('a' + 'b' + 'c' + 'd', $opt$noinline$stringSum4LeadingChars("abcdef"));
10287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    try {
10387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      $opt$noinline$stringSum4LeadingChars("abc");
10487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      throw new Error("Should throw SIOOB.");
10587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    } catch (StringIndexOutOfBoundsException sioob) {
10687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
10787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      assertStringContains("Main.$opt$noinline$stringSum4LeadingChars",
10887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko                           sioob.getStackTrace()[1].toString());
10987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
110dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  }
111dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
112dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (before)
113dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<Length:i\d+>>   InvokeVirtual intrinsic:StringLength
114dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:                    Return [<<Length>>]
115dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
116dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (after)
117dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
118dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
119dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
120dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:                    Return [<<Length>>]
121dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
122dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (after)
123dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringLength
124dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
125dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  static public int $opt$noinline$getStringLength(String s) {
126dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    if (doThrow) { throw new Error(); }
127dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    return s.length();
128dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  }
129dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
130dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (before)
131dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<IsEmpty:z\d+>>  InvokeVirtual intrinsic:StringIsEmpty
132dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:                    Return [<<IsEmpty>>]
133dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
134dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (after)
135dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
136dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<Const0:i\d+>>   IntConstant 0
137dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
138dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
139dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:  <<IsEmpty:z\d+>>  Equal [<<Length>>,<<Const0>>]
140dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-DAG:                    Return [<<IsEmpty>>]
141dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
142dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (after)
143dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringIsEmpty
144dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko
145dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko  static public boolean $opt$noinline$isStringEmpty(String s) {
146dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    if (doThrow) { throw new Error(); }
147dce016eab87302f02b0bd903dd2cd86ae512df2dVladimir Marko    return s.isEmpty();
148a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
149a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
15087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (before)
15187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<Char:c\d+>>     InvokeVirtual intrinsic:StringCharAt
15287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    Return [<<Char>>]
15387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
15487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after)
15587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
15687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
15787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
15887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
159431121fb0e1fab93a550e71e1da22d3bf056bd95Nicolas Geoffray  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
160431121fb0e1fab93a550e71e1da22d3bf056bd95Nicolas Geoffray  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
16187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    Return [<<Char>>]
16287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
16387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after)
16487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
16587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
16687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  static public char $opt$noinline$stringCharAt(String s, int pos) {
16787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (doThrow) { throw new Error(); }
16887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    return s.charAt(pos);
16987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
17087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
17187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (before)
1720381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin  /// CHECK-DAG:  <<Int:i\d+>>      IntConstant 0
17387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<Char:c\d+>>     InvokeVirtual intrinsic:StringCharAt
174919c3c5344724113eaf9b4faa5379a8b0de24b15Alan Leung
175919c3c5344724113eaf9b4faa5379a8b0de24b15Alan Leung  //                                The return value can come from a Phi should the two returns be merged.
176919c3c5344724113eaf9b4faa5379a8b0de24b15Alan Leung  //                                Please refer to the Smali code for a more detailed verification.
177919c3c5344724113eaf9b4faa5379a8b0de24b15Alan Leung
178919c3c5344724113eaf9b4faa5379a8b0de24b15Alan Leung  /// CHECK-DAG:                    Return [{{(c|i)\d+}}]
17987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
18087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after)
18187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
18287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
1830381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin  /// CHECK-DAG:  <<Int:i\d+>>      IntConstant 0
18487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
18587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
186431121fb0e1fab93a550e71e1da22d3bf056bd95Nicolas Geoffray  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
187431121fb0e1fab93a550e71e1da22d3bf056bd95Nicolas Geoffray  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
188919c3c5344724113eaf9b4faa5379a8b0de24b15Alan Leung  /// CHECK-DAG:                    Return [{{(c|i)\d+}}]
18987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
19087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after)
19187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
19287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
19387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  static public char $opt$noinline$stringCharAtCatch(String s, int pos) {
19487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (doThrow) { throw new Error(); }
19587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    try {
19687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      return s.charAt(pos);
19787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    } catch (StringIndexOutOfBoundsException ignored) {
19887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      return '\0';
19987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
20087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
20187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
20287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (before)
20387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringLength
20487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
20587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
20687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after)
20787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
20887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
20987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
21087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
21187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
21287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after)
21387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringLength
21487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
21587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
21687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) GVN (after)
21787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
21887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    ArrayLength is_string_length:true
21987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
22087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) BCE (after)
22187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    BoundsCheck
22287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
22387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  static public int $opt$noinline$stringSumChars(String s) {
22487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (doThrow) { throw new Error(); }
22587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    int sum = 0;
22687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    int len = s.length();
22787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    for (int i = 0; i < len; ++i) {
22887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      sum += s.charAt(i);
22987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
23087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    return sum;
23187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
23287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
23387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (before)
23487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
23587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
23687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after)
23787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
23887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
23987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
24087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
24187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after)
24287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
24387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
24487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
24587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]
24687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
24787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
24887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    BoundsCheck is_string_char_at:true
24987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
25087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  static public int $opt$noinline$stringSumLeadingChars(String s, int n) {
25187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (doThrow) { throw new Error(); }
25287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    int sum = 0;
25387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    for (int i = 0; i < n; ++i) {
25487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko      sum += s.charAt(i);
25587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    }
25687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    return sum;
25787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
25887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
25987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (before)
26087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
26187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
26287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
26387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
26487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
26587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after)
26687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
26787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
26887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
26987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
27087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
27187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
27287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
27387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
27487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
27587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayLength is_string_length:true
27687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
27787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
27887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
27987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after)
28087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
28187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
28287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
28387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]
28487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
28587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
28687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  /// CHECK-NOT:                    BoundsCheck is_string_char_at:true
28787f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
28887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  static public int $opt$noinline$stringSum4LeadingChars(String s) {
28987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    if (doThrow) { throw new Error(); }
29087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    int sum = s.charAt(0) + s.charAt(1) + s.charAt(2) + s.charAt(3);
29187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    return sum;
29287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko  }
29387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
294a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-START: boolean Main.stringEqualsSame() instruction_simplifier (before)
295a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK:      InvokeStaticOrDirect
296a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
297a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-START: boolean Main.stringEqualsSame() register (before)
298a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK:      <<Const1:i\d+>> IntConstant 1
299a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK:      Return [<<Const1>>]
300a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
301a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-START: boolean Main.stringEqualsSame() register (before)
302a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-NOT:  InvokeStaticOrDirect
303a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  public static boolean stringEqualsSame() {
304a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    return $inline$callStringEquals("obj", "obj");
305a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
306a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
307a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-START: boolean Main.stringEqualsNull() register (after)
308e523423a053af5cb55837f07ceae9ff2fd581712Nicolas Geoffray  /// CHECK:      <<Invoke:z\d+>> InvokeVirtual
309a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK:      Return [<<Invoke>>]
310a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  public static boolean stringEqualsNull() {
311a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    String o = (String)myObject;
312a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    return $inline$callStringEquals(o, o);
313a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
314a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
315a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  public static boolean $inline$callStringEquals(String a, String b) {
316a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    return a.equals(b);
317a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
318a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
319a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-START-X86: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
32053b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
321a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-NOT:      test
32253b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko
32353b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-START-X86_64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
32453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
32553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      test
32653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko
32753b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-START-ARM: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
32853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
32953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // CompareAndBranchIfZero() may emit either CBZ or CMP+BEQ.
33053b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      cbz
33153b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      cmp {{r\d+}}, #0
33253b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
33353b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // whichever comes first.
33453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          cmp {{r\d+}}, {{r\d+}}
33553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko
33653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-START-ARM64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
33753b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
33853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      cbz
33953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
34053b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // whichever comes first.
341e39f14ff4e0d7c70016874cff24863b912d40bf1Vladimir Marko  /// CHECK:          cmp {{w.*,}} {{w.*|#.*}}
34264fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic
34364fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-START-MIPS: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
34464fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
34543e99b099a8ca71eda14d8009fd38cb0d441b694Goran Jakovljevic  /// CHECK-NOT:      beq zero,
34664fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-NOT:      beqz
34764fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-NOT:      beqzc
34864fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // Terminate the scope for the CHECK-NOT search at the class field or length comparison,
34964fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // whichever comes first.
35064fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          lw
35164fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic
35264fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-START-MIPS64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
35364fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
35464fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-NOT:      beqzc
35564fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // Terminate the scope for the CHECK-NOT search at the reference comparison.
35664fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          beqc
357a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  public static boolean stringArgumentNotNull(Object obj) {
358a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    obj.getClass();
359a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    return "foo".equals(obj);
360a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
361a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
362a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  // Test is very brittle as it depends on the order we emit instructions.
363a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  /// CHECK-START-X86: boolean Main.stringArgumentIsString() disassembly (after)
36453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual intrinsic:StringEquals
36553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          test
36653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          jz/eq
36753b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Check that we don't try to compare the classes.
36853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      mov
36953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          cmp
37053b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko
37153b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Test is very brittle as it depends on the order we emit instructions.
37253b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-START-X86_64: boolean Main.stringArgumentIsString() disassembly (after)
37353b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual intrinsic:StringEquals
37453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          test
37553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          jz/eq
37653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Check that we don't try to compare the classes.
37753b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      mov
37853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          cmp
37953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko
38053b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Test is brittle as it depends on the class offset being 0.
38153b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-START-ARM: boolean Main.stringArgumentIsString() disassembly (after)
38253b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual intrinsic:StringEquals
38353b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          {{cbz|cmp}}
38453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Check that we don't try to compare the classes.
38553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // The dissassembler currently explicitly emits the offset 0 but don't rely on it.
38653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // We want to terminate the CHECK-NOT search after two CMPs, one for reference
38753b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // equality and one for length comparison but these may be emitted in different order,
38853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // so repeat the check twice.
38953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
39053b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
39153b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          cmp {{r\d+}}, {{r\d+}}
39253b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
39353b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
39453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          cmp {{r\d+}}, {{r\d+}}
39553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko
39653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // Test is brittle as it depends on the class offset being 0.
39753b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-START-ARM64: boolean Main.stringArgumentIsString() disassembly (after)
39853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          InvokeVirtual intrinsic:StringEquals
39953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK:          cbz
400a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  // Check that we don't try to compare the classes.
40153b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // The dissassembler currently does not explicitly emits the offset 0 but don't rely on it.
40253b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // We want to terminate the CHECK-NOT search after two CMPs, one for reference
40353b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // equality and one for length comparison but these may be emitted in different order,
40453b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  // so repeat the check twice.
40553b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
40653b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
407e39f14ff4e0d7c70016874cff24863b912d40bf1Vladimir Marko  /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
40853b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
40953b52005ddae649e6f1cf475de7c259bc6885e6dVladimir Marko  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
410e39f14ff4e0d7c70016874cff24863b912d40bf1Vladimir Marko  /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
41164fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic
41264fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // Test is brittle as it depends on the class offset being 0.
41364fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-START-MIPS: boolean Main.stringArgumentIsString() disassembly (after)
41464fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          InvokeVirtual intrinsic:StringEquals
41564fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          beq{{(zc)?}}
41664fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // Check that we don't try to compare the classes.
41764fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-NOT:      lw {{r\d+}}, +0({{r\d+}})
41864fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          bne{{c?}}
41964fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic
42064fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // Test is brittle as it depends on the class offset being 0.
42164fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-START-MIPS64: boolean Main.stringArgumentIsString() disassembly (after)
42264fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          InvokeVirtual intrinsic:StringEquals
42364fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          beqzc
42464fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  // Check that we don't try to compare the classes.
42564fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK-NOT:      lw {{r\d+}}, +0({{r\d+}})
42664fa84fba1d46afd5a2dc7dc3cc1de77461888bcGoran Jakovljevic  /// CHECK:          bnec
427a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  public static boolean stringArgumentIsString() {
428a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray    return "foo".equals(myString);
429a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  }
430a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray
431a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  static String myString;
432a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray  static Object myObject;
4330381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin
4340381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin  public static char $noinline$runSmaliTest(String name, String str, int pos) {
4350381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin    try {
4360381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin      Class<?> c = Class.forName("SmaliTests");
4370381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin      Method m = c.getMethod(name, String.class, int.class);
4380381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin      return (Character) m.invoke(null, str, pos);
4390381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin    } catch (Exception ex) {
4400381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin      throw new Error(ex);
4410381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin    }
4420381bed9bc857a4c48b5aecee6f8ab9c468c18deIgor Murashkin  }
443a83a54d7f2322060f08480f8aabac5eb07268912Nicolas Geoffray}
444