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