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;
     90 
     91    # Deoptimize here if the array is too short.
     92    aget v1, p0, v1
     93    add-int/2addr v2, 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 
    102    # This ArrayGet will throw ArrayIndexOutOfBoundsException.
    103    const v1, 0x4
    104    aget v1, p0, v1
    105    add-int/2addr v2, v1
    106 
    107    return v2
    108 
    109 .end method
    110 
    111 # Test that a redundant NewInstance is removed if not used and not compiling
    112 # --debuggable.
    113 
    114 ## CHECK-START: java.lang.String TestCase.removeNewInstance(byte[]) register (after)
    115 ## CHECK-NOT:     NewInstance
    116 ## CHECK-NOT:     LoadClass
    117 
    118 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.removeNewInstance(byte[]) register (after)
    119 ## CHECK:         NewInstance
    120 
    121 .method public static removeNewInstance([B)Ljava/lang/String;
    122    .registers 5
    123 
    124    new-instance v0, Ljava/lang/String;
    125    const-string v1, "UTF8"
    126    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    127    return-object v0
    128 
    129 .end method
    130 
    131 # Test that the compiler does not assume that the first argument of String.<init>
    132 # is a NewInstance by inserting an irreducible loop between them (b/26676472).
    133 
    134 # We verify the type of the input instruction (Phi) in debuggable mode, because
    135 # it is eliminated by later stages of SsaBuilder otherwise.
    136 
    137 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.thisNotNewInstance1(byte[], boolean) register (after)
    138 ## CHECK-DAG:                   InvokeStaticOrDirect env:[[<<Phi:l\d+>>,{{.*]]}}
    139 ## CHECK-DAG:     <<Phi>>       Phi
    140 
    141 .method public static thisNotNewInstance1([BZ)Ljava/lang/String;
    142    .registers 5
    143 
    144    new-instance v0, Ljava/lang/String;
    145 
    146    # Irreducible loop
    147    if-eqz p1, :loop_entry
    148    :loop_header
    149    const v1, 0x1
    150    xor-int p1, p1, v1
    151    :loop_entry
    152    if-eqz p1, :string_init
    153    goto :loop_header
    154 
    155    :string_init
    156    const-string v1, "UTF8"
    157    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    158    return-object v0
    159 
    160 .end method
    161 
    162 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.thisNotNewInstance2(byte[], boolean) register (after)
    163 ## CHECK-DAG:                   InvokeStaticOrDirect env:[[<<Phi:l\d+>>,{{.*]]}}
    164 ## CHECK-DAG:     <<Phi>>       Phi
    165 
    166 .method public static thisNotNewInstance2([BZ)Ljava/lang/String;
    167    .registers 5
    168 
    169    new-instance v0, Ljava/lang/String;
    170 
    171    # Irreducible loop
    172    if-eqz p1, :loop_entry
    173    :loop_header
    174    if-eqz p1, :string_init
    175    :loop_entry
    176    const v1, 0x1
    177    xor-int p1, p1, v1
    178    goto :loop_header
    179 
    180    :string_init
    181    const-string v1, "UTF8"
    182    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    183    return-object v0
    184 
    185 .end method
    186