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 noLocals()7 private static void noLocals() { 8 System.out.println("There's no local here"); 9 } 10 unusedLocals()11 private static void unusedLocals() { 12 int i = Integer.MAX_VALUE; 13 System.out.println("Not using local variable"); 14 } 15 constantLocals(int p)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 zeroLocals()22 private static void zeroLocals() { 23 int i = 0; 24 float f = 0.0f; 25 System.out.println("zeroLocals"); 26 } 27 noFlowOptimization()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 manyLocals()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 reverseRange(int a, int b, int c, int d, int e, int f, int g)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 invokeRange(int a, int b, int c, int d, int e, int f, int g)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 lotsOfArrayLength()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. breakpoint()161 private static void breakpoint() { 162 } 163 foo(int x)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 sout(long l)181 private void sout(long l) { 182 System.out.print(l); 183 } 184 invokerangeLong(long a, long b, long c, long d, long e, long f)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 main(String[] args)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