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