1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 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 import java.lang.reflect.Method; 18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException; 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker public class Main { assertIsInterpreted()21*795d594fSAndroid Build Coastguard Worker public static native void assertIsInterpreted(); ensureJitCompiled(Class<?> cls, String methodName)22*795d594fSAndroid Build Coastguard Worker public static native void ensureJitCompiled(Class<?> cls, String methodName); 23*795d594fSAndroid Build Coastguard Worker assertEqual(String expected, String actual)24*795d594fSAndroid Build Coastguard Worker public static void assertEqual(String expected, String actual) { 25*795d594fSAndroid Build Coastguard Worker if (!expected.equals(actual)) { 26*795d594fSAndroid Build Coastguard Worker throw new Error("Assertion failed: " + expected + " != " + actual); 27*795d594fSAndroid Build Coastguard Worker } 28*795d594fSAndroid Build Coastguard Worker } 29*795d594fSAndroid Build Coastguard Worker assertEqual(byte[] expected, String actual)30*795d594fSAndroid Build Coastguard Worker public static void assertEqual(byte[] expected, String actual) throws Exception { 31*795d594fSAndroid Build Coastguard Worker String str = new String(expected, "UTF8"); 32*795d594fSAndroid Build Coastguard Worker if (!str.equals(actual)) { 33*795d594fSAndroid Build Coastguard Worker throw new Error("Assertion failed: " + str + " != " + actual); 34*795d594fSAndroid Build Coastguard Worker } 35*795d594fSAndroid Build Coastguard Worker } 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker // Create an empty int[] to force loading the int[] class before compiling 38*795d594fSAndroid Build Coastguard Worker // TestCase.deoptimizeNewInstance. 39*795d594fSAndroid Build Coastguard Worker // This makes sure the compiler can properly type int[] and not bail. 40*795d594fSAndroid Build Coastguard Worker static int[] emptyArray = new int[0]; 41*795d594fSAndroid Build Coastguard Worker main(String[] args)42*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws Throwable { 43*795d594fSAndroid Build Coastguard Worker System.loadLibrary(args[0]); 44*795d594fSAndroid Build Coastguard Worker Class<?> c = Class.forName("TestCase"); 45*795d594fSAndroid Build Coastguard Worker String testString = "Hello world"; 46*795d594fSAndroid Build Coastguard Worker byte[] testData = testString.getBytes("UTF8"); 47*795d594fSAndroid Build Coastguard Worker 48*795d594fSAndroid Build Coastguard Worker { 49*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("vregAliasing", byte[].class); 50*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData }); 51*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 52*795d594fSAndroid Build Coastguard Worker } 53*795d594fSAndroid Build Coastguard Worker 54*795d594fSAndroid Build Coastguard Worker { 55*795d594fSAndroid Build Coastguard Worker c.getMethod("compareNewInstance").invoke(null, (Object[]) null); 56*795d594fSAndroid Build Coastguard Worker } 57*795d594fSAndroid Build Coastguard Worker 58*795d594fSAndroid Build Coastguard Worker { 59*795d594fSAndroid Build Coastguard Worker // If the JIT is enabled, ensure it has compiled the method to force the deopt. 60*795d594fSAndroid Build Coastguard Worker ensureJitCompiled(c, "deoptimizeNewInstance"); 61*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("deoptimizeNewInstance", int[].class, byte[].class); 62*795d594fSAndroid Build Coastguard Worker try { 63*795d594fSAndroid Build Coastguard Worker m.invoke(null, new Object[] { new int[] { 1, 2, 3 }, testData }); 64*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ex) { 65*795d594fSAndroid Build Coastguard Worker if (ex.getCause() instanceof ArrayIndexOutOfBoundsException) { 66*795d594fSAndroid Build Coastguard Worker // Expected. 67*795d594fSAndroid Build Coastguard Worker } else { 68*795d594fSAndroid Build Coastguard Worker throw ex.getCause(); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker } 71*795d594fSAndroid Build Coastguard Worker } 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker { 74*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("removeNewInstance", byte[].class); 75*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData }); 76*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 77*795d594fSAndroid Build Coastguard Worker } 78*795d594fSAndroid Build Coastguard Worker 79*795d594fSAndroid Build Coastguard Worker { 80*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("irreducibleLoopAndStringInit1", byte[].class, boolean.class); 81*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 82*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 83*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 84*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 85*795d594fSAndroid Build Coastguard Worker } 86*795d594fSAndroid Build Coastguard Worker { 87*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("irreducibleLoopAndStringInit2", byte[].class, boolean.class); 88*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 89*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 90*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 91*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 92*795d594fSAndroid Build Coastguard Worker } 93*795d594fSAndroid Build Coastguard Worker { 94*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("irreducibleLoopAndStringInit3", byte[].class, boolean.class); 95*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 96*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 97*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 98*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 99*795d594fSAndroid Build Coastguard Worker } 100*795d594fSAndroid Build Coastguard Worker { 101*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("loopAndStringInit", byte[].class, boolean.class); 102*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 103*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 104*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 105*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 106*795d594fSAndroid Build Coastguard Worker } 107*795d594fSAndroid Build Coastguard Worker { 108*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("loopAndStringInitAlias", byte[].class, boolean.class); 109*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 110*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 111*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 112*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 113*795d594fSAndroid Build Coastguard Worker } 114*795d594fSAndroid Build Coastguard Worker { 115*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("loopAndStringInitAndTest", byte[].class, boolean.class); 116*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 117*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 118*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 119*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker { 122*795d594fSAndroid Build Coastguard Worker // If the JIT is enabled, ensure it has compiled the method to force the deopt. 123*795d594fSAndroid Build Coastguard Worker ensureJitCompiled(c, "deoptimizeNewInstanceAfterLoop"); 124*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod( 125*795d594fSAndroid Build Coastguard Worker "deoptimizeNewInstanceAfterLoop", int[].class, byte[].class, int.class); 126*795d594fSAndroid Build Coastguard Worker try { 127*795d594fSAndroid Build Coastguard Worker m.invoke(null, new Object[] { new int[] { 1, 2, 3 }, testData, 0 }); 128*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ex) { 129*795d594fSAndroid Build Coastguard Worker if (ex.getCause() instanceof ArrayIndexOutOfBoundsException) { 130*795d594fSAndroid Build Coastguard Worker // Expected. 131*795d594fSAndroid Build Coastguard Worker } else { 132*795d594fSAndroid Build Coastguard Worker throw ex.getCause(); 133*795d594fSAndroid Build Coastguard Worker } 134*795d594fSAndroid Build Coastguard Worker } 135*795d594fSAndroid Build Coastguard Worker } 136*795d594fSAndroid Build Coastguard Worker { 137*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("loopAndStringInitAndPhi", byte[].class, boolean.class); 138*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, true }); 139*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 140*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false }); 141*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 142*795d594fSAndroid Build Coastguard Worker } 143*795d594fSAndroid Build Coastguard Worker { 144*795d594fSAndroid Build Coastguard Worker Method m = 145*795d594fSAndroid Build Coastguard Worker c.getMethod("loopAndTwoStringInitAndPhi", byte[].class, boolean.class, boolean.class); 146*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, false, false }); 147*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 148*795d594fSAndroid Build Coastguard Worker result = (String) m.invoke(null, new Object[] { testData, false, true }); 149*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker { 152*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("stringAndCatch", byte[].class, boolean.class); 153*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, false }); 154*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 155*795d594fSAndroid Build Coastguard Worker } 156*795d594fSAndroid Build Coastguard Worker { 157*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("stringAndCatch2", byte[].class, boolean.class); 158*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, false }); 159*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 160*795d594fSAndroid Build Coastguard Worker } 161*795d594fSAndroid Build Coastguard Worker { 162*795d594fSAndroid Build Coastguard Worker Method m = c.getMethod("stringAndCatch3", byte[].class, boolean.class); 163*795d594fSAndroid Build Coastguard Worker String result = (String) m.invoke(null, new Object[] { testData, false }); 164*795d594fSAndroid Build Coastguard Worker assertEqual(testString, result); 165*795d594fSAndroid Build Coastguard Worker } 166*795d594fSAndroid Build Coastguard Worker } 167*795d594fSAndroid Build Coastguard Worker $noinline$HiddenNull()168*795d594fSAndroid Build Coastguard Worker public static Object $noinline$HiddenNull() { 169*795d594fSAndroid Build Coastguard Worker return null; 170*795d594fSAndroid Build Coastguard Worker } 171*795d594fSAndroid Build Coastguard Worker } 172