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
192b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static boolean doThrow = false;
202b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko
214c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
224c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure an inlined static invoke explicitly triggers the
234c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * initialization check of the called method's declaring class, and
244c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * that the corresponding load class instruction does not get
254c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * removed before register allocation & code generation.
264c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
274c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
28a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() builder (after)
29a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
30a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
3194015b939060f5041d408d48717f22443e55b6adNicolas Geoffray  /// CHECK-DAG:                           InvokeStaticOrDirect [{{[ij]\d+}},<<ClinitCheck>>]
324c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
33a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
34a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
35a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
364c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
37a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
38a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
394c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
404c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // The following checks ensure the clinit check instruction added by
414c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // the builder is pruned by the PrepareForRegisterAllocation, while
424c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // the load class instruction is preserved.  As the control flow
434c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // graph is not dumped after (nor before) this step, we check the
444c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // CFG as it is before the next pass (liveness analysis) instead.
454c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
46a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
47a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           LoadClass gen_clinit_check:true
484c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
49a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
50a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
51a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
524c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
534c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static void invokeStaticInlined() {
544c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    ClassWithClinit1.$opt$inline$StaticMethod();
554c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
564c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
574c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit1 {
584c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
594c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit1's static initializer");
604c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
614c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
624c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void $opt$inline$StaticMethod() {
634c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
644c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
654c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
664c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
674c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure a non-inlined static invoke eventually has an implicit
684c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * initialization check of the called method's declaring class.
694c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
704c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
71a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() builder (after)
72b554b5a5ae3cdc66969d61be20783a8af816206eVladimir Marko  /// CHECK:         <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
73b554b5a5ae3cdc66969d61be20783a8af816206eVladimir Marko  /// CHECK:         <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
74b554b5a5ae3cdc66969d61be20783a8af816206eVladimir Marko  /// CHECK:                               InvokeStaticOrDirect [{{[ij]\d+}},<<ClinitCheck>>]
754c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
76a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() inliner (after)
77b554b5a5ae3cdc66969d61be20783a8af816206eVladimir Marko  /// CHECK:         <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
78b554b5a5ae3cdc66969d61be20783a8af816206eVladimir Marko  /// CHECK:         <<ClinitCheck:l\d+>>  ClinitCheck [<<LoadClass>>]
79b554b5a5ae3cdc66969d61be20783a8af816206eVladimir Marko  /// CHECK:                               InvokeStaticOrDirect [{{([ij]\d+,)?}}<<ClinitCheck>>]
804c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
814c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // The following checks ensure the clinit check and load class
824c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // instructions added by the builder are pruned by the
834c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // PrepareForRegisterAllocation.  As the control flow graph is not
844c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // dumped after (nor before) this step, we check the CFG as it is
854c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // before the next pass (liveness analysis) instead.
864c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
87a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
88fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:implicit
894c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
90a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
91a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
92a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
934c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
944c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static void invokeStaticNotInlined() {
95e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    ClassWithClinit2.$noinline$staticMethod();
964c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
974c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
984c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit2 {
994c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
1004c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit2's static initializer");
1014c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1024c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1034c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static boolean doThrow = false;
1044c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
105e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    static void $noinline$staticMethod() {
1064c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      if (doThrow) {
1074c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        // Try defeating inlining.
1084c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        throw new Error();
1094c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      }
1104c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1114c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
1124c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1134c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
1144c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure an inlined call to a static method whose declaring class
1154c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * is statically known to have been initialized does not require an
1164c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * explicit clinit check.
1174c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
1184c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
119a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
120a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1214c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
122a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
123a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
124a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
1254c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
126a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() inliner (after)
127a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
128a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
129a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
1304c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1314c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit3 {
1324c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void invokeStaticInlined() {
1334c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // The invocation of invokeStaticInlined triggers the
1344c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // initialization of ClassWithClinit3, meaning that the
1354c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // hereinbelow call to $opt$inline$StaticMethod does not need a
1364c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // clinit check.
1374c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      $opt$inline$StaticMethod();
1384c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1394c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1404c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
1414c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit3's static initializer");
1424c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1434c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1444c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void $opt$inline$StaticMethod() {
1454c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1464c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
1474c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1484c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  /*
1494c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * Ensure an non-inlined call to a static method whose declaring
1504c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * class is statically known to have been initialized does not
1514c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   * require an explicit clinit check.
1524c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain   */
1534c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
154a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
155a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1564c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
157a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
158a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
159a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
1604c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
161a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
162a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1634c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
164a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
165a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
166a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
1674c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1684c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  static class ClassWithClinit4 {
1694c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static void invokeStaticNotInlined() {
1704c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // The invocation of invokeStaticNotInlined triggers the
1714c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // initialization of ClassWithClinit4, meaning that the
172d23eeef3492b53102eb8093524cf37e2b4c296dbNicolas Geoffray      // call to staticMethod below does not need a clinit
1734c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      // check.
174e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez      $noinline$staticMethod();
1754c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1764c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1774c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static {
1784c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      System.out.println("Main$ClassWithClinit4's static initializer");
1794c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1804c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1814c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    static boolean doThrow = false;
1824c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
183e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    static void $noinline$staticMethod() {
1844c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      if (doThrow) {
1854c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        // Try defeating inlining.
1864c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain        throw new Error();
1874c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain      }
1884c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    }
1894c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
1904c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
1915f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  /*
1925f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * Ensure an inlined call to a static method whose declaring class
1935f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * is a super class of the caller's class does not require an
1945f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * explicit clinit check.
1955f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   */
1965f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
197a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
198a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
1995f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
200a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
201a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
202a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2035f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
204a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() inliner (after)
205a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
206a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
207a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           InvokeStaticOrDirect
2085f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2095f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class ClassWithClinit5 {
2105f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static void $opt$inline$StaticMethod() {
2115f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2125f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2135f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static {
2145f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      System.out.println("Main$ClassWithClinit5's static initializer");
2155f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2165f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2175f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2185f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class SubClassOfClassWithClinit5 extends ClassWithClinit5 {
2195f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static void invokeStaticInlined() {
2205f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      ClassWithClinit5.$opt$inline$StaticMethod();
2215f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2225f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2235f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2245f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  /*
2255f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * Ensure an non-inlined call to a static method whose declaring
2265f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * class is a super class of the caller's class does not require an
2275f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   * explicit clinit check.
2285f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain   */
2295f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
230a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
231a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
2325f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
233a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
234a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
235a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2365f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
237a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
238a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           InvokeStaticOrDirect
2395f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
240a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
241a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           LoadClass
242a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2435f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2445f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class ClassWithClinit6 {
2455f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static boolean doThrow = false;
2465f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
247e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    static void $noinline$staticMethod() {
2485f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      if (doThrow) {
2495f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain        // Try defeating inlining.
2505f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain        throw new Error();
2515f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      }
2525f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2535f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2545f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static {
2555f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain      System.out.println("Main$ClassWithClinit6's static initializer");
2565f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2575f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2585f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2595f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  static class SubClassOfClassWithClinit6 extends ClassWithClinit6 {
2605f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    static void invokeStaticNotInlined() {
261e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez      ClassWithClinit6.$noinline$staticMethod();
2625f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    }
2635f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain  }
2645f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain
2650ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
2660ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  /*
2670ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * Verify that if we have a static call immediately after the load class
2680ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * we don't do generate a clinit check.
2690ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   */
2700ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
271a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
272a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<IntConstant:i\d+>>  IntConstant 0
273a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:false
274fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-DAG:                           InvokeStaticOrDirect clinit_check:implicit
275a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
2760ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
277a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
278a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2790ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
2800ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  static void noClinitBecauseOfInvokeStatic() {
281e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    ClassWithClinit2.$noinline$staticMethod();
2820ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle    ClassWithClinit2.doThrow = false;
2830ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  }
2840ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
2850ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  /*
2860ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * Verify that if the static call is after a field access, the load class
2870ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   * will generate a clinit check.
2880ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle   */
2890ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
290a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
291a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<IntConstant:i\d+>>  IntConstant 0
292a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:     <<LoadClass:l\d+>>    LoadClass gen_clinit_check:true
293a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-DAG:                           StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
294fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-DAG:                           InvokeStaticOrDirect clinit_check:none
2950ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
296a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
297a06d66a4ee60926127b9498b7ff0b3e37a24fccfDavid Brazdil  /// CHECK-NOT:                           ClinitCheck
2980ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  static void clinitBecauseOfFieldAccess() {
2990ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle    ClassWithClinit2.doThrow = false;
300e918d38535f210fe669eb3f18e7f286e5b687419Guillaume "Vermeille" Sanchez    ClassWithClinit2.$noinline$staticMethod();
3010ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle  }
3020ba218df92d2130295eccd2c564f8fdd2efc3a71Calin Juravle
303fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /*
304fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * Verify that LoadClass from const-class is not merged with
305fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * later invoke-static (or it's ClinitCheck).
306fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   */
307fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
308fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.constClassAndInvokeStatic(java.lang.Iterable) liveness (before)
309fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               LoadClass gen_clinit_check:false
310fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:implicit
311fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
312fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.constClassAndInvokeStatic(java.lang.Iterable) liveness (before)
313fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-NOT:                           ClinitCheck
314fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
3152b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void constClassAndInvokeStatic(Iterable<?> it) {
316fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    $opt$inline$ignoreClass(ClassWithClinit7.class);
317fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit7.someStaticMethod(it);
318fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
319fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
3202b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void $opt$inline$ignoreClass(Class<?> c) {
321fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
322fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
323fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static class ClassWithClinit7 {
324fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    static {
325fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      System.out.println("Main$ClassWithClinit7's static initializer");
326fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
327fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
328fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    // Note: not inlined from constClassAndInvokeStatic() but fully inlined from main().
3292b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void someStaticMethod(Iterable<?> it) {
330fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      // We're not inlining invoke-interface at the moment.
331fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      it.iterator();
332fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
333fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
334fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
335fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /*
336fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * Verify that LoadClass from sget is not merged with later invoke-static.
337fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   */
338fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
339fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.sgetAndInvokeStatic(java.lang.Iterable) liveness (before)
340fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               LoadClass gen_clinit_check:true
341fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:none
342fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
343fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.sgetAndInvokeStatic(java.lang.Iterable) liveness (before)
344fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-NOT:                           ClinitCheck
345fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
3462b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void sgetAndInvokeStatic(Iterable<?> it) {
347fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    $opt$inline$ignoreInt(ClassWithClinit8.value);
348fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit8.someStaticMethod(it);
349fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
350fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
351fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static void $opt$inline$ignoreInt(int i) {
352fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
353fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
354fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static class ClassWithClinit8 {
355fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    public static int value = 0;
356fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    static {
357fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      System.out.println("Main$ClassWithClinit8's static initializer");
358fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
359fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
360fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    // Note: not inlined from sgetAndInvokeStatic() but fully inlined from main().
3612b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void someStaticMethod(Iterable<?> it) {
362fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      // We're not inlining invoke-interface at the moment.
363fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      it.iterator();
364fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
365fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
366fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
367fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /*
368fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * Verify that LoadClass from const-class, ClinitCheck from sget and
369fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * InvokeStaticOrDirect from invoke-static are not merged.
370fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   */
371fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
372fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.constClassSgetAndInvokeStatic(java.lang.Iterable) liveness (before)
373fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               LoadClass gen_clinit_check:false
374fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               ClinitCheck
375fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:none
376fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
3772b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void constClassSgetAndInvokeStatic(Iterable<?> it) {
378fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    $opt$inline$ignoreClass(ClassWithClinit9.class);
379fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    $opt$inline$ignoreInt(ClassWithClinit9.value);
380fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit9.someStaticMethod(it);
381fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
382fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
383fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static class ClassWithClinit9 {
384fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    public static int value = 0;
385fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    static {
386fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      System.out.println("Main$ClassWithClinit9's static initializer");
387fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
388fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
389fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    // Note: not inlined from constClassSgetAndInvokeStatic() but fully inlined from main().
3902b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void someStaticMethod(Iterable<?> it) {
391fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      // We're not inlining invoke-interface at the moment.
392fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      it.iterator();
393fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
394fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
395fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
396fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /*
397fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * Verify that LoadClass from a fully-inlined invoke-static is not merged
398fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * with InvokeStaticOrDirect from a later invoke-static to the same method.
399fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   */
400fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
401fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.inlinedInvokeStaticViaNonStatic(java.lang.Iterable) liveness (before)
402fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               LoadClass gen_clinit_check:true
403fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:none
404fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
405fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.inlinedInvokeStaticViaNonStatic(java.lang.Iterable) liveness (before)
406fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-NOT:                           ClinitCheck
407fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4082b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void inlinedInvokeStaticViaNonStatic(Iterable<?> it) {
409fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    inlinedInvokeStaticViaNonStaticHelper(null);
410fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    inlinedInvokeStaticViaNonStaticHelper(it);
411fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
412fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4132b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void inlinedInvokeStaticViaNonStaticHelper(Iterable<?> it) {
414fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit10.inlinedForNull(it);
415fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
416fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
417fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static class ClassWithClinit10 {
418fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    public static int value = 0;
419fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    static {
420fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      System.out.println("Main$ClassWithClinit10's static initializer");
421fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
422fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4232b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void inlinedForNull(Iterable<?> it) {
424fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      if (it != null) {
425fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko        // We're not inlining invoke-interface at the moment.
426fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko        it.iterator();
427fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      }
428fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
429fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
430fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
431fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /*
432fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * Check that the LoadClass from an invoke-static C.foo() doesn't get merged with
433fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * an invoke-static inside C.foo(). This would mess up the stack walk in the
434fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * resolution trampoline where we would have to load C (if C isn't loaded yet)
435fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * which is not permitted there.
436fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   *
437fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * Note: In case of failure, we would get an failed assertion during compilation,
438fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * so we wouldn't really get to the checker tests below.
439fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   */
440fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
441fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.inlinedInvokeStaticViaStatic(java.lang.Iterable) liveness (before)
442fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               LoadClass gen_clinit_check:true
443fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:none
444fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
445fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.inlinedInvokeStaticViaStatic(java.lang.Iterable) liveness (before)
446fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-NOT:                           ClinitCheck
447fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4482b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void inlinedInvokeStaticViaStatic(Iterable<?> it) {
449fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit11.callInlinedForNull(it);
450fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
451fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
452fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static class ClassWithClinit11 {
453fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    public static int value = 0;
454fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    static {
455fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      System.out.println("Main$ClassWithClinit11's static initializer");
456fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
457fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4582b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void callInlinedForNull(Iterable<?> it) {
459fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      inlinedForNull(it);
460fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
461fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4622b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void inlinedForNull(Iterable<?> it) {
463fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      // We're not inlining invoke-interface at the moment.
464fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      it.iterator();
465fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
466fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
467fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
468fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /*
469fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * A test similar to inlinedInvokeStaticViaStatic() but doing the indirect invoke
470fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   * twice with the first one to be fully inlined.
471fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko   */
472fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
473fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.inlinedInvokeStaticViaStaticTwice(java.lang.Iterable) liveness (before)
474fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               LoadClass gen_clinit_check:true
475fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK:                               InvokeStaticOrDirect clinit_check:none
476fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
477fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-START: void Main.inlinedInvokeStaticViaStaticTwice(java.lang.Iterable) liveness (before)
478fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  /// CHECK-NOT:                           ClinitCheck
479fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4802b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static void inlinedInvokeStaticViaStaticTwice(Iterable<?> it) {
481fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit12.callInlinedForNull(null);
482fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    ClassWithClinit12.callInlinedForNull(it);
483fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
484fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
485fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  static class ClassWithClinit12 {
486fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    public static int value = 0;
487fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    static {
488fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      System.out.println("Main$ClassWithClinit12's static initializer");
489fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
490fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4912b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void callInlinedForNull(Iterable<?> it) {
492fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      inlinedForNull(it);
493fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
494fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
4952b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static void inlinedForNull(Iterable<?> it) {
496fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      if (it != null) {
497fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko        // We're not inlining invoke-interface at the moment.
498fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko        it.iterator();
499fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko      }
500fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    }
501fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko  }
502fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko
5032b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static class ClassWithClinit13 {
5042b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    static {
5052b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko      System.out.println("Main$ClassWithClinit13's static initializer");
5062b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    }
5072b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko
5082b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    public static void $inline$forwardToGetIterator(Iterable<?> it) {
5092b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko      $noinline$getIterator(it);
5102b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    }
5112b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko
5122b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    public static void $noinline$getIterator(Iterable<?> it) {
5132b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko      // We're not inlining invoke-interface at the moment.
5142b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko      it.iterator();
5152b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    }
5162b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  }
5172b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko
5182b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  // TODO: Write checker statements.
5192b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  static Object $noinline$testInliningAndNewInstance(Iterable<?> it) {
5202b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    if (doThrow) { throw new Error(); }
5212b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    ClassWithClinit13.$inline$forwardToGetIterator(it);
5222b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    return new ClassWithClinit13();
5232b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko  }
5242b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko
5254c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // TODO: Add a test for the case of a static method whose declaring
5264c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // class type index is not available (i.e. when `storage_index`
5274c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // equals `DexFile::kDexNoIndex` in
5284c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  // art::HGraphBuilder::BuildInvoke).
5294c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain
5304c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  public static void main(String[] args) {
5314c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    invokeStaticInlined();
5324c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    invokeStaticNotInlined();
5334c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    ClassWithClinit3.invokeStaticInlined();
5344c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain    ClassWithClinit4.invokeStaticNotInlined();
5355f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    SubClassOfClassWithClinit5.invokeStaticInlined();
5365f02c6caf9f38be49e655f8bdeeeb99b6faf9383Roland Levillain    SubClassOfClassWithClinit6.invokeStaticNotInlined();
537fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    Iterable it = new Iterable() { public java.util.Iterator iterator() { return null; } };
538fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    constClassAndInvokeStatic(it);
539fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    sgetAndInvokeStatic(it);
540fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    constClassSgetAndInvokeStatic(it);
541fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    inlinedInvokeStaticViaNonStatic(it);
542fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    inlinedInvokeStaticViaStatic(it);
543fbb184a1c6df22d9302b32b55206396c8278edcfVladimir Marko    inlinedInvokeStaticViaStaticTwice(it);
5442b8b6040d0d34f40e3db71f0e4b1c369fd1f02c6Vladimir Marko    $noinline$testInliningAndNewInstance(it);
5454c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain  }
5464c0eb42259d790fddcd9978b66328dbb3ab65615Roland Levillain}
547