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+>>   NullConstant
     46 ## CHECK-DAG:     <<String:l\d+>> NewInstance
     47 ## CHECK-DAG:     <<Cond:z\d+>>   NotEqual [<<String>>,<<Null>>]
     48 ## CHECK-DAG:                     If [<<Cond>>]
     49 
     50 .method public static compareNewInstance()V
     51    .registers 3
     52 
     53    new-instance v0, Ljava/lang/String;
     54    if-nez v0, :return
     55 
     56    # Will throw NullPointerException if this branch is taken.
     57    const v1, 0x0
     58    const-string v2, "UTF8"
     59    invoke-direct {v0, v1, v2}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
     60    return-void
     61 
     62    :return
     63    return-void
     64 
     65 .end method
     66 
     67 # Test deoptimization between String's allocation and initialization. When not
     68 # compiling --debuggable, the NewInstance will be optimized out.
     69 
     70 ## CHECK-START: int TestCase.deoptimizeNewInstance(int[], byte[]) register (after)
     71 ## CHECK:         <<Null:l\d+>>   NullConstant
     72 ## CHECK:                         Deoptimize env:[[<<Null>>,{{.*]]}}
     73 ## CHECK:                         InvokeStaticOrDirect method_name:java.lang.String.<init>
     74 
     75 ## CHECK-START-DEBUGGABLE: int TestCase.deoptimizeNewInstance(int[], byte[]) register (after)
     76 ## CHECK:         <<String:l\d+>> NewInstance
     77 ## CHECK:                         Deoptimize env:[[<<String>>,{{.*]]}}
     78 ## CHECK:                         InvokeStaticOrDirect method_name:java.lang.String.<init>
     79 
     80 .method public static deoptimizeNewInstance([I[B)I
     81    .registers 6
     82 
     83    const v2, 0x0
     84    const v1, 0x1
     85 
     86    new-instance v0, Ljava/lang/String;
     87 
     88    # Deoptimize here if the array is too short.
     89    aget v1, p0, v1
     90    add-int/2addr v2, v1
     91 
     92    # Check that we're being executed by the interpreter.
     93    invoke-static {}, LMain;->assertIsInterpreted()V
     94 
     95    # String allocation should succeed.
     96    const-string v3, "UTF8"
     97    invoke-direct {v0, p1, v3}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
     98 
     99    # This ArrayGet will throw ArrayIndexOutOfBoundsException.
    100    const v1, 0x4
    101    aget v1, p0, v1
    102    add-int/2addr v2, v1
    103 
    104    return v2
    105 
    106 .end method
    107 
    108 # Test that a redundant NewInstance is removed if not used and not compiling
    109 # --debuggable.
    110 
    111 ## CHECK-START: java.lang.String TestCase.removeNewInstance(byte[]) register (after)
    112 ## CHECK-NOT:     NewInstance
    113 ## CHECK-NOT:     LoadClass
    114 
    115 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.removeNewInstance(byte[]) register (after)
    116 ## CHECK:         NewInstance
    117 
    118 .method public static removeNewInstance([B)Ljava/lang/String;
    119    .registers 5
    120 
    121    new-instance v0, Ljava/lang/String;
    122    const-string v1, "UTF8"
    123    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    124    return-object v0
    125 
    126 .end method
    127 
    128 # Test that the compiler does not assume that the first argument of String.<init>
    129 # is a NewInstance by inserting an irreducible loop between them (b/26676472).
    130 
    131 # We verify the type of the input instruction (Phi) in debuggable mode, because
    132 # it is eliminated by later stages of SsaBuilder otherwise.
    133 
    134 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.thisNotNewInstance1(byte[], boolean) register (after)
    135 ## CHECK-DAG:                   InvokeStaticOrDirect env:[[<<Phi:l\d+>>,{{.*]]}}
    136 ## CHECK-DAG:     <<Phi>>       Phi
    137 
    138 .method public static thisNotNewInstance1([BZ)Ljava/lang/String;
    139    .registers 5
    140 
    141    new-instance v0, Ljava/lang/String;
    142 
    143    # Irreducible loop
    144    if-eqz p1, :loop_entry
    145    :loop_header
    146    const v1, 0x1
    147    xor-int p1, p1, v1
    148    :loop_entry
    149    if-eqz p1, :string_init
    150    goto :loop_header
    151 
    152    :string_init
    153    const-string v1, "UTF8"
    154    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    155    return-object v0
    156 
    157 .end method
    158 
    159 ## CHECK-START-DEBUGGABLE: java.lang.String TestCase.thisNotNewInstance2(byte[], boolean) register (after)
    160 ## CHECK-DAG:                   InvokeStaticOrDirect env:[[<<Phi:l\d+>>,{{.*]]}}
    161 ## CHECK-DAG:     <<Phi>>       Phi
    162 
    163 .method public static thisNotNewInstance2([BZ)Ljava/lang/String;
    164    .registers 5
    165 
    166    new-instance v0, Ljava/lang/String;
    167 
    168    # Irreducible loop
    169    if-eqz p1, :loop_entry
    170    :loop_header
    171    if-eqz p1, :string_init
    172    :loop_entry
    173    const v1, 0x1
    174    xor-int p1, p1, v1
    175    goto :loop_header
    176 
    177    :string_init
    178    const-string v1, "UTF8"
    179    invoke-direct {v0, p0, v1}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    180    return-object v0
    181 
    182 .end method
    183