1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 public class Main { main(String[] args)18 public static void main(String[] args) { 19 System.out.println($opt$noinline$foo(new Main())); 20 System.out.println($opt$noinline$foo(new SubMain())); 21 System.out.println($opt$noinline$foo(new SubSubMain())); 22 } 23 24 25 // Checker test to make sure the only inlined instruction is 26 // SubMain.bar. 27 /// CHECK-START: int Main.$opt$noinline$foo(Main) inliner (after) 28 /// CHECK-DAG: InvokeVirtual method_name:Main.foo 29 /// CHECK-DAG: <<Const:i\d+>> IntConstant 3 30 /// CHECK: begin_block 31 /// CHECK: BoundType klass:SubMain 32 /// CHECK: Return [<<Const>>] 33 /// CHECK-NOT: begin_block 34 /// CHECK: end_block $opt$noinline$foo(Main o)35 public static int $opt$noinline$foo(Main o) { 36 if (doThrow) { throw new Error(); } 37 // To exercise the bug on Jack, we need two getClass compares. 38 if (o.getClass() == Main.class || o.getClass() != SubMain.class) { 39 return o.foo(); 40 } else { 41 // We used to wrongly bound the type of o to `Main` here and then realize that's 42 // impossible and mark this branch as dead. 43 return o.bar(); 44 } 45 } 46 bar()47 public int bar() { 48 return 1; 49 } 50 foo()51 public int foo() { 52 return 2; 53 } 54 55 public static boolean doThrow = false; 56 } 57 58 class SubMain extends Main { bar()59 public int bar() { 60 return 3; 61 } 62 foo()63 public int foo() { 64 return 4; 65 } 66 } 67 68 class SubSubMain extends SubMain { bar()69 public int bar() { 70 return 5; 71 } 72 foo()73 public int foo() { 74 return 6; 75 } 76 } 77