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