1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 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 public class Main { Main()18*795d594fSAndroid Build Coastguard Worker public Main() { 19*795d594fSAndroid Build Coastguard Worker } 20*795d594fSAndroid Build Coastguard Worker $noinline$testLiveArgument(int arg1, Integer arg2)21*795d594fSAndroid Build Coastguard Worker static int $noinline$testLiveArgument(int arg1, Integer arg2) { 22*795d594fSAndroid Build Coastguard Worker doStaticNativeCallLiveVreg(); 23*795d594fSAndroid Build Coastguard Worker return arg1 + arg2.intValue(); 24*795d594fSAndroid Build Coastguard Worker } 25*795d594fSAndroid Build Coastguard Worker moveArgToCalleeSave()26*795d594fSAndroid Build Coastguard Worker static void moveArgToCalleeSave() { 27*795d594fSAndroid Build Coastguard Worker try { 28*795d594fSAndroid Build Coastguard Worker Thread.sleep(0); 29*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 30*795d594fSAndroid Build Coastguard Worker throw new Error(e); 31*795d594fSAndroid Build Coastguard Worker } 32*795d594fSAndroid Build Coastguard Worker } 33*795d594fSAndroid Build Coastguard Worker $noinline$testIntervalHole(int arg, boolean test)34*795d594fSAndroid Build Coastguard Worker static void $noinline$testIntervalHole(int arg, boolean test) { 35*795d594fSAndroid Build Coastguard Worker // Move the argument to callee save to ensure it is in 36*795d594fSAndroid Build Coastguard Worker // a readable register. 37*795d594fSAndroid Build Coastguard Worker moveArgToCalleeSave(); 38*795d594fSAndroid Build Coastguard Worker if (test) { 39*795d594fSAndroid Build Coastguard Worker staticField1 = arg; 40*795d594fSAndroid Build Coastguard Worker // The environment use of `arg` should not make it live. 41*795d594fSAndroid Build Coastguard Worker doStaticNativeCallLiveVreg(); 42*795d594fSAndroid Build Coastguard Worker } else { 43*795d594fSAndroid Build Coastguard Worker staticField2 = arg; 44*795d594fSAndroid Build Coastguard Worker // The environment use of `arg` should not make it live. 45*795d594fSAndroid Build Coastguard Worker doStaticNativeCallLiveVreg(); 46*795d594fSAndroid Build Coastguard Worker } 47*795d594fSAndroid Build Coastguard Worker if (staticField1 == 2) { 48*795d594fSAndroid Build Coastguard Worker throw new Error(""); 49*795d594fSAndroid Build Coastguard Worker } 50*795d594fSAndroid Build Coastguard Worker } 51*795d594fSAndroid Build Coastguard Worker doStaticNativeCallLiveVreg()52*795d594fSAndroid Build Coastguard Worker static native void doStaticNativeCallLiveVreg(); 53*795d594fSAndroid Build Coastguard Worker main(String[] args)54*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 55*795d594fSAndroid Build Coastguard Worker System.loadLibrary(args[0]); 56*795d594fSAndroid Build Coastguard Worker if ($noinline$testLiveArgument(staticField3, Integer.valueOf(1)) != staticField3 + 1) { 57*795d594fSAndroid Build Coastguard Worker throw new Error("Expected " + staticField3 + 1); 58*795d594fSAndroid Build Coastguard Worker } 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker if ($noinline$testLiveArgument(staticField3,Integer.valueOf(1)) != staticField3 + 1) { 61*795d594fSAndroid Build Coastguard Worker throw new Error("Expected " + staticField3 + 1); 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker testWrapperIntervalHole(1, true); 65*795d594fSAndroid Build Coastguard Worker testWrapperIntervalHole(1, false); 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker $noinline$testCodeSinking(1); 68*795d594fSAndroid Build Coastguard Worker } 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker // Wrapper method to avoid inlining, which affects liveness 71*795d594fSAndroid Build Coastguard Worker // of dex registers. testWrapperIntervalHole(int arg, boolean test)72*795d594fSAndroid Build Coastguard Worker static void testWrapperIntervalHole(int arg, boolean test) { 73*795d594fSAndroid Build Coastguard Worker try { 74*795d594fSAndroid Build Coastguard Worker Thread.sleep(0); 75*795d594fSAndroid Build Coastguard Worker $noinline$testIntervalHole(arg, test); 76*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 77*795d594fSAndroid Build Coastguard Worker throw new Error(e); 78*795d594fSAndroid Build Coastguard Worker } 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker 81*795d594fSAndroid Build Coastguard Worker // The value of dex register which originally holded "Object[] o = new Object[1];" will not be 82*795d594fSAndroid Build Coastguard Worker // live at the call to doStaticNativeCallLiveVreg after code sinking optimizizaion. $noinline$testCodeSinking(int x)83*795d594fSAndroid Build Coastguard Worker static void $noinline$testCodeSinking(int x) { 84*795d594fSAndroid Build Coastguard Worker Object[] o = new Object[1]; 85*795d594fSAndroid Build Coastguard Worker o[0] = o; 86*795d594fSAndroid Build Coastguard Worker doStaticNativeCallLiveVreg(); 87*795d594fSAndroid Build Coastguard Worker if (doThrow) { 88*795d594fSAndroid Build Coastguard Worker throw new Error(o.toString()); 89*795d594fSAndroid Build Coastguard Worker } 90*795d594fSAndroid Build Coastguard Worker } 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker static boolean doThrow; 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker static int staticField1; 95*795d594fSAndroid Build Coastguard Worker static int staticField2; 96*795d594fSAndroid Build Coastguard Worker static int staticField3 = 42; 97*795d594fSAndroid Build Coastguard Worker } 98