1 /* 2 * Copyright (c) 2015, 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 * @modules $module$/$package$ 30 * @run testng/othervm -Diters=100 -Xint compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 31 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 32 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 33 * @run testng/othervm -Diters=20000 compiler.unsafe.$Qualifier$UnsafeAccessTest$Type$ 34 */ 35 36 package compiler.unsafe; 37 38 import org.testng.annotations.Test; 39 40 import java.lang.reflect.Field; 41 42 import static org.testng.Assert.*; 43 44 public class $Qualifier$UnsafeAccessTest$Type$ { 45 static final int ITERS = Integer.getInteger("iters", 1); 46 static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); 47 48 static final $package$.Unsafe UNSAFE; 49 50 static final long V_OFFSET; 51 52 static final Object STATIC_V_BASE; 53 54 static final long STATIC_V_OFFSET; 55 56 static int ARRAY_OFFSET; 57 58 static int ARRAY_SHIFT; 59 60 static { 61 try { 62 Field f = $package$.Unsafe.class.getDeclaredField("theUnsafe"); 63 f.setAccessible(true); 64 UNSAFE = ($package$.Unsafe) f.get(null); 65 } catch (Exception e) { 66 throw new RuntimeException("Unable to get Unsafe instance.", e); 67 } 68 69 try { 70 Field staticVField = $Qualifier$UnsafeAccessTest$Type$.class.getDeclaredField("static_v"); 71 STATIC_V_BASE = UNSAFE.staticFieldBase(staticVField); 72 STATIC_V_OFFSET = UNSAFE.staticFieldOffset(staticVField); 73 } catch (Exception e) { 74 throw new RuntimeException(e); 75 } 76 77 try { 78 Field vField = $Qualifier$UnsafeAccessTest$Type$.class.getDeclaredField("v"); 79 V_OFFSET = UNSAFE.objectFieldOffset(vField); 80 } catch (Exception e) { 81 throw new RuntimeException(e); 82 } 83 84 ARRAY_OFFSET = UNSAFE.arrayBaseOffset($type$[].class); 85 int ascale = UNSAFE.arrayIndexScale($type$[].class); 86 ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); 87 } 88 89 static $type$ static_v; 90 91 $type$ v; 92 93 @Test 94 public void testFieldInstance() { 95 $Qualifier$UnsafeAccessTest$Type$ t = new $Qualifier$UnsafeAccessTest$Type$(); 96 for (int c = 0; c < ITERS; c++) { 97 testAccess(t, V_OFFSET); 98 } 99 } 100 101 @Test 102 public void testFieldStatic() { 103 for (int c = 0; c < ITERS; c++) { 104 testAccess(STATIC_V_BASE, STATIC_V_OFFSET); 105 } 106 } 107 108 @Test 109 public void testArray() { 110 $type$[] array = new $type$[10]; 111 for (int c = 0; c < ITERS; c++) { 112 for (int i = 0; i < array.length; i++) { 113 testAccess(array, (((long) i) << ARRAY_SHIFT) + ARRAY_OFFSET); 114 } 115 } 116 } 117 118 #if[!Object] 119 #if[!boolean] 120 @Test 121 public void testArrayOffHeap() { 122 int size = 10; 123 long address = UNSAFE.allocateMemory(size << ARRAY_SHIFT); 124 try { 125 for (int c = 0; c < ITERS; c++) { 126 for (int i = 0; i < size; i++) { 127 testAccess(null, (((long) i) << ARRAY_SHIFT) + address); 128 } 129 } 130 } finally { 131 UNSAFE.freeMemory(address); 132 } 133 } 134 135 @Test 136 public void testArrayOffHeapDirect() { 137 int size = 10; 138 long address = UNSAFE.allocateMemory(size << ARRAY_SHIFT); 139 try { 140 for (int c = 0; c < ITERS; c++) { 141 for (int i = 0; i < size; i++) { 142 testAccess((((long) i) << ARRAY_SHIFT) + address); 143 } 144 } 145 } finally { 146 UNSAFE.freeMemory(address); 147 } 148 } 149 #end[!boolean] 150 #end[!Object] 151 152 static void testAccess(Object base, long offset) { 153 // Plain 154 { 155 UNSAFE.put$Type$(base, offset, $value1$); 156 $type$ x = UNSAFE.get$Type$(base, offset); 157 assertEquals(x, $value1$, "set $type$ value"); 158 } 159 160 // Volatile 161 { 162 UNSAFE.put$Type$Volatile(base, offset, $value2$); 163 $type$ x = UNSAFE.get$Type$Volatile(base, offset); 164 assertEquals(x, $value2$, "putVolatile $type$ value"); 165 } 166 167 #if[!JdkInternalMisc] 168 #if[Ordered] 169 // Lazy 170 { 171 UNSAFE.putOrdered$Type$(base, offset, $value1$); 172 $type$ x = UNSAFE.get$Type$Volatile(base, offset); 173 assertEquals(x, $value1$, "putRelease $type$ value"); 174 } 175 #end[Ordered] 176 #end[!JdkInternalMisc] 177 178 #if[JdkInternalMisc] 179 // Lazy 180 { 181 UNSAFE.put$Type$Release(base, offset, $value1$); 182 $type$ x = UNSAFE.get$Type$Acquire(base, offset); 183 assertEquals(x, $value1$, "putRelease $type$ value"); 184 } 185 186 // Opaque 187 { 188 UNSAFE.put$Type$Opaque(base, offset, $value2$); 189 $type$ x = UNSAFE.get$Type$Opaque(base, offset); 190 assertEquals(x, $value2$, "putOpaque $type$ value"); 191 } 192 #end[JdkInternalMisc] 193 194 #if[JdkInternalMisc] 195 #if[Unaligned] 196 // Unaligned 197 { 198 UNSAFE.put$Type$Unaligned(base, offset, $value2$); 199 $type$ x = UNSAFE.get$Type$Unaligned(base, offset); 200 assertEquals(x, $value2$, "putUnaligned $type$ value"); 201 } 202 203 { 204 UNSAFE.put$Type$Unaligned(base, offset, $value1$, true); 205 $type$ x = UNSAFE.get$Type$Unaligned(base, offset, true); 206 assertEquals(x, $value1$, "putUnaligned big endian $type$ value"); 207 } 208 209 { 210 UNSAFE.put$Type$Unaligned(base, offset, $value2$, false); 211 $type$ x = UNSAFE.get$Type$Unaligned(base, offset, false); 212 assertEquals(x, $value2$, "putUnaligned little endian $type$ value"); 213 } 214 #end[Unaligned] 215 #end[JdkInternalMisc] 216 217 #if[CAS] 218 UNSAFE.put$Type$(base, offset, $value1$); 219 220 // Compare 221 { 222 boolean r = UNSAFE.compareAndSwap$Type$(base, offset, $value1$, $value2$); 223 assertEquals(r, true, "success compareAndSwap $type$"); 224 $type$ x = UNSAFE.get$Type$(base, offset); 225 assertEquals(x, $value2$, "success compareAndSwap $type$ value"); 226 } 227 228 { 229 boolean r = UNSAFE.compareAndSwap$Type$(base, offset, $value1$, $value3$); 230 assertEquals(r, false, "failing compareAndSwap $type$"); 231 $type$ x = UNSAFE.get$Type$(base, offset); 232 assertEquals(x, $value2$, "failing compareAndSwap $type$ value"); 233 } 234 235 #if[JdkInternalMisc] 236 // Advanced compare 237 { 238 $type$ r = UNSAFE.compareAndExchange$Type$Volatile(base, offset, $value2$, $value1$); 239 assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); 240 $type$ x = UNSAFE.get$Type$(base, offset); 241 assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); 242 } 243 244 { 245 $type$ r = UNSAFE.compareAndExchange$Type$Volatile(base, offset, $value2$, $value3$); 246 assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); 247 $type$ x = UNSAFE.get$Type$(base, offset); 248 assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); 249 } 250 251 { 252 $type$ r = UNSAFE.compareAndExchange$Type$Acquire(base, offset, $value1$, $value2$); 253 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); 254 $type$ x = UNSAFE.get$Type$(base, offset); 255 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); 256 } 257 258 { 259 $type$ r = UNSAFE.compareAndExchange$Type$Acquire(base, offset, $value1$, $value3$); 260 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); 261 $type$ x = UNSAFE.get$Type$(base, offset); 262 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); 263 } 264 265 { 266 $type$ r = UNSAFE.compareAndExchange$Type$Release(base, offset, $value2$, $value1$); 267 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); 268 $type$ x = UNSAFE.get$Type$(base, offset); 269 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); 270 } 271 272 { 273 $type$ r = UNSAFE.compareAndExchange$Type$Release(base, offset, $value2$, $value3$); 274 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); 275 $type$ x = UNSAFE.get$Type$(base, offset); 276 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); 277 } 278 279 { 280 boolean success = false; 281 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 282 success = UNSAFE.weakCompareAndSwap$Type$(base, offset, $value1$, $value2$); 283 } 284 assertEquals(success, true, "weakCompareAndSwap $type$"); 285 $type$ x = UNSAFE.get$Type$(base, offset); 286 assertEquals(x, $value2$, "weakCompareAndSwap $type$ value"); 287 } 288 289 { 290 boolean success = false; 291 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 292 success = UNSAFE.weakCompareAndSwap$Type$Acquire(base, offset, $value2$, $value1$); 293 } 294 assertEquals(success, true, "weakCompareAndSwapAcquire $type$"); 295 $type$ x = UNSAFE.get$Type$(base, offset); 296 assertEquals(x, $value1$, "weakCompareAndSwapAcquire $type$"); 297 } 298 299 { 300 boolean success = false; 301 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 302 success = UNSAFE.weakCompareAndSwap$Type$Release(base, offset, $value1$, $value2$); 303 } 304 assertEquals(success, true, "weakCompareAndSwapRelease $type$"); 305 $type$ x = UNSAFE.get$Type$(base, offset); 306 assertEquals(x, $value2$, "weakCompareAndSwapRelease $type$"); 307 } 308 309 { 310 boolean success = false; 311 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 312 success = UNSAFE.weakCompareAndSwap$Type$Volatile(base, offset, $value2$, $value1$); 313 } 314 assertEquals(success, true, "weakCompareAndSwapVolatile $type$"); 315 $type$ x = UNSAFE.get$Type$(base, offset); 316 assertEquals(x, $value1$, "weakCompareAndSwapVolatile $type$"); 317 } 318 319 #end[JdkInternalMisc] 320 UNSAFE.put$Type$(base, offset, $value2$); 321 322 // Compare set and get 323 { 324 $type$ o = UNSAFE.getAndSet$Type$(base, offset, $value1$); 325 assertEquals(o, $value2$, "getAndSet $type$"); 326 $type$ x = UNSAFE.get$Type$(base, offset); 327 assertEquals(x, $value1$, "getAndSet $type$ value"); 328 } 329 #end[CAS] 330 331 #if[AtomicAdd] 332 UNSAFE.put$Type$(base, offset, $value1$); 333 334 // get and add, add and get 335 { 336 $type$ o = UNSAFE.getAndAdd$Type$(base, offset, $value2$); 337 assertEquals(o, $value1$, "getAndAdd $type$"); 338 $type$ x = UNSAFE.get$Type$(base, offset); 339 assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$"); 340 } 341 #end[AtomicAdd] 342 } 343 344 #if[!Object] 345 #if[!boolean] 346 static void testAccess(long address) { 347 // Plain 348 { 349 UNSAFE.put$Type$(address, $value1$); 350 $type$ x = UNSAFE.get$Type$(address); 351 assertEquals(x, $value1$, "set $type$ value"); 352 } 353 } 354 #end[!boolean] 355 #end[!Object] 356 } 357