1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2019 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 /** 18*795d594fSAndroid Build Coastguard Worker * Test code generation for BoundsCheck. 19*795d594fSAndroid Build Coastguard Worker */ 20*795d594fSAndroid Build Coastguard Worker public class Main { 21*795d594fSAndroid Build Coastguard Worker // Constant index, variable length. 22*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.constantIndex(int[]) disassembly (after) 23*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheck 24*795d594fSAndroid Build Coastguard Worker /// CHECK: cmp {{w\d+}}, #0x0 25*795d594fSAndroid Build Coastguard Worker /// CHECK: b.ls #+0x{{[0-9a-f]+}} (addr 0x<<SLOW:[0-9a-f]+>>) 26*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheckSlowPathARM64 27*795d594fSAndroid Build Coastguard Worker /// CHECK-NEXT: 0x<<SLOW>>: 28*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.constantIndex(int[]) disassembly (after) 29*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheck 30*795d594fSAndroid Build Coastguard Worker /// CHECK: cmp {{r\d+}}, #0 31*795d594fSAndroid Build Coastguard Worker /// CHECK: bls.w <<SLOW:0x[0-9a-f]+>> 32*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheckSlowPathARMVIXL 33*795d594fSAndroid Build Coastguard Worker /// CHECK-NEXT: <<SLOW>>: constantIndex(int[] a)34*795d594fSAndroid Build Coastguard Worker public static int constantIndex(int[] a) { 35*795d594fSAndroid Build Coastguard Worker try { 36*795d594fSAndroid Build Coastguard Worker a[0] = 42; 37*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException expected) { 38*795d594fSAndroid Build Coastguard Worker return -1; 39*795d594fSAndroid Build Coastguard Worker } 40*795d594fSAndroid Build Coastguard Worker return a.length; 41*795d594fSAndroid Build Coastguard Worker } 42*795d594fSAndroid Build Coastguard Worker 43*795d594fSAndroid Build Coastguard Worker // Constant length, variable index. 44*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.constantLength(int) disassembly (after) 45*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheck 46*795d594fSAndroid Build Coastguard Worker /// CHECK: cmp {{w\d+}}, #0xa 47*795d594fSAndroid Build Coastguard Worker /// CHECK: b.hs #+0x{{[0-9a-f]+}} (addr 0x<<SLOW:[0-9a-f]+>>) 48*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheckSlowPathARM64 49*795d594fSAndroid Build Coastguard Worker /// CHECK-NEXT: 0x<<SLOW>>: 50*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.constantLength(int) disassembly (after) 51*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheck 52*795d594fSAndroid Build Coastguard Worker /// CHECK: cmp {{r\d+}}, #10 53*795d594fSAndroid Build Coastguard Worker /// CHECK: bcs.w <<SLOW:0x[0-9a-f]+>> 54*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheckSlowPathARMVIXL 55*795d594fSAndroid Build Coastguard Worker /// CHECK-NEXT: <<SLOW>>: constantLength(int index)56*795d594fSAndroid Build Coastguard Worker public static int constantLength(int index) { 57*795d594fSAndroid Build Coastguard Worker int[] a = new int[10]; 58*795d594fSAndroid Build Coastguard Worker try { 59*795d594fSAndroid Build Coastguard Worker a[index] = 1; 60*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException expected) { 61*795d594fSAndroid Build Coastguard Worker return -1; 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker return index; 64*795d594fSAndroid Build Coastguard Worker } 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker // Constant index and length, out of bounds access. Check that we only have 67*795d594fSAndroid Build Coastguard Worker // the slow path. 68*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.constantIndexAndLength() disassembly (after) 69*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheck 70*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: cmp 71*795d594fSAndroid Build Coastguard Worker /// CHECK: b #+0x{{[0-9a-f]+}} (addr 0x<<SLOW:[0-9a-f]+>>) 72*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheckSlowPathARM64 73*795d594fSAndroid Build Coastguard Worker /// CHECK-NEXT: 0x<<SLOW>>: 74*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.constantIndexAndLength() disassembly (after) 75*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheck 76*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: cmp 77*795d594fSAndroid Build Coastguard Worker /// CHECK: b <<SLOW:0x[0-9a-f]+>> 78*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundsCheckSlowPathARMVIXL 79*795d594fSAndroid Build Coastguard Worker /// CHECK-NEXT: <<SLOW>>: constantIndexAndLength()80*795d594fSAndroid Build Coastguard Worker public static int constantIndexAndLength() { 81*795d594fSAndroid Build Coastguard Worker try { 82*795d594fSAndroid Build Coastguard Worker int[] a = new int[5]; 83*795d594fSAndroid Build Coastguard Worker a[10] = 42; 84*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException expected) { 85*795d594fSAndroid Build Coastguard Worker return -1; 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker return 0; 88*795d594fSAndroid Build Coastguard Worker } 89*795d594fSAndroid Build Coastguard Worker main(String[] args)90*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 91*795d594fSAndroid Build Coastguard Worker int[] a = new int[10]; 92*795d594fSAndroid Build Coastguard Worker int[] b = new int[0]; 93*795d594fSAndroid Build Coastguard Worker expectEquals(a.length, constantIndex(a)); 94*795d594fSAndroid Build Coastguard Worker expectEquals(-1, constantIndex(b)); 95*795d594fSAndroid Build Coastguard Worker expectEquals(0, constantLength(0)); 96*795d594fSAndroid Build Coastguard Worker expectEquals(9, constantLength(9)); 97*795d594fSAndroid Build Coastguard Worker expectEquals(-1, constantLength(10)); 98*795d594fSAndroid Build Coastguard Worker expectEquals(-1, constantLength(-2)); 99*795d594fSAndroid Build Coastguard Worker expectEquals(-1, constantIndexAndLength()); 100*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)103*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 104*795d594fSAndroid Build Coastguard Worker if (expected != result) { 105*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 106*795d594fSAndroid Build Coastguard Worker } 107*795d594fSAndroid Build Coastguard Worker } 108*795d594fSAndroid Build Coastguard Worker } 109