1 /* 2 * Copyright (c) 2019, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.lang.invoke; 26 27 import jdk.internal.access.foreign.MemoryAddressProxy; 28 import jdk.internal.vm.annotation.ForceInline; 29 30 import java.util.Objects; 31 32 import static java.lang.invoke.MethodHandleStatics.UNSAFE; 33 34 #warn 35 36 final class VarHandleMemoryAddressAs$Type$s { 37 38 static final boolean BE = UNSAFE.isBigEndian(); 39 40 static final int VM_ALIGN = $BoxType$.BYTES - 1; 41 42 #if[floatingPoint] 43 @ForceInline 44 static $rawType$ convEndian(boolean big, $type$ v) { 45 $rawType$ rv = $Type$.$type$ToRaw$RawType$Bits(v); 46 return big == BE ? rv : $RawBoxType$.reverseBytes(rv); 47 } 48 49 @ForceInline 50 static $type$ convEndian(boolean big, $rawType$ rv) { 51 rv = big == BE ? rv : $RawBoxType$.reverseBytes(rv); 52 return $Type$.$rawType$BitsTo$Type$(rv); 53 } 54 #else[floatingPoint] 55 #if[byte] 56 @ForceInline 57 static $type$ convEndian(boolean big, $type$ n) { 58 return n; 59 } 60 #else[byte] 61 @ForceInline 62 static $type$ convEndian(boolean big, $type$ n) { 63 return big == BE ? n : $BoxType$.reverseBytes(n); 64 } 65 #end[byte] 66 #end[floatingPoint] 67 68 @ForceInline 69 static MemoryAddressProxy checkAddress(Object obb, long offset, long length, boolean ro) { 70 MemoryAddressProxy oo = (MemoryAddressProxy)Objects.requireNonNull(obb); 71 oo.checkAccess(offset, length, ro); 72 return oo; 73 } 74 75 @ForceInline 76 static long offset(MemoryAddressProxy bb, long offset, long alignmentMask) { 77 long address = bb.unsafeGetOffset() + offset; 78 if ((address & alignmentMask) != 0) { 79 throw VarHandleMemoryAddressBase.newIllegalStateExceptionForMisalignedAccess(address); 80 } 81 if ((address & VM_ALIGN) != 0) { 82 throw VarHandleMemoryAddressBase.newIllegalStateExceptionForMisalignedAccess(address); 83 } 84 return address; 85 } 86 87 @ForceInline 88 static long offsetNoVMAlignCheck(MemoryAddressProxy bb, long offset, long alignmentMask) { 89 long address = bb.unsafeGetOffset() + offset; 90 if ((address & alignmentMask) != 0) { 91 throw VarHandleMemoryAddressBase.newIllegalStateExceptionForMisalignedAccess(address); 92 } 93 return address; 94 } 95 96 @ForceInline 97 static $type$ get0(VarHandleMemoryAddressBase handle, Object obb, long base) { 98 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true); 99 #if[floatingPoint] 100 $rawType$ rawValue = UNSAFE.get$RawType$Unaligned( 101 bb.unsafeGetBase(), 102 offsetNoVMAlignCheck(bb, base, handle.alignmentMask), 103 handle.be); 104 return $Type$.$rawType$BitsTo$Type$(rawValue); 105 #else[floatingPoint] 106 #if[byte] 107 return UNSAFE.get$Type$( 108 bb.unsafeGetBase(), 109 offsetNoVMAlignCheck(bb, base, handle.alignmentMask)); 110 #else[byte] 111 return UNSAFE.get$Type$Unaligned( 112 bb.unsafeGetBase(), 113 offsetNoVMAlignCheck(bb, base, handle.alignmentMask), 114 handle.be); 115 #end[byte] 116 #end[floatingPoint] 117 } 118 119 @ForceInline 120 static void set0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 121 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 122 #if[floatingPoint] 123 UNSAFE.put$RawType$Unaligned( 124 bb.unsafeGetBase(), 125 offsetNoVMAlignCheck(bb, base, handle.alignmentMask), 126 $Type$.$type$ToRaw$RawType$Bits(value), 127 handle.be); 128 #else[floatingPoint] 129 #if[byte] 130 UNSAFE.put$Type$( 131 bb.unsafeGetBase(), 132 offsetNoVMAlignCheck(bb, base, handle.alignmentMask), 133 value); 134 #else[byte] 135 UNSAFE.put$Type$Unaligned( 136 bb.unsafeGetBase(), 137 offsetNoVMAlignCheck(bb, base, handle.alignmentMask), 138 value, 139 handle.be); 140 #end[byte] 141 #end[floatingPoint] 142 } 143 144 @ForceInline 145 static $type$ getVolatile0(VarHandleMemoryAddressBase handle, Object obb, long base) { 146 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true); 147 return convEndian(handle.be, 148 UNSAFE.get$RawType$Volatile( 149 bb.unsafeGetBase(), 150 offset(bb, base, handle.alignmentMask))); 151 } 152 153 @ForceInline 154 static void setVolatile0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 155 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 156 UNSAFE.put$RawType$Volatile( 157 bb.unsafeGetBase(), 158 offset(bb, base, handle.alignmentMask), 159 convEndian(handle.be, value)); 160 } 161 162 @ForceInline 163 static $type$ getAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base) { 164 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true); 165 return convEndian(handle.be, 166 UNSAFE.get$RawType$Acquire( 167 bb.unsafeGetBase(), 168 offset(bb, base, handle.alignmentMask))); 169 } 170 171 @ForceInline 172 static void setRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 173 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 174 UNSAFE.put$RawType$Release( 175 bb.unsafeGetBase(), 176 offset(bb, base, handle.alignmentMask), 177 convEndian(handle.be, value)); 178 } 179 180 @ForceInline 181 static $type$ getOpaque0(VarHandleMemoryAddressBase handle, Object obb, long base) { 182 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true); 183 return convEndian(handle.be, 184 UNSAFE.get$RawType$Opaque( 185 bb.unsafeGetBase(), 186 offset(bb, base, handle.alignmentMask))); 187 } 188 189 @ForceInline 190 static void setOpaque0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 191 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 192 UNSAFE.put$RawType$Opaque( 193 bb.unsafeGetBase(), 194 offset(bb, base, handle.alignmentMask), 195 convEndian(handle.be, value)); 196 } 197 #if[CAS] 198 199 @ForceInline 200 static boolean compareAndSet0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 201 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 202 return UNSAFE.compareAndSet$RawType$( 203 bb.unsafeGetBase(), 204 offset(bb, base, handle.alignmentMask), 205 convEndian(handle.be, expected), convEndian(handle.be, value)); 206 } 207 208 @ForceInline 209 static $type$ compareAndExchange0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 210 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 211 return convEndian(handle.be, 212 UNSAFE.compareAndExchange$RawType$( 213 bb.unsafeGetBase(), 214 offset(bb, base, handle.alignmentMask), 215 convEndian(handle.be, expected), convEndian(handle.be, value))); 216 } 217 218 @ForceInline 219 static $type$ compareAndExchangeAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 220 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 221 return convEndian(handle.be, 222 UNSAFE.compareAndExchange$RawType$Acquire( 223 bb.unsafeGetBase(), 224 offset(bb, base, handle.alignmentMask), 225 convEndian(handle.be, expected), convEndian(handle.be, value))); 226 } 227 228 @ForceInline 229 static $type$ compareAndExchangeRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 230 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 231 return convEndian(handle.be, 232 UNSAFE.compareAndExchange$RawType$Release( 233 bb.unsafeGetBase(), 234 offset(bb, base, handle.alignmentMask), 235 convEndian(handle.be, expected), convEndian(handle.be, value))); 236 } 237 238 @ForceInline 239 static boolean weakCompareAndSetPlain0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 240 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 241 return UNSAFE.weakCompareAndSet$RawType$Plain( 242 bb.unsafeGetBase(), 243 offset(bb, base, handle.alignmentMask), 244 convEndian(handle.be, expected), convEndian(handle.be, value)); 245 } 246 247 @ForceInline 248 static boolean weakCompareAndSet0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 249 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 250 return UNSAFE.weakCompareAndSet$RawType$( 251 bb.unsafeGetBase(), 252 offset(bb, base, handle.alignmentMask), 253 convEndian(handle.be, expected), convEndian(handle.be, value)); 254 } 255 256 @ForceInline 257 static boolean weakCompareAndSetAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 258 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 259 return UNSAFE.weakCompareAndSet$RawType$Acquire( 260 bb.unsafeGetBase(), 261 offset(bb, base, handle.alignmentMask), 262 convEndian(handle.be, expected), convEndian(handle.be, value)); 263 } 264 265 @ForceInline 266 static boolean weakCompareAndSetRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ expected, $type$ value) { 267 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 268 return UNSAFE.weakCompareAndSet$RawType$Release( 269 bb.unsafeGetBase(), 270 offset(bb, base, handle.alignmentMask), 271 convEndian(handle.be, expected), convEndian(handle.be, value)); 272 } 273 274 @ForceInline 275 static $type$ getAndSet0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 276 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 277 return convEndian(handle.be, 278 UNSAFE.getAndSet$RawType$( 279 bb.unsafeGetBase(), 280 offset(bb, base, handle.alignmentMask), 281 convEndian(handle.be, value))); 282 } 283 284 @ForceInline 285 static $type$ getAndSetAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 286 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 287 return convEndian(handle.be, 288 UNSAFE.getAndSet$RawType$Acquire( 289 bb.unsafeGetBase(), 290 offset(bb, base, handle.alignmentMask), 291 convEndian(handle.be, value))); 292 } 293 294 @ForceInline 295 static $type$ getAndSetRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 296 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 297 return convEndian(handle.be, 298 UNSAFE.getAndSet$RawType$Release( 299 bb.unsafeGetBase(), 300 offset(bb, base, handle.alignmentMask), 301 convEndian(handle.be, value))); 302 } 303 #end[CAS] 304 #if[AtomicAdd] 305 306 @ForceInline 307 static $type$ getAndAdd0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ delta) { 308 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 309 if (handle.be == BE) { 310 return UNSAFE.getAndAdd$RawType$( 311 bb.unsafeGetBase(), 312 offset(bb, base, handle.alignmentMask), 313 delta); 314 } else { 315 return getAndAddConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), delta); 316 } 317 } 318 319 @ForceInline 320 static $type$ getAndAddAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ delta) { 321 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 322 if (handle.be == BE) { 323 return UNSAFE.getAndAdd$RawType$Acquire( 324 bb.unsafeGetBase(), 325 offset(bb, base, handle.alignmentMask), 326 delta); 327 } else { 328 return getAndAddConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), delta); 329 } 330 } 331 332 @ForceInline 333 static $type$ getAndAddRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ delta) { 334 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 335 if (handle.be == BE) { 336 return UNSAFE.getAndAdd$RawType$Release( 337 bb.unsafeGetBase(), 338 offset(bb, base, handle.alignmentMask), 339 delta); 340 } else { 341 return getAndAddConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), delta); 342 } 343 } 344 345 @ForceInline 346 static $type$ getAndAddConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ delta) { 347 $type$ nativeExpectedValue, expectedValue; 348 Object base = bb.unsafeGetBase(); 349 do { 350 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset); 351 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue); 352 } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset, 353 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta))); 354 return expectedValue; 355 } 356 #end[AtomicAdd] 357 #if[Bitwise] 358 359 @ForceInline 360 static $type$ getAndBitwiseOr0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 361 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 362 if (handle.be == BE) { 363 return UNSAFE.getAndBitwiseOr$RawType$( 364 bb.unsafeGetBase(), 365 offset(bb, base, handle.alignmentMask), 366 value); 367 } else { 368 return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 369 } 370 } 371 372 @ForceInline 373 static $type$ getAndBitwiseOrRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 374 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 375 if (handle.be == BE) { 376 return UNSAFE.getAndBitwiseOr$RawType$Release( 377 bb.unsafeGetBase(), 378 offset(bb, base, handle.alignmentMask), 379 value); 380 } else { 381 return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 382 } 383 } 384 385 @ForceInline 386 static $type$ getAndBitwiseOrAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 387 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 388 if (handle.be == BE) { 389 return UNSAFE.getAndBitwiseOr$RawType$Acquire( 390 bb.unsafeGetBase(), 391 offset(bb, base, handle.alignmentMask), 392 value); 393 } else { 394 return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 395 } 396 } 397 398 @ForceInline 399 static $type$ getAndBitwiseOrConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ value) { 400 $type$ nativeExpectedValue, expectedValue; 401 Object base = bb.unsafeGetBase(); 402 do { 403 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset); 404 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue); 405 } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset, 406 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value))); 407 return expectedValue; 408 } 409 410 @ForceInline 411 static $type$ getAndBitwiseAnd0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 412 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 413 if (handle.be == BE) { 414 return UNSAFE.getAndBitwiseAnd$RawType$( 415 bb.unsafeGetBase(), 416 offset(bb, base, handle.alignmentMask), 417 value); 418 } else { 419 return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 420 } 421 } 422 423 @ForceInline 424 static $type$ getAndBitwiseAndRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 425 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 426 if (handle.be == BE) { 427 return UNSAFE.getAndBitwiseAnd$RawType$Release( 428 bb.unsafeGetBase(), 429 offset(bb, base, handle.alignmentMask), 430 value); 431 } else { 432 return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 433 } 434 } 435 436 @ForceInline 437 static $type$ getAndBitwiseAndAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 438 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 439 if (handle.be == BE) { 440 return UNSAFE.getAndBitwiseAnd$RawType$Acquire( 441 bb.unsafeGetBase(), 442 offset(bb, base, handle.alignmentMask), 443 value); 444 } else { 445 return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 446 } 447 } 448 449 @ForceInline 450 static $type$ getAndBitwiseAndConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ value) { 451 $type$ nativeExpectedValue, expectedValue; 452 Object base = bb.unsafeGetBase(); 453 do { 454 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset); 455 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue); 456 } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset, 457 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value))); 458 return expectedValue; 459 } 460 461 462 @ForceInline 463 static $type$ getAndBitwiseXor0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 464 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 465 if (handle.be == BE) { 466 return UNSAFE.getAndBitwiseXor$RawType$( 467 bb.unsafeGetBase(), 468 offset(bb, base, handle.alignmentMask), 469 value); 470 } else { 471 return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 472 } 473 } 474 475 @ForceInline 476 static $type$ getAndBitwiseXorRelease0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 477 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 478 if (handle.be == BE) { 479 return UNSAFE.getAndBitwiseXor$RawType$Release( 480 bb.unsafeGetBase(), 481 offset(bb, base, handle.alignmentMask), 482 value); 483 } else { 484 return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 485 } 486 } 487 488 @ForceInline 489 static $type$ getAndBitwiseXorAcquire0(VarHandleMemoryAddressBase handle, Object obb, long base, $type$ value) { 490 MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false); 491 if (handle.be == BE) { 492 return UNSAFE.getAndBitwiseXor$RawType$Acquire( 493 bb.unsafeGetBase(), 494 offset(bb, base, handle.alignmentMask), 495 value); 496 } else { 497 return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value); 498 } 499 } 500 501 @ForceInline 502 static $type$ getAndBitwiseXorConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ value) { 503 $type$ nativeExpectedValue, expectedValue; 504 Object base = bb.unsafeGetBase(); 505 do { 506 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset); 507 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue); 508 } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset, 509 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value))); 510 return expectedValue; 511 } 512 #end[Bitwise] 513 }