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