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