1 /* 2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8143628 27 * @summary Test unsafe access for $type$ 28 * 29 #if[JdkInternalMisc] 30 * @modules $module$/$package$:+open 31 #else[JdkInternalMisc] 32 * @modules $module$/$package$ 33 #end[JdkInternalMisc] 34 * @run testng/othervm -Diters=100 -Xint compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 35 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 36 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 37 * @run testng/othervm -Diters=20000 compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 38 */ 39 40 package compiler.unsafe; 41 42 import org.testng.annotations.Test; 43 44 import java.lang.reflect.Field; 45 46 import static org.testng.Assert.*; 47 48 public class $Qualifier$UnsafeAccessTest$Type$ { 49 static final int ITERS = Integer.getInteger("iters", 1); 50 static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); 51 52 static final $package$.Unsafe UNSAFE; 53 54 static final long V_OFFSET; 55 56 static final Object STATIC_V_BASE; 57 58 static final long STATIC_V_OFFSET; 59 60 static int ARRAY_OFFSET; 61 62 static int ARRAY_SHIFT; 63 64 static { 65 try { 66 Field f = $package$.Unsafe.class.getDeclaredField("theUnsafe"); 67 f.setAccessible(true); 68 UNSAFE = ($package$.Unsafe) f.get(null); 69 } catch (Exception e) { 70 throw new RuntimeException("Unable to get Unsafe instance.", e); 71 } 72 73 try { 74 Field staticVField = $Qualifier$UnsafeAccessTest$Type$.class.getDeclaredField("static_v"); 75 STATIC_V_BASE = UNSAFE.staticFieldBase(staticVField); 76 STATIC_V_OFFSET = UNSAFE.staticFieldOffset(staticVField); 77 } catch (Exception e) { 78 throw new RuntimeException(e); 79 } 80 81 try { 82 Field vField = $Qualifier$UnsafeAccessTest$Type$.class.getDeclaredField("v"); 83 V_OFFSET = UNSAFE.objectFieldOffset(vField); 84 } catch (Exception e) { 85 throw new RuntimeException(e); 86 } 87 88 ARRAY_OFFSET = UNSAFE.arrayBaseOffset($type$[].class); 89 int ascale = UNSAFE.arrayIndexScale($type$[].class); 90 ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); 91 } 92 93 static $type$ static_v; 94 95 $type$ v; 96 97 @Test 98 public void testFieldInstance() { 99 $Qualifier$UnsafeAccessTest$Type$ t = new $Qualifier$UnsafeAccessTest$Type$(); 100 for (int c = 0; c < ITERS; c++) { 101 testAccess(t, V_OFFSET); 102 } 103 } 104 105 @Test 106 public void testFieldStatic() { 107 for (int c = 0; c < ITERS; c++) { 108 testAccess(STATIC_V_BASE, STATIC_V_OFFSET); 109 } 110 } 111 112 @Test 113 public void testArray() { 114 $type$[] array = new $type$[10]; 115 for (int c = 0; c < ITERS; c++) { 116 for (int i = 0; i < array.length; i++) { 117 testAccess(array, (((long) i) << ARRAY_SHIFT) + ARRAY_OFFSET); 118 } 119 } 120 } 121 122 #if[!Object] 123 #if[!boolean] 124 @Test 125 public void testArrayOffHeap() { 126 int size = 10; 127 long address = UNSAFE.allocateMemory(size << ARRAY_SHIFT); 128 try { 129 for (int c = 0; c < ITERS; c++) { 130 for (int i = 0; i < size; i++) { 131 testAccess(null, (((long) i) << ARRAY_SHIFT) + address); 132 } 133 } 134 } finally { 135 UNSAFE.freeMemory(address); 136 } 137 } 138 139 @Test 140 public void testArrayOffHeapDirect() { 141 int size = 10; 142 long address = UNSAFE.allocateMemory(size << ARRAY_SHIFT); 143 try { 144 for (int c = 0; c < ITERS; c++) { 145 for (int i = 0; i < size; i++) { 146 testAccess((((long) i) << ARRAY_SHIFT) + address); 147 } 148 } 149 } finally { 150 UNSAFE.freeMemory(address); 151 } 152 } 153 #end[!boolean] 154 #end[!Object] 155 156 static void testAccess(Object base, long offset) { 157 // Plain 158 { 159 UNSAFE.put$Type$(base, offset, $value1$); 160 $type$ x = UNSAFE.get$Type$(base, offset); 161 assertEquals(x, $value1$, "set $type$ value"); 162 } 163 164 // Volatile 165 { 166 UNSAFE.put$Type$Volatile(base, offset, $value2$); 167 $type$ x = UNSAFE.get$Type$Volatile(base, offset); 168 assertEquals(x, $value2$, "putVolatile $type$ value"); 169 } 170 171 #if[!JdkInternalMisc] 172 #if[Ordered] 173 // Lazy 174 { 175 UNSAFE.putOrdered$Type$(base, offset, $value1$); 176 $type$ x = UNSAFE.get$Type$Volatile(base, offset); 177 assertEquals(x, $value1$, "putRelease $type$ value"); 178 } 179 #end[Ordered] 180 #end[!JdkInternalMisc] 181 182 #if[JdkInternalMisc] 183 // Lazy 184 { 185 UNSAFE.put$Type$Release(base, offset, $value1$); 186 $type$ x = UNSAFE.get$Type$Acquire(base, offset); 187 assertEquals(x, $value1$, "putRelease $type$ value"); 188 } 189 190 // Opaque 191 { 192 UNSAFE.put$Type$Opaque(base, offset, $value2$); 193 $type$ x = UNSAFE.get$Type$Opaque(base, offset); 194 assertEquals(x, $value2$, "putOpaque $type$ value"); 195 } 196 #end[JdkInternalMisc] 197 198 #if[JdkInternalMisc] 199 #if[Unaligned] 200 // Unaligned 201 { 202 UNSAFE.put$Type$Unaligned(base, offset, $value2$); 203 $type$ x = UNSAFE.get$Type$Unaligned(base, offset); 204 assertEquals(x, $value2$, "putUnaligned $type$ value"); 205 } 206 207 { 208 UNSAFE.put$Type$Unaligned(base, offset, $value1$, true); 209 $type$ x = UNSAFE.get$Type$Unaligned(base, offset, true); 210 assertEquals(x, $value1$, "putUnaligned big endian $type$ value"); 211 } 212 213 { 214 UNSAFE.put$Type$Unaligned(base, offset, $value2$, false); 215 $type$ x = UNSAFE.get$Type$Unaligned(base, offset, false); 216 assertEquals(x, $value2$, "putUnaligned little endian $type$ value"); 217 } 218 #end[Unaligned] 219 #end[JdkInternalMisc] 220 221 #if[CAS] 222 UNSAFE.put$Type$(base, offset, $value1$); 223 224 // Compare 225 { 226 #if[JdkInternalMisc] 227 boolean r = UNSAFE.compareAndSet$Type$(base, offset, $value1$, $value2$); 228 assertEquals(r, true, "success compareAndSet $type$"); 229 #else[JdkInternalMisc] 230 boolean r = UNSAFE.compareAndSwap$Type$(base, offset, $value1$, $value2$); 231 assertEquals(r, true, "success compareAndSwap $type$"); 232 #end[JdkInternalMisc] 233 $type$ x = UNSAFE.get$Type$(base, offset); 234 #if[JdkInternalMisc] 235 assertEquals(x, $value2$, "success compareAndSet $type$ value"); 236 #else[JdkInternalMisc] 237 assertEquals(x, $value2$, "success compareAndSwap $type$ value"); 238 #end[JdkInternalMisc] 239 } 240 241 { 242 #if[JdkInternalMisc] 243 boolean r = UNSAFE.compareAndSet$Type$(base, offset, $value1$, $value3$); 244 assertEquals(r, false, "failing compareAndSet $type$"); 245 #else[JdkInternalMisc] 246 boolean r = UNSAFE.compareAndSwap$Type$(base, offset, $value1$, $value3$); 247 assertEquals(r, false, "failing compareAndSwap $type$"); 248 #end[JdkInternalMisc] 249 $type$ x = UNSAFE.get$Type$(base, offset); 250 #if[JdkInternalMisc] 251 assertEquals(x, $value2$, "failing compareAndSet $type$ value"); 252 #else[JdkInternalMisc] 253 assertEquals(x, $value2$, "failing compareAndSwap $type$ value"); 254 #end[JdkInternalMisc] 255 } 256 257 #if[JdkInternalMisc] 258 // Advanced compare 259 { 260 $type$ r = UNSAFE.compareAndExchange$Type$(base, offset, $value2$, $value1$); 261 assertEquals(r, $value2$, "success compareAndExchange $type$"); 262 $type$ x = UNSAFE.get$Type$(base, offset); 263 assertEquals(x, $value1$, "success compareAndExchange $type$ value"); 264 } 265 266 { 267 $type$ r = UNSAFE.compareAndExchange$Type$(base, offset, $value2$, $value3$); 268 assertEquals(r, $value1$, "failing compareAndExchange $type$"); 269 $type$ x = UNSAFE.get$Type$(base, offset); 270 assertEquals(x, $value1$, "failing compareAndExchange $type$ value"); 271 } 272 273 { 274 $type$ r = UNSAFE.compareAndExchange$Type$Acquire(base, offset, $value1$, $value2$); 275 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); 276 $type$ x = UNSAFE.get$Type$(base, offset); 277 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); 278 } 279 280 { 281 $type$ r = UNSAFE.compareAndExchange$Type$Acquire(base, offset, $value1$, $value3$); 282 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); 283 $type$ x = UNSAFE.get$Type$(base, offset); 284 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); 285 } 286 287 { 288 $type$ r = UNSAFE.compareAndExchange$Type$Release(base, offset, $value2$, $value1$); 289 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); 290 $type$ x = UNSAFE.get$Type$(base, offset); 291 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); 292 } 293 294 { 295 $type$ r = UNSAFE.compareAndExchange$Type$Release(base, offset, $value2$, $value3$); 296 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); 297 $type$ x = UNSAFE.get$Type$(base, offset); 298 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); 299 } 300 301 { 302 boolean success = false; 303 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 304 success = UNSAFE.weakCompareAndSet$Type$Plain(base, offset, $value1$, $value2$); 305 } 306 assertEquals(success, true, "weakCompareAndSetPlain $type$"); 307 $type$ x = UNSAFE.get$Type$(base, offset); 308 assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); 309 } 310 311 { 312 boolean success = false; 313 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 314 success = UNSAFE.weakCompareAndSet$Type$Acquire(base, offset, $value2$, $value1$); 315 } 316 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 317 $type$ x = UNSAFE.get$Type$(base, offset); 318 assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); 319 } 320 321 { 322 boolean success = false; 323 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 324 success = UNSAFE.weakCompareAndSet$Type$Release(base, offset, $value1$, $value2$); 325 } 326 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 327 $type$ x = UNSAFE.get$Type$(base, offset); 328 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); 329 } 330 331 { 332 boolean success = false; 333 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 334 success = UNSAFE.weakCompareAndSet$Type$(base, offset, $value2$, $value1$); 335 } 336 assertEquals(success, true, "weakCompareAndSet $type$"); 337 $type$ x = UNSAFE.get$Type$(base, offset); 338 assertEquals(x, $value1$, "weakCompareAndSet $type$"); 339 } 340 341 #end[JdkInternalMisc] 342 UNSAFE.put$Type$(base, offset, $value2$); 343 344 // Compare set and get 345 { 346 $type$ o = UNSAFE.getAndSet$Type$(base, offset, $value1$); 347 assertEquals(o, $value2$, "getAndSet $type$"); 348 $type$ x = UNSAFE.get$Type$(base, offset); 349 assertEquals(x, $value1$, "getAndSet $type$ value"); 350 } 351 #end[CAS] 352 353 #if[AtomicAdd] 354 UNSAFE.put$Type$(base, offset, $value1$); 355 356 // get and add, add and get 357 { 358 $type$ o = UNSAFE.getAndAdd$Type$(base, offset, $value2$); 359 assertEquals(o, $value1$, "getAndAdd $type$"); 360 $type$ x = UNSAFE.get$Type$(base, offset); 361 assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$"); 362 } 363 #end[AtomicAdd] 364 } 365 366 #if[!Object] 367 #if[!boolean] 368 static void testAccess(long address) { 369 // Plain 370 { 371 UNSAFE.put$Type$(address, $value1$); 372 $type$ x = UNSAFE.get$Type$(address); 373 assertEquals(x, $value1$, "set $type$ value"); 374 } 375 } 376 #end[!boolean] 377 #end[!Object] 378 }