Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 import java.lang.reflect.Method;
     17 
     18 public class Main {
     19 
     20   /// CHECK-START: void Main.InlineVoid() inliner (before)
     21   /// CHECK-DAG:     <<Const42:i\d+>> IntConstant 42
     22   /// CHECK-DAG:                      InvokeStaticOrDirect
     23   /// CHECK-DAG:                      InvokeStaticOrDirect [<<Const42>>{{(,[ij]\d+)?}}]
     24 
     25   /// CHECK-START: void Main.InlineVoid() inliner (after)
     26   /// CHECK-NOT:                      InvokeStaticOrDirect
     27 
     28   public static void InlineVoid() {
     29     returnVoid();
     30     returnVoidWithOneParameter(42);
     31   }
     32 
     33   /// CHECK-START: int Main.InlineParameter(int) inliner (before)
     34   /// CHECK-DAG:     <<Param:i\d+>>  ParameterValue
     35   /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}]
     36   /// CHECK-DAG:                     Return [<<Result>>]
     37 
     38   /// CHECK-START: int Main.InlineParameter(int) inliner (after)
     39   /// CHECK-DAG:     <<Param:i\d+>>  ParameterValue
     40   /// CHECK-DAG:                     Return [<<Param>>]
     41 
     42   public static int InlineParameter(int a) {
     43     return returnParameter(a);
     44   }
     45 
     46   /// CHECK-START: long Main.InlineWideParameter(long) inliner (before)
     47   /// CHECK-DAG:     <<Param:j\d+>>  ParameterValue
     48   /// CHECK-DAG:     <<Result:j\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}]
     49   /// CHECK-DAG:                     Return [<<Result>>]
     50 
     51   /// CHECK-START: long Main.InlineWideParameter(long) inliner (after)
     52   /// CHECK-DAG:     <<Param:j\d+>>  ParameterValue
     53   /// CHECK-DAG:                     Return [<<Param>>]
     54 
     55   public static long InlineWideParameter(long a) {
     56     return returnWideParameter(a);
     57   }
     58 
     59   /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (before)
     60   /// CHECK-DAG:     <<Param:l\d+>>  ParameterValue
     61   /// CHECK-DAG:     <<Result:l\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}]
     62   /// CHECK-DAG:                     Return [<<Result>>]
     63 
     64   /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (after)
     65   /// CHECK-DAG:     <<Param:l\d+>>  ParameterValue
     66   /// CHECK-DAG:                     Return [<<Param>>]
     67 
     68   public static Object InlineReferenceParameter(Object o) {
     69     return returnReferenceParameter(o);
     70   }
     71 
     72   /// CHECK-START: int Main.InlineInt() inliner (before)
     73   /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect
     74   /// CHECK-DAG:                     Return [<<Result>>]
     75 
     76   /// CHECK-START: int Main.InlineInt() inliner (after)
     77   /// CHECK-DAG:     <<Const4:i\d+>> IntConstant 4
     78   /// CHECK-DAG:                     Return [<<Const4>>]
     79 
     80   public static int InlineInt() {
     81     return returnInt();
     82   }
     83 
     84   /// CHECK-START: long Main.InlineWide() inliner (before)
     85   /// CHECK-DAG:     <<Result:j\d+>> InvokeStaticOrDirect
     86   /// CHECK-DAG:                     Return [<<Result>>]
     87 
     88   /// CHECK-START: long Main.InlineWide() inliner (after)
     89   /// CHECK-DAG:     <<Const8:j\d+>> LongConstant 8
     90   /// CHECK-DAG:                     Return [<<Const8>>]
     91 
     92   public static long InlineWide() {
     93     return returnWide();
     94   }
     95 
     96   /// CHECK-START: int Main.InlineAdd() inliner (before)
     97   /// CHECK-DAG:     <<Const3:i\d+>> IntConstant 3
     98   /// CHECK-DAG:     <<Const5:i\d+>> IntConstant 5
     99   /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect
    100   /// CHECK-DAG:                     Return [<<Result>>]
    101 
    102   /// CHECK-START: int Main.InlineAdd() inliner (after)
    103   /// CHECK-DAG:     <<Const8:i\d+>> IntConstant 8
    104   /// CHECK-DAG:                     Return [<<Const8>>]
    105 
    106   public static int InlineAdd() {
    107     return returnAdd(3, 5);
    108   }
    109 
    110   /// CHECK-START: int Main.InlineFieldAccess() inliner (before)
    111   /// CHECK-DAG:     <<After:i\d+>>  InvokeStaticOrDirect
    112   /// CHECK-DAG:                     Return [<<After>>]
    113 
    114   /// CHECK-START: int Main.InlineFieldAccess() inliner (after)
    115   /// CHECK-DAG:     <<Const1:i\d+>> IntConstant 1
    116   /// CHECK-DAG:     <<Before:i\d+>> StaticFieldGet
    117   /// CHECK-DAG:     <<After:i\d+>>  Add [<<Before>>,<<Const1>>]
    118   /// CHECK-DAG:                     StaticFieldSet [{{l\d+}},<<After>>]
    119   /// CHECK-DAG:                     Return [<<After>>]
    120 
    121   /// CHECK-START: int Main.InlineFieldAccess() inliner (after)
    122   /// CHECK-NOT:                     InvokeStaticOrDirect
    123 
    124   public static int InlineFieldAccess() {
    125     return incCounter();
    126   }
    127 
    128   public static int InlineWithControlFlow(boolean cond) {
    129     try {
    130       Class<?> c = Class.forName("Smali");
    131       Method m = c.getMethod("InlineWithControlFlow", boolean.class);
    132       return (Integer) m.invoke(null, cond);
    133     } catch (Throwable t) {
    134       throw new RuntimeException(t);
    135     }
    136   }
    137 
    138   /// CHECK-START: int Main.returnAbs(int) intrinsics_recognition (before)
    139   /// CHECK-DAG:     <<Result:i\d+>>      InvokeStaticOrDirect
    140   /// CHECK-DAG:                          Return [<<Result>>]
    141 
    142   /// CHECK-START: int Main.returnAbs(int) intrinsics_recognition (after)
    143   /// CHECK-DAG:     <<Result:i\d+>>      InvokeStaticOrDirect intrinsic:MathAbsInt
    144   /// CHECK-DAG:                          Return [<<Result>>]
    145 
    146   private static int returnAbs(int i) {
    147     return Math.abs(i);
    148   }
    149 
    150   /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (before)
    151   /// CHECK-DAG:     <<ConstMinus1:i\d+>> IntConstant -1
    152   /// CHECK-DAG:     <<Result:i\d+>>      InvokeStaticOrDirect
    153   /// CHECK-DAG:                          Return [<<Result>>]
    154 
    155   /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (after)
    156   /// CHECK-DAG:     <<ConstMinus1:i\d+>> IntConstant -1
    157   /// CHECK-DAG:     <<Result:i\d+>>      InvokeStaticOrDirect intrinsic:MathAbsInt
    158   /// CHECK-DAG:                          Return [<<Result>>]
    159 
    160   public static int InlinedIntrinsicsAreStillIntrinsic() {
    161     return returnAbs(-1);
    162   }
    163 
    164   private static void returnVoid() {
    165     return;
    166   }
    167 
    168   private static void returnVoidWithOneParameter(int a) {
    169     return;
    170   }
    171 
    172   private static int returnParameter(int a) {
    173     return a;
    174   }
    175 
    176   private static long returnWideParameter(long a) {
    177     return a;
    178   }
    179 
    180   private static Object returnReferenceParameter(Object o) {
    181     return o;
    182   }
    183 
    184   private static int returnInt() {
    185     return 4;
    186   }
    187 
    188   private static long returnWide() {
    189     return 8L;
    190   }
    191 
    192   private static int returnAdd(int a, int b) {
    193     return a + b;
    194   }
    195 
    196   private static int returnSub(int a, int b) {
    197     return a - b;
    198   }
    199 
    200   private static int counter = 42;
    201 
    202   private static int incCounter() {
    203     return ++counter;
    204   }
    205 
    206   public static void main(String[] args) {
    207     InlineVoid();
    208 
    209     if (InlineInt() != 4) {
    210       throw new Error();
    211     }
    212 
    213     if (InlineWide() != 8L) {
    214       throw new Error();
    215     }
    216 
    217     if (InlineParameter(42) != 42) {
    218       throw new Error();
    219     }
    220 
    221     if (InlineWideParameter(0x100000001L) != 0x100000001L) {
    222       throw new Error();
    223     }
    224 
    225     if (InlineReferenceParameter(Main.class) != Main.class) {
    226       throw new Error();
    227     }
    228 
    229     if (InlineAdd() != 8) {
    230       throw new Error();
    231     }
    232 
    233     if (InlineFieldAccess() != 43 || InlineFieldAccess() != 44) {
    234       throw new Error();
    235     }
    236 
    237     if (InlineWithControlFlow(true) != 4) {
    238       throw new Error();
    239     }
    240 
    241     if (InlineWithControlFlow(false) != 2) {
    242       throw new Error();
    243     }
    244 
    245     if (InlinedIntrinsicsAreStillIntrinsic() != 1) {
    246       throw new Error();
    247     }
    248 
    249     if (returnAbs(-1) != 1) {
    250       throw new Error();
    251     }
    252   }
    253 }
    254