Home | History | Annotate | Download | only in smali
      1 # Copyright (C) 2017 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 .class public LSmaliTests;
     16 .super Ljava/lang/Object;
     17 
     18 ## CHECK-START: void SmaliTests.bar() load_store_elimination (after)
     19 ## CHECK-DAG: <<Null:l\d+>>       NullConstant
     20 ## CHECK-DAG: <<BoundType:l\d+>>  BoundType [<<Null>>]
     21 ## CHECK-DAG: <<CheckL:l\d+>>     NullCheck [<<BoundType>>]
     22 ## CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     23 ## CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     24 ## CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     25 ## CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     26 ## CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
     27 ## CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     28 ## CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     29 ## CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     30 ## CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     31 .method public static bar()V
     32     .registers 7
     33 
     34     .prologue
     35     const/4 v6, 0x3
     36     const/4 v5, 0x2
     37     const/4 v4, 0x1
     38     const/4 v3, 0x0
     39 
     40     # We create multiple accesses that will lead the bounds check
     41     # elimination pass to add a HDeoptimize. Not having the bounds check helped
     42     # the load store elimination think it could merge two ArrayGet with different
     43     # types.
     44 
     45     # String[] array = (String[])getNull();
     46     invoke-static {}, LMain;->getNull()Ljava/lang/Object;
     47     move-result-object v0
     48     check-cast v0, [Ljava/lang/String;
     49 
     50     # objectField = array[0];
     51     aget-object v2, v0, v3
     52     sput-object v2, LMain;->objectField:Ljava/lang/Object;
     53     # objectField = array[1];
     54     aget-object v2, v0, v4
     55     sput-object v2, LMain;->objectField:Ljava/lang/Object;
     56     # objectField = array[2];
     57     aget-object v2, v0, v5
     58     sput-object v2, LMain;->objectField:Ljava/lang/Object;
     59     # objectField = array[3];
     60     aget-object v2, v0, v6
     61     sput-object v2, LMain;->objectField:Ljava/lang/Object;
     62 
     63     # long[] longArray = getLongArray();
     64     invoke-static {}, LMain;->getLongArray()[J
     65     move-result-object v1
     66 
     67     # longField = longArray[0];
     68     aget-wide v2, v1, v3
     69     sput-wide v2, LMain;->longField:J
     70     # longField = longArray[1];
     71     aget-wide v2, v1, v4
     72     sput-wide v2, LMain;->longField:J
     73     # longField = longArray[2];
     74     aget-wide v2, v1, v5
     75     sput-wide v2, LMain;->longField:J
     76     # longField = longArray[3];
     77     aget-wide v2, v1, v6
     78     sput-wide v2, LMain;->longField:J
     79 
     80     return-void
     81 .end method
     82 
     83 #   This is indentical to bar() except that it has two check-casts
     84 #   that DX tends to generate.
     85 
     86 ##  CHECK-START: void SmaliTests.bar2() load_store_elimination (after)
     87 ##  CHECK-DAG: <<Null:l\d+>>       NullConstant
     88 ##  CHECK-DAG: <<BoundFirst:l\d+>> BoundType [<<Null>>]
     89 ##  CHECK-DAG: <<BoundType:l\d+>>  BoundType [<<BoundFirst>>]
     90 ##  CHECK-DAG: <<CheckL:l\d+>>     NullCheck [<<BoundType>>]
     91 ##  CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     92 ##  CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     93 ##  CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     94 ##  CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
     95 ##  CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
     96 ##  CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     97 ##  CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     98 ##  CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
     99 ##  CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
    100 .method public static bar2()V
    101     .registers 7
    102 
    103     .prologue
    104     const/4 v6, 0x3
    105     const/4 v5, 0x2
    106     const/4 v4, 0x1
    107     const/4 v3, 0x0
    108 
    109     # We create multiple accesses that will lead the bounds check
    110     # elimination pass to add a HDeoptimize. Not having the bounds check helped
    111     # the load store elimination think it could merge two ArrayGet with different
    112     # types.
    113 
    114     # String[] array = (String[])getNull();
    115     invoke-static {}, LMain;->getNull()Ljava/lang/Object;
    116     move-result-object v2
    117     check-cast v2, [Ljava/lang/String;
    118 
    119     move-object v0, v2
    120     check-cast v0, [Ljava/lang/String;
    121 
    122     # objectField = array[0];
    123     aget-object v2, v0, v3
    124     sput-object v2, LMain;->objectField:Ljava/lang/Object;
    125     # objectField = array[1];
    126     aget-object v2, v0, v4
    127     sput-object v2, LMain;->objectField:Ljava/lang/Object;
    128     # objectField = array[2];
    129     aget-object v2, v0, v5
    130     sput-object v2, LMain;->objectField:Ljava/lang/Object;
    131     # objectField = array[3];
    132     aget-object v2, v0, v6
    133     sput-object v2, LMain;->objectField:Ljava/lang/Object;
    134 
    135     # long[] longArray = getLongArray();
    136     invoke-static {}, LMain;->getLongArray()[J
    137     move-result-object v1
    138 
    139     # longField = longArray[0];
    140     aget-wide v2, v1, v3
    141     sput-wide v2, LMain;->longField:J
    142     # longField = longArray[1];
    143     aget-wide v2, v1, v4
    144     sput-wide v2, LMain;->longField:J
    145     # longField = longArray[2];
    146     aget-wide v2, v1, v5
    147     sput-wide v2, LMain;->longField:J
    148     # longField = longArray[3];
    149     aget-wide v2, v1, v6
    150     sput-wide v2, LMain;->longField:J
    151 
    152     return-void
    153 .end method
    154 
    155 # static fields
    156 .field static doThrow:Z # boolean
    157 
    158 # direct methods
    159 .method static constructor <clinit>()V
    160     .registers 1
    161 
    162     .prologue
    163     # doThrow = false
    164     const/4 v0, 0x0
    165     sput-boolean v0, LSmaliTests;->doThrow:Z
    166     return-void
    167 .end method
    168