1 // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file 2 // for details. All rights reserved. Use of this source code is governed by a 3 // BSD-style license that can be found in the LICENSE file. 4 5 public class Locals { 6 7 private static void noLocals() { 8 System.out.println("There's no local here"); 9 } 10 11 private static void unusedLocals() { 12 int i = Integer.MAX_VALUE; 13 System.out.println("Not using local variable"); 14 } 15 16 private static void constantLocals(int p) { 17 int c = 5; 18 int v = c + p; 19 System.out.println("c=" + c + ", v=" + v); 20 } 21 22 private static void zeroLocals() { 23 int i = 0; 24 float f = 0.0f; 25 System.out.println("zeroLocals"); 26 } 27 28 private static void noFlowOptimization() { 29 int i = 0; 30 if (i == 0) { 31 System.out.println("i == 0"); 32 } else { 33 System.out.println("i != 0"); 34 } 35 } 36 37 private static void manyLocals() { 38 int i1 = 1; 39 int i2 = 2; 40 int i3 = 3; 41 int i4 = 4; 42 int i5 = 5; 43 int i6 = 6; 44 int i7 = 7; 45 int i8 = 8; 46 int i9 = 9; 47 int i10 = 10; 48 int i11 = 11; 49 int i12 = 12; 50 invokeRange(i6, i5, i4, i3, i2, i1, invokeRange(i12, i11, i10, i9, i8, i7, 0)); 51 } 52 53 private static int reverseRange(int a, int b, int c, int d, int e, int f, int g) { 54 return invokeRange(g, f, e, d, c, b, a); 55 } 56 57 private static int invokeRange(int a, int b, int c, int d, int e, int f, int g) { 58 System.out.println(a + b + c + d + e + f + g); 59 return a + b + c + d + e + f + g; 60 } 61 62 private void lotsOfArrayLength() { 63 int lengthOfArray1 = 0; 64 int lengthOfArray2 = 0; 65 int lengthOfArray3 = 0; 66 int lengthOfArray4 = 0; 67 int lengthOfArray5 = 0; 68 int lengthOfArray6 = 0; 69 int lengthOfArray7 = 0; 70 int lengthOfArray8 = 0; 71 int lengthOfArray9 = 0; 72 int lengthOfArray10 = 0; 73 int lengthOfArray11 = 0; 74 int lengthOfArray12 = 0; 75 int lengthOfArray13 = 0; 76 int lengthOfArray14 = 0; 77 int lengthOfArray15 = 0; 78 int lengthOfArray16 = 0; 79 80 // These statements are compiled into new-array in DEX which stores the result in a 4bit 81 // register (0..15). 82 boolean[] array1 = new boolean[1]; 83 byte[] array2 = new byte[1]; 84 char[] array3 = new char[1]; 85 short[] array4 = new short[1]; 86 int[] array5 = new int[1]; 87 long[] array6 = new long[1]; 88 float[] array7 = new float[1]; 89 double[] array8 = new double[1]; 90 Object[] array9 = new Object[1]; 91 String[] array10 = new String[1]; 92 String[] array11 = new String[1]; 93 String[] array12 = new String[1]; 94 String[] array13 = new String[1]; 95 String[] array14 = new String[1]; 96 String[] array15 = new String[1]; 97 String[] array16 = new String[1]; 98 99 // 1st breakpoint to capture the IDs of each array. 100 breakpoint(); 101 102 // Breakpoint at line below. In DEX, the array-length instruction expects a 4bit register 103 // (0..15). By creating >16 locals, we should cause an intermediate move instruction to 104 // copy/move a high register (>= 16) into a lower register (< 16). 105 // A test should step instruction by instruction and make sure all locals have the correct 106 // value. 107 lengthOfArray1 = array1.length; 108 lengthOfArray2 = array2.length; 109 lengthOfArray3 = array3.length; 110 lengthOfArray4 = array4.length; 111 lengthOfArray5 = array5.length; 112 lengthOfArray6 = array6.length; 113 lengthOfArray7 = array7.length; 114 lengthOfArray8 = array8.length; 115 lengthOfArray9 = array9.length; 116 lengthOfArray10 = array10.length; 117 lengthOfArray11 = array11.length; 118 lengthOfArray12 = array12.length; 119 lengthOfArray13 = array13.length; 120 lengthOfArray14 = array14.length; 121 lengthOfArray15 = array15.length; 122 lengthOfArray16 = array16.length; 123 124 // Use all locals 125 System.out.println(array1); 126 System.out.println(array2); 127 System.out.println(array3); 128 System.out.println(array4); 129 System.out.println(array5); 130 System.out.println(array6); 131 System.out.println(array7); 132 System.out.println(array8); 133 System.out.println(array9); 134 System.out.println(array10); 135 System.out.println(array11); 136 System.out.println(array12); 137 System.out.println(array13); 138 System.out.println(array14); 139 System.out.println(array15); 140 System.out.println(array16); 141 142 System.out.println(lengthOfArray1); 143 System.out.println(lengthOfArray2); 144 System.out.println(lengthOfArray3); 145 System.out.println(lengthOfArray4); 146 System.out.println(lengthOfArray5); 147 System.out.println(lengthOfArray6); 148 System.out.println(lengthOfArray7); 149 System.out.println(lengthOfArray8); 150 System.out.println(lengthOfArray9); 151 System.out.println(lengthOfArray10); 152 System.out.println(lengthOfArray11); 153 System.out.println(lengthOfArray12); 154 System.out.println(lengthOfArray13); 155 System.out.println(lengthOfArray14); 156 System.out.println(lengthOfArray15); 157 System.out.println(lengthOfArray16); 158 } 159 160 // Utility method to set a breakpoint and inspect the stack. 161 private static void breakpoint() { 162 } 163 164 public void foo(int x) { 165 Integer obj = new Integer(x + x); 166 long l = obj.longValue(); 167 try { 168 l = obj.longValue(); 169 x = (int) l / x; 170 invokerangeLong(l, l, l, l, l, l); 171 sout(x); 172 } catch (ArithmeticException e) { 173 sout(l); 174 } catch (RuntimeException e) { 175 sout(l); // We should not attempt to read the previous definition of 'e' here or below. 176 } catch (Throwable e) { 177 sout(l); 178 } 179 } 180 181 private void sout(long l) { 182 System.out.print(l); 183 } 184 185 private void invokerangeLong(long a, long b, long c, long d, long e, long f) { 186 if (a != d) { 187 throw new RuntimeException("unexpected"); 188 } 189 } 190 191 public static void main(String[] args) { 192 noLocals(); 193 unusedLocals(); 194 constantLocals(10); 195 zeroLocals(); 196 noFlowOptimization(); 197 manyLocals(); 198 reverseRange(1,2,3,4,5,6,7); 199 new Locals().lotsOfArrayLength(); 200 new Locals().foo(21); 201 } 202 203 } 204