Home | History | Annotate | Download | only in smali
      1 # Copyright (C) 2016 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 LTestCase;
     16 .super Ljava/lang/Object;
     17 
     18 # Test that all vregs holding the new-instance are updated after the
     19 # StringFactory call.
     20 
     21 ## CHECK-START: java.lang.String TestCase.vregAliasing(byte[]) register (after)
     22 ## CHECK-DAG:                Return [<<String:l\d+>>]
     23 ## CHECK-DAG:     <<String>> InvokeStaticOrDirect  method_name:java.lang.String.<init>
     24 
     25 .method public static vregAliasing([B)Ljava/lang/String;
     26    .registers 5
     27 
     28    # Create new instance of String and store it to v0, v1, v2.
     29    new-instance v0, Ljava/lang/String;
     30    move-object v1, v0
     31    move-object v2, v0
     32 
     33    # Call String.<init> on v1.
     34    const-string v3, "UTF8"
     35    invoke-direct {v1, p0, v3}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
     36 
     37    # Return the object from v2.
     38    return-object v2
     39 
     40 .end method
     41 
     42 # Test usage of String new-instance before it is initialized.
     43 
     44 ## CHECK-START: void TestCase.compareNewInstance() register (after)
     45 ## CHECK-DAG:     <<Null:l\d+>>   InvokeStaticOrDirect method_name:Main.$noinline$HiddenNull
     46 ## CHECK-DAG:     <<String:l\d+>> NewInstance
     47 ## CHECK-DAG:     <<Cond:z\d+>>   NotEqual [<<Null>>,<<String>>]
     48 ## CHECK-DAG:                     If [<<Cond>>]
     49 
     50 .method public static compareNewInstance()V
     51    .registers 3
     52 
     53    invoke-static {}, LMain;->$noinline$HiddenNull()Ljava/lang/Object;
     54    move-result-object v1
     55 
     56    new-instance v0, Ljava/lang/String;
     57    if-ne v0, v1, :return
     58 
     59    # Will throw NullPointerException if this branch is taken.
     60    const v1, 0x0
     61    const-string v2, "UTF8"
     62    invoke-direct {v0, v1, v2}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
     63    return-void
     64 
     65    :return
     66    return-void
     67 
     68 .end method
     69 
     70 # Test deoptimization between String's allocation and initialization. When not
     71 # compiling --debuggable, the NewInstance will be optimized out.
     72 
     73 ## CHECK-START: int TestCase.deoptimizeNewInstance(int[], byte[]) register (after)
     74 ## CHECK:         <<Null:l\d+>>   NullConstant
     75 ## CHECK:                         Deoptimize env:[[<<Null>>,{{.*]]}}
     76 ## CHECK:                         InvokeStaticOrDirect method_name:java.lang.String.<init>
     77 
     78 ## CHECK-START-DEBUGGABLE: int TestCase.deoptimizeNewInstance(int[], byte[]) register (after)
     79 ## CHECK:         <<String:l\d+>> NewInstance
     80 ## CHECK:                         Deoptimize env:[[<<String>>,{{.*]]}}
     81 ## CHECK:                         InvokeStaticOrDirect method_name:java.lang.String.<init>
     82 
     83 .method public static deoptimizeNewInstance([I[B)I
     84    .registers 6
     85 
     86    const v2, 0x0
     87    const v1, 0x1
     88 
     89    new-instance v0, Ljava/lang/String; # HNewInstance(String)
     90 
     91    # Deoptimize here if the array is too short.
     92    aget v1, p0, v1              # v1 = int_array[0x1]
     93    add-int/2addr v2, v1         # v2 = 0x0 + v1
     94 
     95    # Check that we're being executed by the interpreter.
     96    invoke-static {}, LMain;->assertIsInterpreted()V
     97 
     98    # String allocation should succeed.
     99    const-string v3, "UTF8"
    100    invoke-direct {v0, p1, v3}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    101    # Transformed into invoke StringFactory(p1,v3).
    102    # The use of v0 is dropped (so HNewInstance(String) ends up having 0 uses and is removed).
    103 
    104    # This ArrayGet will throw ArrayIndexOutOfBoundsException.
    105    const v1, 0x4
    106    aget v1, p0, v1
    107    add-int/2addr v2, v1
    108 
    109    return v2
    110 
    111 .end method
    112 
    113 # Test that a redundant NewInstance is removed if not used and not compiling
    114 # --debuggable.
    115 
    116 ## CHECK-START: java.lang.String TestCase.removeNewInstance(byte[]) register (after)
    117 ## CHECK-NOT:     NewInstance
    118 ## CHECK-NOT:     LoadClass
    119 
    120 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.removeNewInstance(byte[]) register (after)
    121 ## CHECK:         NewInstance
    122 
    123 .method public static removeNewInstance([B)Ljava/lang/String;
    124    .registers 5
    125 
    126    new-instance v0, Ljava/lang/String;
    127    const-string v1, "UTF8"
    128    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    129    return-object v0
    130    # Although it looks like we "use" the new-instance v0 here, the optimizing compiler
    131    # transforms all uses of the new-instance into uses of the StringFactory invoke.
    132    # therefore the HNewInstance for v0 becomes dead and is removed.
    133 
    134 .end method
    135 
    136 # Test that the compiler does not assume that the first argument of String.<init>
    137 # is a NewInstance by inserting an irreducible loop between them (b/26676472).
    138 
    139 # We verify the type of the input instruction (Phi) in debuggable mode, because
    140 # it is eliminated by later stages of SsaBuilder otherwise.
    141 
    142 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.thisNotNewInstance1(byte[], boolean) register (after)
    143 ## CHECK-DAG:                   InvokeStaticOrDirect env:[[<<Phi:l\d+>>,{{.*]]}}
    144 ## CHECK-DAG:     <<Phi>>       Phi
    145 
    146 .method public static thisNotNewInstance1([BZ)Ljava/lang/String;
    147    .registers 5
    148 
    149    new-instance v0, Ljava/lang/String;
    150 
    151    # Irreducible loop
    152    if-eqz p1, :loop_entry
    153    :loop_header
    154    const v1, 0x1
    155    xor-int p1, p1, v1
    156    :loop_entry
    157    if-eqz p1, :string_init
    158    goto :loop_header
    159 
    160    :string_init
    161    const-string v1, "UTF8"
    162    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    163    return-object v0
    164 
    165 .end method
    166 
    167 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.thisNotNewInstance2(byte[], boolean) register (after)
    168 ## CHECK-DAG:                   InvokeStaticOrDirect env:[[<<Phi:l\d+>>,{{.*]]}}
    169 ## CHECK-DAG:     <<Phi>>       Phi
    170 
    171 .method public static thisNotNewInstance2([BZ)Ljava/lang/String;
    172    .registers 5
    173 
    174    new-instance v0, Ljava/lang/String;
    175 
    176    # Irreducible loop
    177    if-eqz p1, :loop_entry
    178    :loop_header
    179    if-eqz p1, :string_init
    180    :loop_entry
    181    const v1, 0x1
    182    xor-int p1, p1, v1
    183    goto :loop_header
    184 
    185    :string_init
    186    const-string v1, "UTF8"
    187    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    188    return-object v0
    189 
    190 .end method
    191