xref: /aosp_15_r20/art/test/478-checker-clinit-check-pruning/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker   /*
20*795d594fSAndroid Build Coastguard Worker    * Ensure an inlined static invoke explicitly triggers the
21*795d594fSAndroid Build Coastguard Worker    * initialization check of the called method's declaring class, and
22*795d594fSAndroid Build Coastguard Worker    * that the corresponding load class instruction does not get
23*795d594fSAndroid Build Coastguard Worker    * removed before register allocation & code generation.
24*795d594fSAndroid Build Coastguard Worker    */
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticInlined() builder (after)
27*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
28*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
29*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect [{{([ij]\d+,)?}}<<ClinitCheck>>]
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
32*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
33*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
36*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           InvokeStaticOrDirect
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker   // The following checks ensure the clinit check instruction added by
39*795d594fSAndroid Build Coastguard Worker   // the builder is pruned by the PrepareForRegisterAllocation, while
40*795d594fSAndroid Build Coastguard Worker   // the load class instruction is preserved.  As the control flow
41*795d594fSAndroid Build Coastguard Worker   // graph is not dumped after (nor before) this step, we check the
42*795d594fSAndroid Build Coastguard Worker   // CFG as it is before the next pass (liveness analysis) instead.
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
45*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass gen_clinit_check:true
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
48*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
49*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           InvokeStaticOrDirect
50*795d594fSAndroid Build Coastguard Worker 
invokeStaticInlined()51*795d594fSAndroid Build Coastguard Worker   static void invokeStaticInlined() {
52*795d594fSAndroid Build Coastguard Worker     ClassWithClinit1.$opt$inline$StaticMethod();
53*795d594fSAndroid Build Coastguard Worker   }
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit1 {
56*795d594fSAndroid Build Coastguard Worker     static {
57*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit1's static initializer");
58*795d594fSAndroid Build Coastguard Worker     }
59*795d594fSAndroid Build Coastguard Worker 
$opt$inline$StaticMethod()60*795d594fSAndroid Build Coastguard Worker     static void $opt$inline$StaticMethod() {
61*795d594fSAndroid Build Coastguard Worker     }
62*795d594fSAndroid Build Coastguard Worker   }
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker   /*
65*795d594fSAndroid Build Coastguard Worker    * Ensure a non-inlined static invoke eventually has an implicit
66*795d594fSAndroid Build Coastguard Worker    * initialization check of the called method's declaring class.
67*795d594fSAndroid Build Coastguard Worker    */
68*795d594fSAndroid Build Coastguard Worker 
69*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticNotInlined() builder (after)
70*795d594fSAndroid Build Coastguard Worker   /// CHECK:         <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
71*795d594fSAndroid Build Coastguard Worker   /// CHECK:         <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
72*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect [{{([ij]\d+,)?}}<<ClinitCheck>>]
73*795d594fSAndroid Build Coastguard Worker 
74*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticNotInlined() inliner (after)
75*795d594fSAndroid Build Coastguard Worker   /// CHECK:         <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
76*795d594fSAndroid Build Coastguard Worker   /// CHECK:         <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
77*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect [{{([ij]\d+,)?}}<<ClinitCheck>>]
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   // The following checks ensure the clinit check and load class
80*795d594fSAndroid Build Coastguard Worker   // instructions added by the builder are pruned by the
81*795d594fSAndroid Build Coastguard Worker   // PrepareForRegisterAllocation.  As the control flow graph is not
82*795d594fSAndroid Build Coastguard Worker   // dumped after (nor before) this step, we check the CFG as it is
83*795d594fSAndroid Build Coastguard Worker   // before the next pass (liveness analysis) instead.
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
86*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:implicit
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
89*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
90*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
91*795d594fSAndroid Build Coastguard Worker 
invokeStaticNotInlined()92*795d594fSAndroid Build Coastguard Worker   static void invokeStaticNotInlined() {
93*795d594fSAndroid Build Coastguard Worker     ClassWithClinit2.$noinline$staticMethod();
94*795d594fSAndroid Build Coastguard Worker   }
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit2 {
97*795d594fSAndroid Build Coastguard Worker     static {
98*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit2's static initializer");
99*795d594fSAndroid Build Coastguard Worker     }
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker     static boolean staticField = false;
102*795d594fSAndroid Build Coastguard Worker 
$noinline$staticMethod()103*795d594fSAndroid Build Coastguard Worker     static void $noinline$staticMethod() {
104*795d594fSAndroid Build Coastguard Worker     }
105*795d594fSAndroid Build Coastguard Worker   }
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   /*
108*795d594fSAndroid Build Coastguard Worker    * Ensure an inlined call from a static method to a static method
109*795d594fSAndroid Build Coastguard Worker    * of the same class does not require an explicit clinit check
110*795d594fSAndroid Build Coastguard Worker    * (already initialized or initializing in the same thread).
111*795d594fSAndroid Build Coastguard Worker    */
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit3Static.invokeStaticInlined() builder (after)
114*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit3Static.invokeStaticInlined() builder (after)
117*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
118*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
119*795d594fSAndroid Build Coastguard Worker 
120*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit3Static.invokeStaticInlined() inliner (after)
121*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
122*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
123*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           InvokeStaticOrDirect
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit3Static {
invokeStaticInlined()126*795d594fSAndroid Build Coastguard Worker     static void invokeStaticInlined() {
127*795d594fSAndroid Build Coastguard Worker       // The invocation of invokeStaticInlined happens only after a clinit check
128*795d594fSAndroid Build Coastguard Worker       // of ClassWithClinit3Static, meaning that the hereinbelow call to
129*795d594fSAndroid Build Coastguard Worker       // $opt$inline$StaticMethod does not need another clinit check.
130*795d594fSAndroid Build Coastguard Worker       $opt$inline$StaticMethod();
131*795d594fSAndroid Build Coastguard Worker     }
132*795d594fSAndroid Build Coastguard Worker 
133*795d594fSAndroid Build Coastguard Worker     static {
134*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit3Static's static initializer");
135*795d594fSAndroid Build Coastguard Worker     }
136*795d594fSAndroid Build Coastguard Worker 
$opt$inline$StaticMethod()137*795d594fSAndroid Build Coastguard Worker     static void $opt$inline$StaticMethod() {
138*795d594fSAndroid Build Coastguard Worker     }
139*795d594fSAndroid Build Coastguard Worker   }
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   /*
142*795d594fSAndroid Build Coastguard Worker    * Ensure an inlined call from an instance method to a static method
143*795d594fSAndroid Build Coastguard Worker    * of the same class actually requires an explicit clinit check when
144*795d594fSAndroid Build Coastguard Worker    * the class has a non-trivial initialization as we could be executing
145*795d594fSAndroid Build Coastguard Worker    * the instance method on an escaped object of an erroneous class. b/62478025
146*795d594fSAndroid Build Coastguard Worker    */
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit3Instance.invokeStaticInlined() builder (after)
149*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
150*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
151*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit3Instance.invokeStaticInlined() inliner (after)
154*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
155*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
156*795d594fSAndroid Build Coastguard Worker 
157*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit3Instance.invokeStaticInlined() inliner (after)
158*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           InvokeStaticOrDirect
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit3Instance {
invokeStaticInlined()161*795d594fSAndroid Build Coastguard Worker     void invokeStaticInlined() {
162*795d594fSAndroid Build Coastguard Worker       // ClinitCheck required.
163*795d594fSAndroid Build Coastguard Worker       $opt$inline$StaticMethod();
164*795d594fSAndroid Build Coastguard Worker     }
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker     static {
167*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit3Instance's static initializer");
168*795d594fSAndroid Build Coastguard Worker     }
169*795d594fSAndroid Build Coastguard Worker 
$opt$inline$StaticMethod()170*795d594fSAndroid Build Coastguard Worker     static void $opt$inline$StaticMethod() {
171*795d594fSAndroid Build Coastguard Worker     }
172*795d594fSAndroid Build Coastguard Worker   }
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker   /*
175*795d594fSAndroid Build Coastguard Worker    * Ensure a non-inlined call from a static method to a static method
176*795d594fSAndroid Build Coastguard Worker    * of the same class does not require an explicit clinit check
177*795d594fSAndroid Build Coastguard Worker    * (already initialized or initializing in the same thread).
178*795d594fSAndroid Build Coastguard Worker    */
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Static.invokeStaticNotInlined() builder (after)
181*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Static.invokeStaticNotInlined() builder (after)
184*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
185*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Static.invokeStaticNotInlined() inliner (after)
188*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Static.invokeStaticNotInlined() inliner (after)
191*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
192*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
193*795d594fSAndroid Build Coastguard Worker 
194*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit4Static {
invokeStaticNotInlined()195*795d594fSAndroid Build Coastguard Worker     static void invokeStaticNotInlined() {
196*795d594fSAndroid Build Coastguard Worker       // The invocation of invokeStaticNotInlined triggers the
197*795d594fSAndroid Build Coastguard Worker       // initialization of ClassWithClinit4Static, meaning that the
198*795d594fSAndroid Build Coastguard Worker       // call to staticMethod below does not need a clinit
199*795d594fSAndroid Build Coastguard Worker       // check.
200*795d594fSAndroid Build Coastguard Worker       $noinline$staticMethod();
201*795d594fSAndroid Build Coastguard Worker     }
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker     static {
204*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit4Static's static initializer");
205*795d594fSAndroid Build Coastguard Worker     }
206*795d594fSAndroid Build Coastguard Worker 
$noinline$staticMethod()207*795d594fSAndroid Build Coastguard Worker     static void $noinline$staticMethod() {
208*795d594fSAndroid Build Coastguard Worker     }
209*795d594fSAndroid Build Coastguard Worker   }
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker   /*
212*795d594fSAndroid Build Coastguard Worker    * Ensure a non-inlined call from an instance method to a static method
213*795d594fSAndroid Build Coastguard Worker    * of the same class actually requires an explicit clinit check when
214*795d594fSAndroid Build Coastguard Worker    * the class has a non-trivial initialization as we could be executing
215*795d594fSAndroid Build Coastguard Worker    * the instance method on an escaped object of an erroneous class. b/62478025
216*795d594fSAndroid Build Coastguard Worker    */
217*795d594fSAndroid Build Coastguard Worker 
218*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Instance.invokeStaticNotInlined() builder (after)
219*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
220*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
221*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Instance.invokeStaticNotInlined() inliner (after)
224*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
225*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
226*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
227*795d594fSAndroid Build Coastguard Worker 
228*795d594fSAndroid Build Coastguard Worker   // The following checks ensure the clinit check and load class
229*795d594fSAndroid Build Coastguard Worker   // instructions added by the builder are pruned by the
230*795d594fSAndroid Build Coastguard Worker   // PrepareForRegisterAllocation.  As the control flow graph is not
231*795d594fSAndroid Build Coastguard Worker   // dumped after (nor before) this step, we check the CFG as it is
232*795d594fSAndroid Build Coastguard Worker   // before the next pass (liveness analysis) instead.
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Instance.invokeStaticNotInlined() liveness (before)
235*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:implicit
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$ClassWithClinit4Instance.invokeStaticNotInlined() liveness (before)
238*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
239*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit4Instance {
invokeStaticNotInlined()242*795d594fSAndroid Build Coastguard Worker     void invokeStaticNotInlined() {
243*795d594fSAndroid Build Coastguard Worker       // ClinitCheck required.
244*795d594fSAndroid Build Coastguard Worker       $noinline$staticMethod();
245*795d594fSAndroid Build Coastguard Worker     }
246*795d594fSAndroid Build Coastguard Worker 
247*795d594fSAndroid Build Coastguard Worker     static {
248*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit4Instance's static initializer");
249*795d594fSAndroid Build Coastguard Worker     }
250*795d594fSAndroid Build Coastguard Worker 
$noinline$staticMethod()251*795d594fSAndroid Build Coastguard Worker     static void $noinline$staticMethod() {
252*795d594fSAndroid Build Coastguard Worker     }
253*795d594fSAndroid Build Coastguard Worker   }
254*795d594fSAndroid Build Coastguard Worker 
255*795d594fSAndroid Build Coastguard Worker   /*
256*795d594fSAndroid Build Coastguard Worker    * We used to remove clinit check for calls to static methods in a superclass. However, this
257*795d594fSAndroid Build Coastguard Worker    * is not a valid optimization when instances of erroneous classes can escape, therefore
258*795d594fSAndroid Build Coastguard Worker    * we avoid this optimization for classes with non-trivial initialization. b/62478025
259*795d594fSAndroid Build Coastguard Worker    */
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
262*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
263*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
264*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
265*795d594fSAndroid Build Coastguard Worker 
266*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() inliner (after)
267*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
268*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
269*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           InvokeStaticOrDirect
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit5 {
$opt$inline$StaticMethod()272*795d594fSAndroid Build Coastguard Worker     static void $opt$inline$StaticMethod() {
273*795d594fSAndroid Build Coastguard Worker     }
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker     static {
276*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit5's static initializer");
277*795d594fSAndroid Build Coastguard Worker     }
278*795d594fSAndroid Build Coastguard Worker   }
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker   static class SubClassOfClassWithClinit5 extends ClassWithClinit5 {
invokeStaticInlined()281*795d594fSAndroid Build Coastguard Worker     static void invokeStaticInlined() {
282*795d594fSAndroid Build Coastguard Worker       ClassWithClinit5.$opt$inline$StaticMethod();
283*795d594fSAndroid Build Coastguard Worker     }
284*795d594fSAndroid Build Coastguard Worker   }
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker   /*
287*795d594fSAndroid Build Coastguard Worker    * Ensure an inlined call to a static method whose declaring class is a super class
288*795d594fSAndroid Build Coastguard Worker    * of the caller's class does not require an explicit clinit check if the declaring
289*795d594fSAndroid Build Coastguard Worker    * class has a trivial initialization. b/62478025
290*795d594fSAndroid Build Coastguard Worker    */
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit5.invokeStaticInlined() builder (after)
293*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit5.invokeStaticInlined() builder (after)
296*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
297*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
298*795d594fSAndroid Build Coastguard Worker 
299*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit5.invokeStaticInlined() inliner (after)
300*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
301*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
302*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           InvokeStaticOrDirect
303*795d594fSAndroid Build Coastguard Worker 
304*795d594fSAndroid Build Coastguard Worker   static class ClassWithoutClinit5 {  // Mimicks ClassWithClinit5 but without the <clinit>.
$opt$inline$StaticMethod()305*795d594fSAndroid Build Coastguard Worker     static void $opt$inline$StaticMethod() {
306*795d594fSAndroid Build Coastguard Worker     }
307*795d594fSAndroid Build Coastguard Worker   }
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker   static class SubClassOfClassWithoutClinit5 extends ClassWithoutClinit5 {
310*795d594fSAndroid Build Coastguard Worker     static {
311*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$SubClassOfClassWithoutClinit5's static initializer");
312*795d594fSAndroid Build Coastguard Worker     }
313*795d594fSAndroid Build Coastguard Worker 
invokeStaticInlined()314*795d594fSAndroid Build Coastguard Worker     static void invokeStaticInlined() {
315*795d594fSAndroid Build Coastguard Worker       ClassWithoutClinit5.$opt$inline$StaticMethod();
316*795d594fSAndroid Build Coastguard Worker     }
317*795d594fSAndroid Build Coastguard Worker   }
318*795d594fSAndroid Build Coastguard Worker 
319*795d594fSAndroid Build Coastguard Worker   /*
320*795d594fSAndroid Build Coastguard Worker    * We used to remove clinit check for calls to static methods in a superclass. However, this
321*795d594fSAndroid Build Coastguard Worker    * is not a valid optimization when instances of erroneous classes can escape, therefore
322*795d594fSAndroid Build Coastguard Worker    * we avoid this optimization for classes with non-trivial initialization. b/62478025
323*795d594fSAndroid Build Coastguard Worker    */
324*795d594fSAndroid Build Coastguard Worker 
325*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
326*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
329*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
330*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
333*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           LoadClass
334*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           ClinitCheck
335*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
336*795d594fSAndroid Build Coastguard Worker 
337*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit6 {
$noinline$staticMethod()338*795d594fSAndroid Build Coastguard Worker     static void $noinline$staticMethod() {
339*795d594fSAndroid Build Coastguard Worker     }
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker     static {
342*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit6's static initializer");
343*795d594fSAndroid Build Coastguard Worker     }
344*795d594fSAndroid Build Coastguard Worker   }
345*795d594fSAndroid Build Coastguard Worker 
346*795d594fSAndroid Build Coastguard Worker   static class SubClassOfClassWithClinit6 extends ClassWithClinit6 {
invokeStaticNotInlined()347*795d594fSAndroid Build Coastguard Worker     static void invokeStaticNotInlined() {
348*795d594fSAndroid Build Coastguard Worker       ClassWithClinit6.$noinline$staticMethod();
349*795d594fSAndroid Build Coastguard Worker     }
350*795d594fSAndroid Build Coastguard Worker   }
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker   /*
353*795d594fSAndroid Build Coastguard Worker    * Ensure a non-inlined call to a static method whose declaring class is a super class
354*795d594fSAndroid Build Coastguard Worker    * of the caller's class does not require an explicit clinit check if the declaring
355*795d594fSAndroid Build Coastguard Worker    * class has a trivial initialization. b/62478025
356*795d594fSAndroid Build Coastguard Worker    */
357*795d594fSAndroid Build Coastguard Worker 
358*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit6.invokeStaticNotInlined() builder (after)
359*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
360*795d594fSAndroid Build Coastguard Worker 
361*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit6.invokeStaticNotInlined() builder (after)
362*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
363*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
364*795d594fSAndroid Build Coastguard Worker 
365*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit6.invokeStaticNotInlined() inliner (after)
366*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect
367*795d594fSAndroid Build Coastguard Worker 
368*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main$SubClassOfClassWithoutClinit6.invokeStaticNotInlined() inliner (after)
369*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           LoadClass
370*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
371*795d594fSAndroid Build Coastguard Worker 
372*795d594fSAndroid Build Coastguard Worker   static class ClassWithoutClinit6 {  // Mimicks ClassWithClinit6 but without the <clinit>.
$noinline$staticMethod()373*795d594fSAndroid Build Coastguard Worker     static void $noinline$staticMethod() {
374*795d594fSAndroid Build Coastguard Worker     }
375*795d594fSAndroid Build Coastguard Worker   }
376*795d594fSAndroid Build Coastguard Worker 
377*795d594fSAndroid Build Coastguard Worker   static class SubClassOfClassWithoutClinit6 extends ClassWithoutClinit6 {
378*795d594fSAndroid Build Coastguard Worker     static {
379*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$SubClassOfClassWithoutClinit6's static initializer");
380*795d594fSAndroid Build Coastguard Worker     }
381*795d594fSAndroid Build Coastguard Worker 
invokeStaticNotInlined()382*795d594fSAndroid Build Coastguard Worker     static void invokeStaticNotInlined() {
383*795d594fSAndroid Build Coastguard Worker       ClassWithoutClinit6.$noinline$staticMethod();
384*795d594fSAndroid Build Coastguard Worker     }
385*795d594fSAndroid Build Coastguard Worker   }
386*795d594fSAndroid Build Coastguard Worker 
387*795d594fSAndroid Build Coastguard Worker   /*
388*795d594fSAndroid Build Coastguard Worker    * Verify that if we have a static call immediately after the load class
389*795d594fSAndroid Build Coastguard Worker    * we don't do generate a clinit check.
390*795d594fSAndroid Build Coastguard Worker    */
391*795d594fSAndroid Build Coastguard Worker 
392*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
393*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<IntConstant:i\d+>>  IntConstant 0
394*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
395*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect clinit_check:implicit
396*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
397*795d594fSAndroid Build Coastguard Worker 
398*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
399*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
400*795d594fSAndroid Build Coastguard Worker 
noClinitBecauseOfInvokeStatic()401*795d594fSAndroid Build Coastguard Worker   static void noClinitBecauseOfInvokeStatic() {
402*795d594fSAndroid Build Coastguard Worker     ClassWithClinit2.$noinline$staticMethod();
403*795d594fSAndroid Build Coastguard Worker     ClassWithClinit2.staticField = false;
404*795d594fSAndroid Build Coastguard Worker   }
405*795d594fSAndroid Build Coastguard Worker 
406*795d594fSAndroid Build Coastguard Worker   /*
407*795d594fSAndroid Build Coastguard Worker    * Verify that if the static call is after a field access, the load class
408*795d594fSAndroid Build Coastguard Worker    * will generate a clinit check.
409*795d594fSAndroid Build Coastguard Worker    */
410*795d594fSAndroid Build Coastguard Worker 
411*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
412*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<IntConstant:i\d+>>  IntConstant 0
413*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:true
414*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
415*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                           InvokeStaticOrDirect clinit_check:none
416*795d594fSAndroid Build Coastguard Worker 
417*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
418*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
clinitBecauseOfFieldAccess()419*795d594fSAndroid Build Coastguard Worker   static void clinitBecauseOfFieldAccess() {
420*795d594fSAndroid Build Coastguard Worker     ClassWithClinit2.staticField = false;
421*795d594fSAndroid Build Coastguard Worker     ClassWithClinit2.$noinline$staticMethod();
422*795d594fSAndroid Build Coastguard Worker   }
423*795d594fSAndroid Build Coastguard Worker 
424*795d594fSAndroid Build Coastguard Worker   /*
425*795d594fSAndroid Build Coastguard Worker    * Verify that LoadClass from const-class is not merged with
426*795d594fSAndroid Build Coastguard Worker    * later invoke-static (or it's ClinitCheck).
427*795d594fSAndroid Build Coastguard Worker    */
428*795d594fSAndroid Build Coastguard Worker 
429*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.constClassAndInvokeStatic(java.lang.Iterable) liveness (before)
430*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               LoadClass gen_clinit_check:false
431*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:implicit
432*795d594fSAndroid Build Coastguard Worker 
433*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.constClassAndInvokeStatic(java.lang.Iterable) liveness (before)
434*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
435*795d594fSAndroid Build Coastguard Worker 
constClassAndInvokeStatic(Iterable<?> it)436*795d594fSAndroid Build Coastguard Worker   static void constClassAndInvokeStatic(Iterable<?> it) {
437*795d594fSAndroid Build Coastguard Worker     $opt$inline$ignoreClass(ClassWithClinit7.class);
438*795d594fSAndroid Build Coastguard Worker     ClassWithClinit7.$noinline$someStaticMethod(it);
439*795d594fSAndroid Build Coastguard Worker   }
440*795d594fSAndroid Build Coastguard Worker 
$opt$inline$ignoreClass(Class<?> c)441*795d594fSAndroid Build Coastguard Worker   static void $opt$inline$ignoreClass(Class<?> c) {
442*795d594fSAndroid Build Coastguard Worker   }
443*795d594fSAndroid Build Coastguard Worker 
444*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit7 {
445*795d594fSAndroid Build Coastguard Worker     static {
446*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit7's static initializer");
447*795d594fSAndroid Build Coastguard Worker     }
448*795d594fSAndroid Build Coastguard Worker 
$noinline$someStaticMethod(Iterable<?> it)449*795d594fSAndroid Build Coastguard Worker     static void $noinline$someStaticMethod(Iterable<?> it) {
450*795d594fSAndroid Build Coastguard Worker       it.iterator();
451*795d594fSAndroid Build Coastguard Worker     }
452*795d594fSAndroid Build Coastguard Worker   }
453*795d594fSAndroid Build Coastguard Worker 
454*795d594fSAndroid Build Coastguard Worker   /*
455*795d594fSAndroid Build Coastguard Worker    * Verify that LoadClass from sget is not merged with later invoke-static.
456*795d594fSAndroid Build Coastguard Worker    */
457*795d594fSAndroid Build Coastguard Worker 
458*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.sgetAndInvokeStatic(java.lang.Iterable) liveness (before)
459*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               LoadClass gen_clinit_check:true
460*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:none
461*795d594fSAndroid Build Coastguard Worker 
462*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.sgetAndInvokeStatic(java.lang.Iterable) liveness (before)
463*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
464*795d594fSAndroid Build Coastguard Worker 
sgetAndInvokeStatic(Iterable<?> it)465*795d594fSAndroid Build Coastguard Worker   static void sgetAndInvokeStatic(Iterable<?> it) {
466*795d594fSAndroid Build Coastguard Worker     $opt$inline$ignoreInt(ClassWithClinit8.value);
467*795d594fSAndroid Build Coastguard Worker     ClassWithClinit8.$noinline$someStaticMethod(it);
468*795d594fSAndroid Build Coastguard Worker   }
469*795d594fSAndroid Build Coastguard Worker 
$opt$inline$ignoreInt(int i)470*795d594fSAndroid Build Coastguard Worker   static void $opt$inline$ignoreInt(int i) {
471*795d594fSAndroid Build Coastguard Worker   }
472*795d594fSAndroid Build Coastguard Worker 
473*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit8 {
474*795d594fSAndroid Build Coastguard Worker     public static int value = 0;
475*795d594fSAndroid Build Coastguard Worker     static {
476*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit8's static initializer");
477*795d594fSAndroid Build Coastguard Worker     }
478*795d594fSAndroid Build Coastguard Worker 
$noinline$someStaticMethod(Iterable<?> it)479*795d594fSAndroid Build Coastguard Worker     static void $noinline$someStaticMethod(Iterable<?> it) {
480*795d594fSAndroid Build Coastguard Worker       it.iterator();
481*795d594fSAndroid Build Coastguard Worker     }
482*795d594fSAndroid Build Coastguard Worker   }
483*795d594fSAndroid Build Coastguard Worker 
484*795d594fSAndroid Build Coastguard Worker   /*
485*795d594fSAndroid Build Coastguard Worker    * Verify that LoadClass from const-class, ClinitCheck from sget and
486*795d594fSAndroid Build Coastguard Worker    * InvokeStaticOrDirect from invoke-static are not merged.
487*795d594fSAndroid Build Coastguard Worker    */
488*795d594fSAndroid Build Coastguard Worker 
489*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.constClassSgetAndInvokeStatic(java.lang.Iterable) liveness (before)
490*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               LoadClass gen_clinit_check:false
491*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               ClinitCheck
492*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:none
493*795d594fSAndroid Build Coastguard Worker 
constClassSgetAndInvokeStatic(Iterable<?> it)494*795d594fSAndroid Build Coastguard Worker   static void constClassSgetAndInvokeStatic(Iterable<?> it) {
495*795d594fSAndroid Build Coastguard Worker     $opt$inline$ignoreClass(ClassWithClinit9.class);
496*795d594fSAndroid Build Coastguard Worker     $opt$inline$ignoreInt(ClassWithClinit9.value);
497*795d594fSAndroid Build Coastguard Worker     ClassWithClinit9.$noinline$someStaticMethod(it);
498*795d594fSAndroid Build Coastguard Worker   }
499*795d594fSAndroid Build Coastguard Worker 
500*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit9 {
501*795d594fSAndroid Build Coastguard Worker     public static int value = 0;
502*795d594fSAndroid Build Coastguard Worker     static {
503*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit9's static initializer");
504*795d594fSAndroid Build Coastguard Worker     }
505*795d594fSAndroid Build Coastguard Worker 
$noinline$someStaticMethod(Iterable<?> it)506*795d594fSAndroid Build Coastguard Worker     static void $noinline$someStaticMethod(Iterable<?> it) {
507*795d594fSAndroid Build Coastguard Worker       it.iterator();
508*795d594fSAndroid Build Coastguard Worker     }
509*795d594fSAndroid Build Coastguard Worker   }
510*795d594fSAndroid Build Coastguard Worker 
511*795d594fSAndroid Build Coastguard Worker   /*
512*795d594fSAndroid Build Coastguard Worker    * Verify that LoadClass from a fully-inlined invoke-static is not merged
513*795d594fSAndroid Build Coastguard Worker    * with InvokeStaticOrDirect from a later invoke-static to the same method.
514*795d594fSAndroid Build Coastguard Worker    */
515*795d594fSAndroid Build Coastguard Worker 
516*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inlinedInvokeStaticViaNonStatic(java.lang.Iterable) liveness (before)
517*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               LoadClass gen_clinit_check:true
518*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:none
519*795d594fSAndroid Build Coastguard Worker 
520*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inlinedInvokeStaticViaNonStatic(java.lang.Iterable) liveness (before)
521*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
522*795d594fSAndroid Build Coastguard Worker 
inlinedInvokeStaticViaNonStatic(Iterable<?> it)523*795d594fSAndroid Build Coastguard Worker   static void inlinedInvokeStaticViaNonStatic(Iterable<?> it) {
524*795d594fSAndroid Build Coastguard Worker     if (it != null) {
525*795d594fSAndroid Build Coastguard Worker       inlinedInvokeStaticViaNonStaticHelper(null);
526*795d594fSAndroid Build Coastguard Worker       inlinedInvokeStaticViaNonStaticHelper(it);
527*795d594fSAndroid Build Coastguard Worker     }
528*795d594fSAndroid Build Coastguard Worker   }
529*795d594fSAndroid Build Coastguard Worker 
inlinedInvokeStaticViaNonStaticHelper(Iterable<?> it)530*795d594fSAndroid Build Coastguard Worker   static void inlinedInvokeStaticViaNonStaticHelper(Iterable<?> it) {
531*795d594fSAndroid Build Coastguard Worker     ClassWithClinit10.inlinedForNull(it);
532*795d594fSAndroid Build Coastguard Worker   }
533*795d594fSAndroid Build Coastguard Worker 
534*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit10 {
535*795d594fSAndroid Build Coastguard Worker     public static int value = 0;
536*795d594fSAndroid Build Coastguard Worker     static {
537*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit10's static initializer");
538*795d594fSAndroid Build Coastguard Worker     }
539*795d594fSAndroid Build Coastguard Worker 
inlinedForNull(Iterable<?> it)540*795d594fSAndroid Build Coastguard Worker     static void inlinedForNull(Iterable<?> it) {
541*795d594fSAndroid Build Coastguard Worker       if (it != null) {
542*795d594fSAndroid Build Coastguard Worker         it.iterator();
543*795d594fSAndroid Build Coastguard Worker         // We're not inlining methods that always throw.
544*795d594fSAndroid Build Coastguard Worker         throw new Error("");
545*795d594fSAndroid Build Coastguard Worker       }
546*795d594fSAndroid Build Coastguard Worker     }
547*795d594fSAndroid Build Coastguard Worker   }
548*795d594fSAndroid Build Coastguard Worker 
549*795d594fSAndroid Build Coastguard Worker   /*
550*795d594fSAndroid Build Coastguard Worker    * Check that the LoadClass from an invoke-static C.foo() doesn't get merged with
551*795d594fSAndroid Build Coastguard Worker    * an invoke-static inside C.foo(). This would mess up the stack walk in the
552*795d594fSAndroid Build Coastguard Worker    * resolution trampoline where we would have to load C (if C isn't loaded yet)
553*795d594fSAndroid Build Coastguard Worker    * which is not permitted there.
554*795d594fSAndroid Build Coastguard Worker    *
555*795d594fSAndroid Build Coastguard Worker    * Note: In case of failure, we would get an failed assertion during compilation,
556*795d594fSAndroid Build Coastguard Worker    * so we wouldn't really get to the checker tests below.
557*795d594fSAndroid Build Coastguard Worker    */
558*795d594fSAndroid Build Coastguard Worker 
559*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inlinedInvokeStaticViaStatic(java.lang.Iterable) liveness (before)
560*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               LoadClass gen_clinit_check:true
561*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:none
562*795d594fSAndroid Build Coastguard Worker 
563*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inlinedInvokeStaticViaStatic(java.lang.Iterable) liveness (before)
564*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
565*795d594fSAndroid Build Coastguard Worker 
inlinedInvokeStaticViaStatic(Iterable<?> it)566*795d594fSAndroid Build Coastguard Worker   static void inlinedInvokeStaticViaStatic(Iterable<?> it) {
567*795d594fSAndroid Build Coastguard Worker     if (it != null) {
568*795d594fSAndroid Build Coastguard Worker       ClassWithClinit11.callInlinedForNull(it);
569*795d594fSAndroid Build Coastguard Worker     }
570*795d594fSAndroid Build Coastguard Worker   }
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit11 {
573*795d594fSAndroid Build Coastguard Worker     public static int value = 0;
574*795d594fSAndroid Build Coastguard Worker     static {
575*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit11's static initializer");
576*795d594fSAndroid Build Coastguard Worker     }
577*795d594fSAndroid Build Coastguard Worker 
callInlinedForNull(Iterable<?> it)578*795d594fSAndroid Build Coastguard Worker     static void callInlinedForNull(Iterable<?> it) {
579*795d594fSAndroid Build Coastguard Worker       inlinedForNull(it);
580*795d594fSAndroid Build Coastguard Worker     }
581*795d594fSAndroid Build Coastguard Worker 
inlinedForNull(Iterable<?> it)582*795d594fSAndroid Build Coastguard Worker     static void inlinedForNull(Iterable<?> it) {
583*795d594fSAndroid Build Coastguard Worker       it.iterator();
584*795d594fSAndroid Build Coastguard Worker       if (it != null) {
585*795d594fSAndroid Build Coastguard Worker         // We're not inlining methods that always throw.
586*795d594fSAndroid Build Coastguard Worker         throw new Error("");
587*795d594fSAndroid Build Coastguard Worker       }
588*795d594fSAndroid Build Coastguard Worker     }
589*795d594fSAndroid Build Coastguard Worker   }
590*795d594fSAndroid Build Coastguard Worker 
591*795d594fSAndroid Build Coastguard Worker   /*
592*795d594fSAndroid Build Coastguard Worker    * A test similar to inlinedInvokeStaticViaStatic() but doing the indirect invoke
593*795d594fSAndroid Build Coastguard Worker    * twice with the first one to be fully inlined.
594*795d594fSAndroid Build Coastguard Worker    */
595*795d594fSAndroid Build Coastguard Worker 
596*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inlinedInvokeStaticViaStaticTwice(java.lang.Iterable) liveness (before)
597*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               LoadClass gen_clinit_check:true
598*795d594fSAndroid Build Coastguard Worker   /// CHECK:                               InvokeStaticOrDirect clinit_check:none
599*795d594fSAndroid Build Coastguard Worker 
600*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inlinedInvokeStaticViaStaticTwice(java.lang.Iterable) liveness (before)
601*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                           ClinitCheck
602*795d594fSAndroid Build Coastguard Worker 
inlinedInvokeStaticViaStaticTwice(Iterable<?> it)603*795d594fSAndroid Build Coastguard Worker   static void inlinedInvokeStaticViaStaticTwice(Iterable<?> it) {
604*795d594fSAndroid Build Coastguard Worker     if (it != null) {
605*795d594fSAndroid Build Coastguard Worker       ClassWithClinit12.callInlinedForNull(null);
606*795d594fSAndroid Build Coastguard Worker       ClassWithClinit12.callInlinedForNull(it);
607*795d594fSAndroid Build Coastguard Worker     }
608*795d594fSAndroid Build Coastguard Worker   }
609*795d594fSAndroid Build Coastguard Worker 
610*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit12 {
611*795d594fSAndroid Build Coastguard Worker     public static int value = 0;
612*795d594fSAndroid Build Coastguard Worker     static {
613*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit12's static initializer");
614*795d594fSAndroid Build Coastguard Worker     }
615*795d594fSAndroid Build Coastguard Worker 
callInlinedForNull(Iterable<?> it)616*795d594fSAndroid Build Coastguard Worker     static void callInlinedForNull(Iterable<?> it) {
617*795d594fSAndroid Build Coastguard Worker       inlinedForNull(it);
618*795d594fSAndroid Build Coastguard Worker     }
619*795d594fSAndroid Build Coastguard Worker 
inlinedForNull(Iterable<?> it)620*795d594fSAndroid Build Coastguard Worker     static void inlinedForNull(Iterable<?> it) {
621*795d594fSAndroid Build Coastguard Worker       if (it != null) {
622*795d594fSAndroid Build Coastguard Worker         // We're not inlining methods that always throw.
623*795d594fSAndroid Build Coastguard Worker         throw new Error("");
624*795d594fSAndroid Build Coastguard Worker       }
625*795d594fSAndroid Build Coastguard Worker     }
626*795d594fSAndroid Build Coastguard Worker   }
627*795d594fSAndroid Build Coastguard Worker 
628*795d594fSAndroid Build Coastguard Worker   static class ClassWithClinit13 {
629*795d594fSAndroid Build Coastguard Worker     static {
630*795d594fSAndroid Build Coastguard Worker       System.out.println("Main$ClassWithClinit13's static initializer");
631*795d594fSAndroid Build Coastguard Worker     }
632*795d594fSAndroid Build Coastguard Worker 
$inline$forwardToGetIterator(Iterable<?> it)633*795d594fSAndroid Build Coastguard Worker     public static void $inline$forwardToGetIterator(Iterable<?> it) {
634*795d594fSAndroid Build Coastguard Worker       $noinline$getIterator(it);
635*795d594fSAndroid Build Coastguard Worker     }
636*795d594fSAndroid Build Coastguard Worker 
$noinline$getIterator(Iterable<?> it)637*795d594fSAndroid Build Coastguard Worker     public static void $noinline$getIterator(Iterable<?> it) {
638*795d594fSAndroid Build Coastguard Worker       it.iterator();
639*795d594fSAndroid Build Coastguard Worker     }
640*795d594fSAndroid Build Coastguard Worker   }
641*795d594fSAndroid Build Coastguard Worker 
642*795d594fSAndroid Build Coastguard Worker   // TODO: Write checker statements.
$noinline$testInliningAndNewInstance(Iterable<?> it)643*795d594fSAndroid Build Coastguard Worker   static Object $noinline$testInliningAndNewInstance(Iterable<?> it) {
644*795d594fSAndroid Build Coastguard Worker     ClassWithClinit13.$inline$forwardToGetIterator(it);
645*795d594fSAndroid Build Coastguard Worker     return new ClassWithClinit13();
646*795d594fSAndroid Build Coastguard Worker   }
647*795d594fSAndroid Build Coastguard Worker 
648*795d594fSAndroid Build Coastguard Worker   // TODO: Add a test for the case of a static method whose declaring
649*795d594fSAndroid Build Coastguard Worker   // class type index is not available (i.e. when `storage_index`
650*795d594fSAndroid Build Coastguard Worker   // equals `dex::kDexNoIndex` in
651*795d594fSAndroid Build Coastguard Worker   // art::HGraphBuilder::BuildInvoke).
652*795d594fSAndroid Build Coastguard Worker 
main(String[] args)653*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
654*795d594fSAndroid Build Coastguard Worker     invokeStaticInlined();
655*795d594fSAndroid Build Coastguard Worker     invokeStaticNotInlined();
656*795d594fSAndroid Build Coastguard Worker     ClassWithClinit3Static.invokeStaticInlined();
657*795d594fSAndroid Build Coastguard Worker     new ClassWithClinit3Instance().invokeStaticInlined();
658*795d594fSAndroid Build Coastguard Worker     ClassWithClinit4Static.invokeStaticNotInlined();
659*795d594fSAndroid Build Coastguard Worker     new ClassWithClinit4Instance().invokeStaticNotInlined();
660*795d594fSAndroid Build Coastguard Worker     SubClassOfClassWithClinit5.invokeStaticInlined();
661*795d594fSAndroid Build Coastguard Worker     SubClassOfClassWithoutClinit5.invokeStaticInlined();
662*795d594fSAndroid Build Coastguard Worker     SubClassOfClassWithClinit6.invokeStaticNotInlined();
663*795d594fSAndroid Build Coastguard Worker     SubClassOfClassWithoutClinit6.invokeStaticNotInlined();
664*795d594fSAndroid Build Coastguard Worker     Iterable it = new Iterable() { public java.util.Iterator iterator() { return null; } };
665*795d594fSAndroid Build Coastguard Worker     constClassAndInvokeStatic(it);
666*795d594fSAndroid Build Coastguard Worker     sgetAndInvokeStatic(it);
667*795d594fSAndroid Build Coastguard Worker     constClassSgetAndInvokeStatic(it);
668*795d594fSAndroid Build Coastguard Worker     try {
669*795d594fSAndroid Build Coastguard Worker       inlinedInvokeStaticViaNonStatic(it);
670*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
671*795d594fSAndroid Build Coastguard Worker       // Expected
672*795d594fSAndroid Build Coastguard Worker     }
673*795d594fSAndroid Build Coastguard Worker     try {
674*795d594fSAndroid Build Coastguard Worker       inlinedInvokeStaticViaStatic(it);
675*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
676*795d594fSAndroid Build Coastguard Worker       // Expected
677*795d594fSAndroid Build Coastguard Worker     }
678*795d594fSAndroid Build Coastguard Worker     try{
679*795d594fSAndroid Build Coastguard Worker       inlinedInvokeStaticViaStaticTwice(it);
680*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
681*795d594fSAndroid Build Coastguard Worker       // Expected
682*795d594fSAndroid Build Coastguard Worker     }
683*795d594fSAndroid Build Coastguard Worker     $noinline$testInliningAndNewInstance(it);
684*795d594fSAndroid Build Coastguard Worker   }
685*795d594fSAndroid Build Coastguard Worker }
686