1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker class SuperClass { 18*795d594fSAndroid Build Coastguard Worker } 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker class ChildClass extends SuperClass { 21*795d594fSAndroid Build Coastguard Worker } 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker public class Main { 24*795d594fSAndroid Build Coastguard Worker main(String[] args)25*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 26*795d594fSAndroid Build Coastguard Worker test1(); 27*795d594fSAndroid Build Coastguard Worker test2(); 28*795d594fSAndroid Build Coastguard Worker } 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.test1() builder (after) 31*795d594fSAndroid Build Coastguard Worker /// CHECK: BoundType klass:SuperClass can_be_null:false exact:false 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.test1() builder (after) 34*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundType klass:SuperClass can_be_null:false exact:true test1()35*795d594fSAndroid Build Coastguard Worker public static void test1() { 36*795d594fSAndroid Build Coastguard Worker Object obj = new ChildClass(); 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker // We need a fixed point iteration to hit the bogus type update 39*795d594fSAndroid Build Coastguard Worker // of 'obj' below, so create a loop that updates the type of 'obj'. 40*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < 1; i++) { 41*795d594fSAndroid Build Coastguard Worker obj = new Object(); 42*795d594fSAndroid Build Coastguard Worker } 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker if (obj instanceof SuperClass) { 45*795d594fSAndroid Build Coastguard Worker // We used to wrongly type obj as an exact SuperClass from this point, 46*795d594fSAndroid Build Coastguard Worker // meaning we were statically determining that the following instanceof 47*795d594fSAndroid Build Coastguard Worker // would always fail. 48*795d594fSAndroid Build Coastguard Worker if (!(obj instanceof ChildClass)) { 49*795d594fSAndroid Build Coastguard Worker throw new Error("Expected a ChildClass, got " + obj.getClass()); 50*795d594fSAndroid Build Coastguard Worker } 51*795d594fSAndroid Build Coastguard Worker } 52*795d594fSAndroid Build Coastguard Worker } 53*795d594fSAndroid Build Coastguard Worker 54*795d594fSAndroid Build Coastguard Worker /// CHECK-START-X86: boolean Main.$noinline$instanceOfString(java.lang.Object) disassembly (after) 55*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceOf check_kind:exact_check 56*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: {{.*fs:.*}} 57*795d594fSAndroid Build Coastguard Worker 58*795d594fSAndroid Build Coastguard Worker /// CHECK-START-X86_64: boolean Main.$noinline$instanceOfString(java.lang.Object) disassembly (after) 59*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceOf check_kind:exact_check 60*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: {{.*gs:.*}} 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker /// CHECK-START-{ARM,ARM64}: boolean Main.$noinline$instanceOfString(java.lang.Object) disassembly (after) 63*795d594fSAndroid Build Coastguard Worker /// CHECK: InstanceOf check_kind:exact_check 64*795d594fSAndroid Build Coastguard Worker // For ARM and ARM64, the marking register (r8 and x20, respectively) can be used in 65*795d594fSAndroid Build Coastguard Worker // non-CC configs for any other purpose, so we'd need a config-specific checker test. 66*795d594fSAndroid Build Coastguard Worker // TODO: Add the checks when we support config-specific tests. $noinline$instanceOfString(Object o)67*795d594fSAndroid Build Coastguard Worker public static boolean $noinline$instanceOfString(Object o) { 68*795d594fSAndroid Build Coastguard Worker // String is a final class, so `instanceof String` should use exact check. 69*795d594fSAndroid Build Coastguard Worker // String is in the boot image, so we should avoid read barriers. The presence 70*795d594fSAndroid Build Coastguard Worker // of the read barrier can be checked in the architecture-specific disassembly. 71*795d594fSAndroid Build Coastguard Worker return o instanceof String; 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker test2()74*795d594fSAndroid Build Coastguard Worker public static void test2() { 75*795d594fSAndroid Build Coastguard Worker if ($noinline$instanceOfString(new Object())) { 76*795d594fSAndroid Build Coastguard Worker throw new Error(); 77*795d594fSAndroid Build Coastguard Worker } 78*795d594fSAndroid Build Coastguard Worker if (!$noinline$instanceOfString(new String())) { 79*795d594fSAndroid Build Coastguard Worker throw new Error(); 80*795d594fSAndroid Build Coastguard Worker } 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker } 83