1 /* 2 * Copyright (C) 2015 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 // TODO: Add more tests after we can inline functions with calls. 18 19 class ClassWithoutFinals { 20 /// CHECK-START: void ClassWithoutFinals.<init>() inliner (after) 21 /// CHECK-NOT: ConstructorFence ClassWithoutFinals()22 public ClassWithoutFinals() {} 23 } 24 25 class ClassWithFinals { 26 public final int x; 27 public ClassWithFinals obj; 28 public static boolean doThrow = false; 29 ClassWithFinals(boolean cond)30 public ClassWithFinals(boolean cond) { 31 x = 1; 32 throw new RuntimeException(); 33 // should not inline this constructor 34 } 35 36 /// CHECK-START: void ClassWithFinals.<init>() inliner (after) 37 /// CHECK: ConstructorFence 38 /// CHECK-NOT: ConstructorFence 39 40 /* 41 * Check that the correct assembly instructions are selected for a Store/Store fence. 42 * 43 * - ARM variants: DMB ISHST (store-store fence for inner shareable domain) 44 * - Intel variants: no-op (store-store does not need a fence). 45 */ 46 47 /// CHECK-START-ARM64: void ClassWithFinals.<init>() disassembly (after) 48 /// CHECK: ConstructorFence 49 /// CHECK-NEXT: dmb ishst 50 51 /// CHECK-START-ARM: void ClassWithFinals.<init>() disassembly (after) 52 /// CHECK: ConstructorFence 53 /// CHECK-NEXT: dmb ishst 54 55 /// CHECK-START-X86_64: void ClassWithFinals.<init>() disassembly (after) 56 /// CHECK: ConstructorFence 57 /// CHECK-NOT: {{[slm]}}fence 58 59 /// CHECK-START-X86: void ClassWithFinals.<init>() disassembly (after) 60 /// CHECK: ConstructorFence 61 /// CHECK-NOT: {{[slm]}}fence ClassWithFinals()62 public ClassWithFinals() { 63 // Exactly one constructor barrier. 64 // Note: Do not store 0 as that can be eliminated together with the constructor 65 // barrier by the code pattern substitution in the inliner. 66 x = 1; 67 } 68 69 /// CHECK-START: void ClassWithFinals.<init>(int) inliner (after) 70 /// CHECK: <<This:l\d+>> ParameterValue 71 /// CHECK: <<NewInstance:l\d+>> NewInstance 72 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 73 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 74 /// CHECK-DAG: ConstructorFence [<<This>>] 75 /// CHECK-NOT: ConstructorFence ClassWithFinals(int x)76 public ClassWithFinals(int x) { 77 // This should have exactly three barriers: 78 // - one for the new-instance 79 // - one for the constructor 80 // - one for the `new` which should be inlined. 81 obj = new ClassWithFinals(); 82 this.x = x; 83 } 84 } 85 86 class InheritFromClassWithFinals extends ClassWithFinals { 87 /// CHECK-START: void InheritFromClassWithFinals.<init>() inliner (after) 88 /// CHECK: <<This:l\d+>> ParameterValue 89 /// CHECK: ConstructorFence [<<This>>] 90 /// CHECK-NOT: ConstructorFence 91 92 /// CHECK-START: void InheritFromClassWithFinals.<init>() inliner (after) 93 /// CHECK-NOT: InvokeStaticOrDirect InheritFromClassWithFinals()94 public InheritFromClassWithFinals() { 95 // Should inline the super constructor. 96 // 97 // Exactly one constructor barrier here. 98 } 99 100 /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) inliner (after) 101 /// CHECK: InvokeStaticOrDirect 102 103 /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) inliner (after) 104 /// CHECK-NOT: ConstructorFence InheritFromClassWithFinals(boolean cond)105 public InheritFromClassWithFinals(boolean cond) { 106 super(cond); 107 // should not inline the super constructor 108 } 109 110 /// CHECK-START: void InheritFromClassWithFinals.<init>(int) inliner (after) 111 /// CHECK: <<This:l\d+>> ParameterValue 112 /// CHECK-DAG: <<NewHere:l\d+>> NewInstance klass:InheritFromClassWithFinals 113 /// CHECK-DAG: ConstructorFence [<<This>>] 114 /// CHECK-DAG: ConstructorFence [<<NewHere>>] 115 /// CHECK-DAG: ConstructorFence [<<NewHere>>] 116 /// CHECK-NOT: ConstructorFence 117 118 /// CHECK-START: void InheritFromClassWithFinals.<init>(int) inliner (after) 119 /// CHECK-NOT: InvokeStaticOrDirect InheritFromClassWithFinals(int unused)120 public InheritFromClassWithFinals(int unused) { 121 // super(); // implicitly the first invoke in this constructor. 122 // Should inline the super constructor and insert a constructor fence there. 123 124 // Should inline the new instance call (barrier); and add another one 125 // because the superclass has finals. 126 new InheritFromClassWithFinals(); 127 } 128 } 129 130 class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals { 131 final int y; 132 133 /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() inliner (after) 134 /// CHECK: <<This:l\d+>> ParameterValue 135 /// CHECK: ConstructorFence [<<This>>] 136 /// CHECK: ConstructorFence [<<This>>] 137 /// CHECK-NOT: ConstructorFence 138 139 /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() inliner (after) 140 /// CHECK-NOT: InvokeStaticOrDirect HaveFinalsAndInheritFromClassWithFinals()141 public HaveFinalsAndInheritFromClassWithFinals() { 142 // Should inline the super constructor and keep the memory barrier. 143 y = 0; 144 } 145 146 /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) inliner (after) 147 /// CHECK: <<This:l\d+>> ParameterValue 148 /// CHECK: InvokeStaticOrDirect 149 /// CHECK: ConstructorFence [<<This>>] 150 /// CHECK-NOT: ConstructorFence HaveFinalsAndInheritFromClassWithFinals(boolean cond)151 public HaveFinalsAndInheritFromClassWithFinals(boolean cond) { 152 super(cond); 153 // should not inline the super constructor 154 y = 0; 155 } 156 157 /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) inliner (after) 158 /// CHECK: <<This:l\d+>> ParameterValue 159 /// CHECK-DAG: <<NewHF:l\d+>> NewInstance klass:HaveFinalsAndInheritFromClassWithFinals 160 /// CHECK-DAG: <<NewIF:l\d+>> NewInstance klass:InheritFromClassWithFinals 161 /// CHECK-DAG: ConstructorFence [<<This>>] 162 /// CHECK-DAG: ConstructorFence [<<NewHF>>] 163 /// CHECK-DAG: ConstructorFence [<<NewHF>>] 164 /// CHECK-DAG: ConstructorFence [<<NewHF>>] 165 /// CHECK-DAG: ConstructorFence [<<NewIF>>] 166 /// CHECK-DAG: ConstructorFence [<<NewIF>>] 167 /// CHECK-DAG: ConstructorFence [<<This>>] 168 /// CHECK-NOT: ConstructorFence 169 170 /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) inliner (after) 171 /// CHECK-NOT: InvokeStaticOrDirect HaveFinalsAndInheritFromClassWithFinals(int unused)172 public HaveFinalsAndInheritFromClassWithFinals(int unused) { 173 // super() 174 // -- Inlined super constructor, insert memory barrier here. 175 y = 0; 176 177 // Should inline new instance and keep both memory barriers. 178 // One more memory barrier for new-instance. 179 // (3 total for this new-instance #1) 180 new HaveFinalsAndInheritFromClassWithFinals(); 181 // Should inline new instance and have exactly one barrier. 182 // One more barrier for new-instance. 183 // (2 total for this new-instance #2) 184 new InheritFromClassWithFinals(); 185 186 // -- End of constructor, insert memory barrier here to freeze 'y'. 187 } 188 } 189 190 public class Main { 191 192 /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() inliner (after) 193 /// CHECK: InvokeStaticOrDirect 194 195 /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() inliner (after) 196 /// CHECK: <<NewInstance:l\d+>> NewInstance 197 /// CHECK: ConstructorFence [<<NewInstance>>] 198 /// CHECK-NOT: ConstructorFence noInlineNoConstructorBarrier()199 public static ClassWithFinals noInlineNoConstructorBarrier() { 200 // Exactly one barrier for the new-instance. 201 return new ClassWithFinals(false); 202 // should not inline the constructor 203 } 204 205 /// CHECK-START: void Main.inlineNew() inliner (after) 206 /// CHECK: <<NewInstance:l\d+>> NewInstance 207 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 208 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 209 /// CHECK-NOT: ConstructorFence 210 211 /// CHECK-START: void Main.inlineNew() inliner (after) 212 /// CHECK-NOT: InvokeStaticOrDirect inlineNew()213 public static void inlineNew() { 214 // Exactly 2 barriers. One for new-instance, one for constructor with finals. 215 new ClassWithFinals(); 216 } 217 218 /// CHECK-START: void Main.inlineNew1() inliner (after) 219 /// CHECK: <<NewInstance:l\d+>> NewInstance 220 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 221 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 222 /// CHECK-NOT: ConstructorFence 223 224 /// CHECK-START: void Main.inlineNew1() inliner (after) 225 /// CHECK-NOT: InvokeStaticOrDirect inlineNew1()226 public static void inlineNew1() { 227 new InheritFromClassWithFinals(); 228 } 229 230 /// CHECK-START: void Main.inlineNew2() inliner (after) 231 /// CHECK: <<NewInstance:l\d+>> NewInstance 232 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 233 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 234 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 235 /// CHECK-NOT: ConstructorFence 236 237 /// CHECK-START: void Main.inlineNew2() inliner (after) 238 /// CHECK-NOT: InvokeStaticOrDirect inlineNew2()239 public static void inlineNew2() { 240 new HaveFinalsAndInheritFromClassWithFinals(); 241 } 242 243 /// CHECK-START: void Main.inlineNew3() inliner (after) 244 /// CHECK: <<NewInstance:l\d+>> NewInstance 245 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 246 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 247 /// CHECK-DAG: ConstructorFence [<<NewInstance>>] 248 /// CHECK-NOT: ConstructorFence 249 /// CHECK: <<NewInstance2:l\d+>> NewInstance 250 /// CHECK-DAG: ConstructorFence [<<NewInstance2>>] 251 /// CHECK-DAG: ConstructorFence [<<NewInstance2>>] 252 /// CHECK-DAG: ConstructorFence [<<NewInstance2>>] 253 /// CHECK-NOT: ConstructorFence 254 255 /// CHECK-START: void Main.inlineNew3() inliner (after) 256 /// CHECK-NOT: InvokeStaticOrDirect inlineNew3()257 public static void inlineNew3() { 258 new HaveFinalsAndInheritFromClassWithFinals(); 259 new HaveFinalsAndInheritFromClassWithFinals(); 260 } 261 262 static int[] mCodePointsEmpty = new int[0]; 263 264 /// CHECK-START: void Main.testNewString() inliner (after) 265 /// CHECK-NOT: ConstructorFence 266 /// CHECK: InvokeStaticOrDirect method_load_kind:StringInit 267 /// CHECK-NOT: ConstructorFence 268 /// CHECK-NOT: InvokeStaticOrDirect testNewString()269 public static void testNewString() { 270 // Strings are special because of StringFactory hackeries. 271 // 272 // Assume they handle their own fencing internally in the StringFactory. 273 int[] codePoints = null; 274 String some_new_string = new String(mCodePointsEmpty, 0, 0); 275 } 276 main(String[] args)277 public static void main(String[] args) {} 278 } 279