Main.java revision e918d38535f210fe669eb3f18e7f286e5b687419
14c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain/*
24c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * Copyright (C) 2015 The Android Open Source Project
34c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain *
44c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * Licensed under the Apache License, Version 2.0 (the "License");
54c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * you may not use this file except in compliance with the License.
64c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * You may obtain a copy of the License at
74c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain *
84c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain *      http://www.apache.org/licenses/LICENSE-2.0
94c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain *
104c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * Unless required by applicable law or agreed to in writing, software
114c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * distributed under the License is distributed on an "AS IS" BASIS,
124c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * See the License for the specific language governing permissions and
144c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain * limitations under the License.
154c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain */
164c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
174c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillainpublic class Main {
184c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
194c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
204c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure an inlined static invoke explicitly triggers the
214c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * initialization check of the called method's declaring class, and
224c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * that the corresponding load class instruction does not get
234c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * removed before register allocation & code generation.
244c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
254c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
26a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() builder (after)
27a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
28a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
29a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect [<<ClinitCheck>>]
304c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
31a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
32a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
33a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
344c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
35a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
36a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
374c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
384c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // The following checks ensure the clinit check instruction added by
394c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // the builder is pruned by the PrepareForRegisterAllocation, while
404c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // the load class instruction is preserved.  As the control flow
414c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // graph is not dumped after (nor before) this step, we check the
424c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // CFG as it is before the next pass (liveness analysis) instead.
434c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
44a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
45a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           LoadClass gen_clinit_check:true
464c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
47a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
48a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
49a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
504c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
514c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static void invokeStaticInlined() {
524c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    ClassWithClinit1.$opt$inline$StaticMethod();
534c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
544c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
554c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit1 {
564c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
574c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit1's static initializer");
584c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
594c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
604c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void $opt$inline$StaticMethod() {
614c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
624c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
634c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
644c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
654c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure a non-inlined static invoke eventually has an implicit
664c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * initialization check of the called method's declaring class.
674c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
684c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
69a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() builder (after)
70a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
71a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
72a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect [<<ClinitCheck>>]
734c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
74a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() inliner (after)
75a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
76a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
77a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect [<<ClinitCheck>>]
784c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
794c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // The following checks ensure the clinit check and load class
804c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // instructions added by the builder are pruned by the
814c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // PrepareForRegisterAllocation.  As the control flow graph is not
824c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // dumped after (nor before) this step, we check the CFG as it is
834c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // before the next pass (liveness analysis) instead.
844c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
85a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
86a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
874c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
88a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
89a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
90a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
914c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
924c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static void invokeStaticNotInlined() {
93e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    ClassWithClinit2.$noinline$staticMethod();
944c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
954c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
964c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit2 {
974c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
984c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit2's static initializer");
994c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1004c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1014c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static boolean doThrow = false;
1024c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
103e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    static void $noinline$staticMethod() {
1044c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      if (doThrow) {
1054c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        // Try defeating inlining.
1064c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        throw new Error();
1074c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      }
1084c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1094c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
1104c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1114c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
1124c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure an inlined call to a static method whose declaring class
1134c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * is statically known to have been initialized does not require an
1144c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * explicit clinit check.
1154c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
1164c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
117a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
118a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1194c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
120a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
121a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
122a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
1234c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
124a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() inliner (after)
125a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
126a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
127a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
1284c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1294c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit3 {
1304c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void invokeStaticInlined() {
1314c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // The invocation of invokeStaticInlined triggers the
1324c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // initialization of ClassWithClinit3, meaning that the
1334c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // hereinbelow call to $opt$inline$StaticMethod does not need a
1344c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // clinit check.
1354c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      $opt$inline$StaticMethod();
1364c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1374c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1384c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
1394c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit3's static initializer");
1404c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1414c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1424c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void $opt$inline$StaticMethod() {
1434c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1444c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
1454c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1464c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
1474c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure an non-inlined call to a static method whose declaring
1484c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * class is statically known to have been initialized does not
1494c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * require an explicit clinit check.
1504c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
1514c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
152a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
153a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1544c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
155a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
156a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
157a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
1584c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
159a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
160a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1614c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
162a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
163a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
164a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
1654c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1664c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit4 {
1674c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void invokeStaticNotInlined() {
1684c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // The invocation of invokeStaticNotInlined triggers the
1694c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // initialization of ClassWithClinit4, meaning that the
170d23eeef3492b53102eb8093524cf37e2b4c296dbNicolas Geoffray      // call to staticMethod below does not need a clinit
1714c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // check.
172e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez      $noinline$staticMethod();
1734c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1744c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1754c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
1764c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit4's static initializer");
1774c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1784c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1794c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static boolean doThrow = false;
1804c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
181e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    static void $noinline$staticMethod() {
1824c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      if (doThrow) {
1834c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        // Try defeating inlining.
1844c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        throw new Error();
1854c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      }
1864c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1874c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
1884c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1895f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  /*
1905f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * Ensure an inlined call to a static method whose declaring class
1915f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * is a super class of the caller's class does not require an
1925f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * explicit clinit check.
1935f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   */
1945f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
195a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
196a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1975f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
198a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
199a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
200a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2015f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
202a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() inliner (after)
203a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
204a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
205a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
2065f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2075f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class ClassWithClinit5 {
2085f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static void $opt$inline$StaticMethod() {
2095f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2105f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2115f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static {
2125f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      System.out.println("Main$ClassWithClinit5's static initializer");
2135f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2145f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2155f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2165f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class SubClassOfClassWithClinit5 extends ClassWithClinit5 {
2175f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static void invokeStaticInlined() {
2185f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      ClassWithClinit5.$opt$inline$StaticMethod();
2195f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2205f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2215f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2225f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  /*
2235f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * Ensure an non-inlined call to a static method whose declaring
2245f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * class is a super class of the caller's class does not require an
2255f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * explicit clinit check.
2265f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   */
2275f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
228a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
229a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
2305f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
231a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
232a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
233a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2345f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
235a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
236a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
2375f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
238a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
239a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
240a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2415f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2425f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class ClassWithClinit6 {
2435f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static boolean doThrow = false;
2445f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
245e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    static void $noinline$staticMethod() {
2465f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      if (doThrow) {
2475f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain        // Try defeating inlining.
2485f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain        throw new Error();
2495f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      }
2505f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2515f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2525f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static {
2535f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      System.out.println("Main$ClassWithClinit6's static initializer");
2545f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2555f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2565f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2575f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class SubClassOfClassWithClinit6 extends ClassWithClinit6 {
2585f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static void invokeStaticNotInlined() {
259e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez      ClassWithClinit6.$noinline$staticMethod();
2605f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2615f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2625f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2630ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
2640ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  /*
2650ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * Verify that if we have a static call immediately after the load class
2660ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * we don't do generate a clinit check.
2670ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   */
2680ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
269a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
270a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<IntConstant:i\d+>>  IntConstant 0
271a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
272a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
273a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
2740ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
275a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
276a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2770ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
2780ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  static void noClinitBecauseOfInvokeStatic() {
279e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    ClassWithClinit2.$noinline$staticMethod();
2800ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle    ClassWithClinit2.doThrow = false;
2810ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  }
2820ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
2830ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  /*
2840ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * Verify that if the static call is after a field access, the load class
2850ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * will generate a clinit check.
2860ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   */
2870ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
288a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
289a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<IntConstant:i\d+>>  IntConstant 0
290a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:true
291a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
292a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
2930ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
294a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
295a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2960ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  static void clinitBecauseOfFieldAccess() {
2970ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle    ClassWithClinit2.doThrow = false;
298e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    ClassWithClinit2.$noinline$staticMethod();
2990ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  }
3000ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
3014c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // TODO: Add a test for the case of a static method whose declaring
3024c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // class type index is not available (i.e. when `storage_index`
3034c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // equals `DexFile::kDexNoIndex` in
3044c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // art::HGraphBuilder::BuildInvoke).
3054c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
3064c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  public static void main(String[] args) {
3074c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    invokeStaticInlined();
3084c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    invokeStaticNotInlined();
3094c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    ClassWithClinit3.invokeStaticInlined();
3104c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    ClassWithClinit4.invokeStaticNotInlined();
3115f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    SubClassOfClassWithClinit5.invokeStaticInlined();
3125f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    SubClassOfClassWithClinit6.invokeStaticNotInlined();
3134c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
3144c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain}
315