1 /* 2 * Copyright (c) 2000, 2013, 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 26 package sun.misc; 27 28 import dalvik.annotation.optimization.FastNative; 29 import jdk.internal.vm.annotation.IntrinsicCandidate; 30 import sun.reflect.Reflection; 31 32 import java.lang.reflect.Field; 33 import java.lang.reflect.Modifier; 34 35 /** 36 * A collection of methods for performing low-level, unsafe operations. 37 * Although the class and all methods are public, use of this class is 38 * limited because only trusted code can obtain instances of it. 39 * 40 * @author John R. Rose 41 * @see #getUnsafe 42 */ 43 public final class Unsafe { 44 /** Traditional dalvik name. */ 45 private static final Unsafe THE_ONE = new Unsafe(); 46 47 private static final Unsafe theUnsafe = THE_ONE; 48 public static final int INVALID_FIELD_OFFSET = -1; 49 50 /** 51 * This class is only privately instantiable. 52 */ Unsafe()53 private Unsafe() {} 54 55 /** 56 * Gets the unique instance of this class. This is only allowed in 57 * very limited situations. 58 */ getUnsafe()59 public static Unsafe getUnsafe() { 60 Class<?> caller = Reflection.getCallerClass(); 61 /* 62 * Only code on the bootclasspath is allowed to get at the 63 * Unsafe instance. 64 */ 65 ClassLoader calling = (caller == null) ? null : caller.getClassLoader(); 66 if ((calling != null) && (calling != Unsafe.class.getClassLoader())) { 67 throw new SecurityException("Unsafe access denied"); 68 } 69 70 return THE_ONE; 71 } 72 73 /** 74 * Gets the raw byte offset from the start of an object's memory to 75 * the memory used to store the indicated instance field. 76 * 77 * @param field non-{@code null}; the field in question, which must be an 78 * instance field 79 * @return the offset to the field 80 */ objectFieldOffset(Field field)81 public long objectFieldOffset(Field field) { 82 if (Modifier.isStatic(field.getModifiers())) { 83 throw new IllegalArgumentException("valid for instance fields only"); 84 } 85 return field.getOffset(); 86 } 87 88 /** 89 * Gets the offset from the start of an array object's memory to 90 * the memory used to store its initial (zeroeth) element. 91 * 92 * @param clazz non-{@code null}; class in question; must be an array class 93 * @return the offset to the initial element 94 */ arrayBaseOffset(Class clazz)95 public int arrayBaseOffset(Class clazz) { 96 Class<?> component = clazz.getComponentType(); 97 if (component == null) { 98 throw new IllegalArgumentException("Valid for array classes only: " + clazz); 99 } 100 return getArrayBaseOffsetForComponentType(component); 101 } 102 103 /** 104 * Gets the size of each element of the given array class. 105 * 106 * @param clazz non-{@code null}; class in question; must be an array class 107 * @return > 0; the size of each element of the array 108 */ arrayIndexScale(Class clazz)109 public int arrayIndexScale(Class clazz) { 110 Class<?> component = clazz.getComponentType(); 111 if (component == null) { 112 throw new IllegalArgumentException("Valid for array classes only: " + clazz); 113 } 114 return getArrayIndexScaleForComponentType(component); 115 } 116 117 @FastNative getArrayBaseOffsetForComponentType(Class component_class)118 private static native int getArrayBaseOffsetForComponentType(Class component_class); 119 @FastNative getArrayIndexScaleForComponentType(Class component_class)120 private static native int getArrayIndexScaleForComponentType(Class component_class); 121 122 /** 123 * Performs a compare-and-set operation on an {@code int} 124 * field within the given object. 125 * 126 * @param obj non-{@code null}; object containing the field 127 * @param offset offset to the field within {@code obj} 128 * @param expectedValue expected value of the field 129 * @param newValue new value to store in the field if the contents are 130 * as expected 131 * @return {@code true} if the new value was in fact stored, and 132 * {@code false} if not 133 */ 134 @FastNative compareAndSwapInt(Object obj, long offset, int expectedValue, int newValue)135 public native boolean compareAndSwapInt(Object obj, long offset, 136 int expectedValue, int newValue); 137 138 /** 139 * Performs a compare-and-set operation on a {@code long} 140 * field within the given object. 141 * 142 * @param obj non-{@code null}; object containing the field 143 * @param offset offset to the field within {@code obj} 144 * @param expectedValue expected value of the field 145 * @param newValue new value to store in the field if the contents are 146 * as expected 147 * @return {@code true} if the new value was in fact stored, and 148 * {@code false} if not 149 */ 150 @FastNative compareAndSwapLong(Object obj, long offset, long expectedValue, long newValue)151 public native boolean compareAndSwapLong(Object obj, long offset, 152 long expectedValue, long newValue); 153 154 /** 155 * Performs a compare-and-set operation on an {@code obj} 156 * field (that is, a reference field) within the given object. 157 * 158 * @param obj non-{@code null}; object containing the field 159 * @param offset offset to the field within {@code obj} 160 * @param expectedValue expected value of the field 161 * @param newValue new value to store in the field if the contents are 162 * as expected 163 * @return {@code true} if the new value was in fact stored, and 164 * {@code false} if not 165 */ 166 @FastNative compareAndSwapObject(Object obj, long offset, Object expectedValue, Object newValue)167 public native boolean compareAndSwapObject(Object obj, long offset, 168 Object expectedValue, Object newValue); 169 170 /** 171 * Gets an {@code int} field from the given object, 172 * using {@code volatile} semantics. 173 * 174 * @param obj non-{@code null}; object containing the field 175 * @param offset offset to the field within {@code obj} 176 * @return the retrieved value 177 */ 178 @FastNative getIntVolatile(Object obj, long offset)179 public native int getIntVolatile(Object obj, long offset); 180 181 /** 182 * Stores an {@code int} field into the given object, 183 * using {@code volatile} semantics. 184 * 185 * @param obj non-{@code null}; object containing the field 186 * @param offset offset to the field within {@code obj} 187 * @param newValue the value to store 188 */ 189 @FastNative putIntVolatile(Object obj, long offset, int newValue)190 public native void putIntVolatile(Object obj, long offset, int newValue); 191 192 /** 193 * Gets a {@code long} field from the given object, 194 * using {@code volatile} semantics. 195 * 196 * @param obj non-{@code null}; object containing the field 197 * @param offset offset to the field within {@code obj} 198 * @return the retrieved value 199 */ 200 @FastNative getLongVolatile(Object obj, long offset)201 public native long getLongVolatile(Object obj, long offset); 202 203 /** 204 * Stores a {@code long} field into the given object, 205 * using {@code volatile} semantics. 206 * 207 * @param obj non-{@code null}; object containing the field 208 * @param offset offset to the field within {@code obj} 209 * @param newValue the value to store 210 */ 211 @FastNative putLongVolatile(Object obj, long offset, long newValue)212 public native void putLongVolatile(Object obj, long offset, long newValue); 213 214 /** 215 * Gets an {@code obj} field from the given object, 216 * using {@code volatile} semantics. 217 * 218 * @param obj non-{@code null}; object containing the field 219 * @param offset offset to the field within {@code obj} 220 * @return the retrieved value 221 */ 222 @FastNative getObjectVolatile(Object obj, long offset)223 public native Object getObjectVolatile(Object obj, long offset); 224 225 /** 226 * Stores an {@code obj} field into the given object, 227 * using {@code volatile} semantics. 228 * 229 * @param obj non-{@code null}; object containing the field 230 * @param offset offset to the field within {@code obj} 231 * @param newValue the value to store 232 */ 233 @FastNative putObjectVolatile(Object obj, long offset, Object newValue)234 public native void putObjectVolatile(Object obj, long offset, 235 Object newValue); 236 237 /** 238 * Gets an {@code int} field from the given object. 239 * 240 * @param obj non-{@code null}; object containing int field 241 * @param offset offset to the field within {@code obj} 242 * @return the retrieved value 243 */ 244 @FastNative getInt(Object obj, long offset)245 public native int getInt(Object obj, long offset); 246 247 /** 248 * Stores an {@code int} field into the given object. 249 * 250 * @param obj non-{@code null}; object containing int field 251 * @param offset offset to the field within {@code obj} 252 * @param newValue the value to store 253 */ 254 @FastNative putInt(Object obj, long offset, int newValue)255 public native void putInt(Object obj, long offset, int newValue); 256 257 /** 258 * Lazy set an int field. 259 * 260 * @param obj non-{@code null}; object containing the field 261 * @param offset offset to the field within {@code obj} 262 * @param newValue the value to store 263 */ 264 @FastNative putOrderedInt(Object obj, long offset, int newValue)265 public native void putOrderedInt(Object obj, long offset, int newValue); 266 267 /** 268 * Gets a {@code long} field from the given object. 269 * 270 * @param obj non-{@code null}; object containing the field 271 * @param offset offset to the field within {@code obj} 272 * @return the retrieved value 273 */ 274 @FastNative getLong(Object obj, long offset)275 public native long getLong(Object obj, long offset); 276 277 /** 278 * Stores a {@code long} field into the given object. 279 * 280 * @param obj non-{@code null}; object containing the field 281 * @param offset offset to the field within {@code obj} 282 * @param newValue the value to store 283 */ 284 @FastNative putLong(Object obj, long offset, long newValue)285 public native void putLong(Object obj, long offset, long newValue); 286 287 /** 288 * Lazy set a long field. 289 * 290 * @param obj non-{@code null}; object containing the field 291 * @param offset offset to the field within {@code obj} 292 * @param newValue the value to store 293 */ 294 @FastNative putOrderedLong(Object obj, long offset, long newValue)295 public native void putOrderedLong(Object obj, long offset, long newValue); 296 297 /** 298 * Gets an {@code obj} field from the given object. 299 * 300 * @param obj non-{@code null}; object containing the field 301 * @param offset offset to the field within {@code obj} 302 * @return the retrieved value 303 */ 304 @FastNative getObject(Object obj, long offset)305 public native Object getObject(Object obj, long offset); 306 307 /** 308 * Stores an {@code obj} field into the given object. 309 * 310 * @param obj non-{@code null}; object containing the field 311 * @param offset offset to the field within {@code obj} 312 * @param newValue the value to store 313 */ 314 @FastNative putObject(Object obj, long offset, Object newValue)315 public native void putObject(Object obj, long offset, Object newValue); 316 317 /** 318 * Lazy set an object field. 319 * 320 * @param obj non-{@code null}; object containing the field 321 * @param offset offset to the field within {@code obj} 322 * @param newValue the value to store 323 */ 324 @FastNative putOrderedObject(Object obj, long offset, Object newValue)325 public native void putOrderedObject(Object obj, long offset, 326 Object newValue); 327 328 /** 329 * Gets a {@code boolean} field from the given object. 330 * 331 * @param obj non-{@code null}; object containing boolean field 332 * @param offset offset to the field within {@code obj} 333 * @return the retrieved value 334 */ 335 @FastNative getBoolean(Object obj, long offset)336 public native boolean getBoolean(Object obj, long offset); 337 338 /** 339 * Stores a {@code boolean} field into the given object. 340 * 341 * @param obj non-{@code null}; object containing boolean field 342 * @param offset offset to the field within {@code obj} 343 * @param newValue the value to store 344 */ 345 @FastNative putBoolean(Object obj, long offset, boolean newValue)346 public native void putBoolean(Object obj, long offset, boolean newValue); 347 348 /** 349 * Gets a {@code byte} field from the given object. 350 * 351 * @param obj non-{@code null}; object containing byte field 352 * @param offset offset to the field within {@code obj} 353 * @return the retrieved value 354 */ 355 @FastNative getByte(Object obj, long offset)356 public native byte getByte(Object obj, long offset); 357 358 /** 359 * Stores a {@code byte} field into the given object. 360 * 361 * @param obj non-{@code null}; object containing byte field 362 * @param offset offset to the field within {@code obj} 363 * @param newValue the value to store 364 */ 365 @FastNative putByte(Object obj, long offset, byte newValue)366 public native void putByte(Object obj, long offset, byte newValue); 367 368 /** 369 * Gets a {@code char} field from the given object. 370 * 371 * @param obj non-{@code null}; object containing char field 372 * @param offset offset to the field within {@code obj} 373 * @return the retrieved value 374 */ 375 @FastNative getChar(Object obj, long offset)376 public native char getChar(Object obj, long offset); 377 378 /** 379 * Stores a {@code char} field into the given object. 380 * 381 * @param obj non-{@code null}; object containing char field 382 * @param offset offset to the field within {@code obj} 383 * @param newValue the value to store 384 */ 385 @FastNative putChar(Object obj, long offset, char newValue)386 public native void putChar(Object obj, long offset, char newValue); 387 388 /** 389 * Gets a {@code short} field from the given object. 390 * 391 * @param obj non-{@code null}; object containing short field 392 * @param offset offset to the field within {@code obj} 393 * @return the retrieved value 394 */ 395 @FastNative getShort(Object obj, long offset)396 public native short getShort(Object obj, long offset); 397 398 /** 399 * Stores a {@code short} field into the given object. 400 * 401 * @param obj non-{@code null}; object containing short field 402 * @param offset offset to the field within {@code obj} 403 * @param newValue the value to store 404 */ 405 @FastNative putShort(Object obj, long offset, short newValue)406 public native void putShort(Object obj, long offset, short newValue); 407 408 /** 409 * Gets a {@code float} field from the given object. 410 * 411 * @param obj non-{@code null}; object containing float field 412 * @param offset offset to the field within {@code obj} 413 * @return the retrieved value 414 */ 415 @FastNative getFloat(Object obj, long offset)416 public native float getFloat(Object obj, long offset); 417 418 /** 419 * Stores a {@code float} field into the given object. 420 * 421 * @param obj non-{@code null}; object containing float field 422 * @param offset offset to the field within {@code obj} 423 * @param newValue the value to store 424 */ 425 @FastNative putFloat(Object obj, long offset, float newValue)426 public native void putFloat(Object obj, long offset, float newValue); 427 428 /** 429 * Gets a {@code double} field from the given object. 430 * 431 * @param obj non-{@code null}; object containing double field 432 * @param offset offset to the field within {@code obj} 433 * @return the retrieved value 434 */ 435 @FastNative getDouble(Object obj, long offset)436 public native double getDouble(Object obj, long offset); 437 438 /** 439 * Stores a {@code double} field into the given object. 440 * 441 * @param obj non-{@code null}; object containing double field 442 * @param offset offset to the field within {@code obj} 443 * @param newValue the value to store 444 */ 445 @FastNative putDouble(Object obj, long offset, double newValue)446 public native void putDouble(Object obj, long offset, double newValue); 447 448 /** 449 * Parks the calling thread for the specified amount of time, 450 * unless the "permit" for the thread is already available (due to 451 * a previous call to {@link #unpark}. This method may also return 452 * spuriously (that is, without the thread being told to unpark 453 * and without the indicated amount of time elapsing). 454 * 455 * <p>See {@link java.util.concurrent.locks.LockSupport} for more 456 * in-depth information of the behavior of this method.</p> 457 * 458 * @param absolute whether the given time value is absolute 459 * milliseconds-since-the-epoch ({@code true}) or relative 460 * nanoseconds-from-now ({@code false}) 461 * @param time the (absolute millis or relative nanos) time value 462 */ 463 park(boolean absolute, long time)464 public native void park(boolean absolute, long time); 465 /** 466 * Unparks the given object, which must be a {@link Thread}. 467 * 468 * <p>See {@link java.util.concurrent.locks.LockSupport} for more 469 * in-depth information of the behavior of this method.</p> 470 * 471 * @param obj non-{@code null}; the object to unpark 472 */ 473 @FastNative unpark(Object obj)474 public native void unpark(Object obj); 475 476 /** 477 * Allocates an instance of the given class without running the constructor. 478 * The class' <clinit> will be run, if necessary. 479 */ allocateInstance(Class<?> c)480 public native Object allocateInstance(Class<?> c); 481 482 /** 483 * Gets the size of the address value, in bytes. 484 * 485 * @return the size of the address, in bytes 486 */ 487 @FastNative addressSize()488 public native int addressSize(); 489 490 /** 491 * Gets the size of the memory page, in bytes. 492 * 493 * @return the size of the page 494 */ 495 @FastNative pageSize()496 public native int pageSize(); 497 498 /** 499 * Allocates a memory block of size {@code bytes}. 500 * 501 * @param bytes size of the memory block 502 * @return address of the allocated memory 503 */ 504 @FastNative allocateMemory(long bytes)505 public native long allocateMemory(long bytes); 506 507 /** 508 * Frees previously allocated memory at given address. 509 * 510 * @param address address of the freed memory 511 */ 512 @FastNative freeMemory(long address)513 public native void freeMemory(long address); 514 515 /** 516 * Fills given memory block with a given value. 517 * 518 * @param address address of the memoory block 519 * @param bytes length of the memory block, in bytes 520 * @param value fills memory with this value 521 */ 522 @FastNative setMemory(long address, long bytes, byte value)523 public native void setMemory(long address, long bytes, byte value); 524 525 /** 526 * Gets {@code byte} from given address in memory. 527 * 528 * @param address address in memory 529 * @return {@code byte} value 530 */ 531 @FastNative getByte(long address)532 public native byte getByte(long address); 533 534 /** 535 * Stores a {@code byte} into the given memory address. 536 * 537 * @param address address in memory where to store the value 538 * @param newValue the value to store 539 */ 540 @FastNative putByte(long address, byte x)541 public native void putByte(long address, byte x); 542 543 /** 544 * Gets {@code short} from given address in memory. 545 * 546 * @param address address in memory 547 * @return {@code short} value 548 */ 549 @FastNative getShort(long address)550 public native short getShort(long address); 551 552 /** 553 * Stores a {@code short} into the given memory address. 554 * 555 * @param address address in memory where to store the value 556 * @param newValue the value to store 557 */ 558 @FastNative putShort(long address, short x)559 public native void putShort(long address, short x); 560 561 /** 562 * Gets {@code char} from given address in memory. 563 * 564 * @param address address in memory 565 * @return {@code char} value 566 */ 567 @FastNative getChar(long address)568 public native char getChar(long address); 569 570 /** 571 * Stores a {@code char} into the given memory address. 572 * 573 * @param address address in memory where to store the value 574 * @param newValue the value to store 575 */ 576 @FastNative putChar(long address, char x)577 public native void putChar(long address, char x); 578 579 /** 580 * Gets {@code int} from given address in memory. 581 * 582 * @param address address in memory 583 * @return {@code int} value 584 */ 585 @FastNative getInt(long address)586 public native int getInt(long address); 587 588 /** 589 * Stores a {@code int} into the given memory address. 590 * 591 * @param address address in memory where to store the value 592 * @param newValue the value to store 593 */ 594 @FastNative putInt(long address, int x)595 public native void putInt(long address, int x); 596 597 598 /** 599 * Gets {@code long} from given address in memory. 600 * 601 * @param address address in memory 602 * @return {@code long} value 603 */ 604 @FastNative getLong(long address)605 public native long getLong(long address); 606 607 /** 608 * Stores a {@code long} into the given memory address. 609 * 610 * @param address address in memory where to store the value 611 * @param newValue the value to store 612 */ 613 @FastNative putLong(long address, long x)614 public native void putLong(long address, long x); 615 616 /** 617 * Gets {@code long} from given address in memory. 618 * 619 * @param address address in memory 620 * @return {@code long} value 621 */ 622 @FastNative getFloat(long address)623 public native float getFloat(long address); 624 625 /** 626 * Stores a {@code float} into the given memory address. 627 * 628 * @param address address in memory where to store the value 629 * @param newValue the value to store 630 */ 631 @FastNative putFloat(long address, float x)632 public native void putFloat(long address, float x); 633 634 /** 635 * Gets {@code double} from given address in memory. 636 * 637 * @param address address in memory 638 * @return {@code double} value 639 */ 640 @FastNative getDouble(long address)641 public native double getDouble(long address); 642 643 /** 644 * Stores a {@code double} into the given memory address. 645 * 646 * @param address address in memory where to store the value 647 * @param newValue the value to store 648 */ 649 @FastNative putDouble(long address, double x)650 public native void putDouble(long address, double x); 651 652 /** 653 * Copies given memory block to a primitive array. 654 * 655 * @param srcAddr address to copy memory from 656 * @param dst address to copy memory to 657 * @param dstOffset offset in {@code dst} 658 * @param bytes number of bytes to copy 659 */ 660 @FastNative copyMemoryToPrimitiveArray(long srcAddr, Object dst, long dstOffset, long bytes)661 public native void copyMemoryToPrimitiveArray(long srcAddr, 662 Object dst, long dstOffset, long bytes); 663 664 /** 665 * Treat given primitive array as a continuous memory block and 666 * copy it to given memory address. 667 * 668 * @param src primitive array to copy data from 669 * @param srcOffset offset in {@code src} to copy from 670 * @param dstAddr memory address to copy data to 671 * @param bytes number of bytes to copy 672 */ 673 @FastNative copyMemoryFromPrimitiveArray(Object src, long srcOffset, long dstAddr, long bytes)674 public native void copyMemoryFromPrimitiveArray(Object src, long srcOffset, 675 long dstAddr, long bytes); 676 677 /** 678 * Sets all bytes in a given block of memory to a copy of another block. 679 * 680 * @param srcAddr address of the source memory to be copied from 681 * @param dstAddr address of the destination memory to copy to 682 * @param bytes number of bytes to copy 683 */ 684 @FastNative copyMemory(long srcAddr, long dstAddr, long bytes)685 public native void copyMemory(long srcAddr, long dstAddr, long bytes); 686 687 688 // The following contain CAS-based Java implementations used on 689 // platforms not supporting native instructions 690 691 /** 692 * Atomically adds the given value to the current value of a field 693 * or array element within the given object {@code o} 694 * at the given {@code offset}. 695 * 696 * @param o object/array to update the field/element in 697 * @param offset field/element offset 698 * @param delta the value to add 699 * @return the previous value 700 * @since 1.8 701 */ 702 @IntrinsicCandidate getAndAddInt(Object o, long offset, int delta)703 public final int getAndAddInt(Object o, long offset, int delta) { 704 int v; 705 do { 706 v = getIntVolatile(o, offset); 707 } while (!compareAndSwapInt(o, offset, v, v + delta)); 708 return v; 709 } 710 711 /** 712 * Atomically adds the given value to the current value of a field 713 * or array element within the given object {@code o} 714 * at the given {@code offset}. 715 * 716 * @param o object/array to update the field/element in 717 * @param offset field/element offset 718 * @param delta the value to add 719 * @return the previous value 720 * @since 1.8 721 */ 722 @IntrinsicCandidate getAndAddLong(Object o, long offset, long delta)723 public final long getAndAddLong(Object o, long offset, long delta) { 724 long v; 725 do { 726 v = getLongVolatile(o, offset); 727 } while (!compareAndSwapLong(o, offset, v, v + delta)); 728 return v; 729 } 730 731 /** 732 * Atomically exchanges the given value with the current value of 733 * a field or array element within the given object {@code o} 734 * at the given {@code offset}. 735 * 736 * @param o object/array to update the field/element in 737 * @param offset field/element offset 738 * @param newValue new value 739 * @return the previous value 740 * @since 1.8 741 */ 742 @IntrinsicCandidate getAndSetInt(Object o, long offset, int newValue)743 public final int getAndSetInt(Object o, long offset, int newValue) { 744 int v; 745 do { 746 v = getIntVolatile(o, offset); 747 } while (!compareAndSwapInt(o, offset, v, newValue)); 748 return v; 749 } 750 751 /** 752 * Atomically exchanges the given value with the current value of 753 * a field or array element within the given object {@code o} 754 * at the given {@code offset}. 755 * 756 * @param o object/array to update the field/element in 757 * @param offset field/element offset 758 * @param newValue new value 759 * @return the previous value 760 * @since 1.8 761 */ 762 @IntrinsicCandidate getAndSetLong(Object o, long offset, long newValue)763 public final long getAndSetLong(Object o, long offset, long newValue) { 764 long v; 765 do { 766 v = getLongVolatile(o, offset); 767 } while (!compareAndSwapLong(o, offset, v, newValue)); 768 return v; 769 } 770 771 /** 772 * Atomically exchanges the given reference value with the current 773 * reference value of a field or array element within the given 774 * object {@code o} at the given {@code offset}. 775 * 776 * @param o object/array to update the field/element in 777 * @param offset field/element offset 778 * @param newValue new value 779 * @return the previous value 780 * @since 1.8 781 */ 782 @IntrinsicCandidate getAndSetObject(Object o, long offset, Object newValue)783 public final Object getAndSetObject(Object o, long offset, Object newValue) { 784 Object v; 785 do { 786 v = getObjectVolatile(o, offset); 787 } while (!compareAndSwapObject(o, offset, v, newValue)); 788 return v; 789 } 790 791 792 /** 793 * Ensures that loads before the fence will not be reordered with loads and 794 * stores after the fence; a "LoadLoad plus LoadStore barrier". 795 * 796 * Corresponds to C11 atomic_thread_fence(memory_order_acquire) 797 * (an "acquire fence"). 798 * 799 * A pure LoadLoad fence is not provided, since the addition of LoadStore 800 * is almost always desired, and most current hardware instructions that 801 * provide a LoadLoad barrier also provide a LoadStore barrier for free. 802 * @since 1.8 803 */ 804 @IntrinsicCandidate 805 @FastNative loadFence()806 public native void loadFence(); 807 808 /** 809 * Ensures that loads and stores before the fence will not be reordered with 810 * stores after the fence; a "StoreStore plus LoadStore barrier". 811 * 812 * Corresponds to C11 atomic_thread_fence(memory_order_release) 813 * (a "release fence"). 814 * 815 * A pure StoreStore fence is not provided, since the addition of LoadStore 816 * is almost always desired, and most current hardware instructions that 817 * provide a StoreStore barrier also provide a LoadStore barrier for free. 818 * @since 1.8 819 */ 820 @IntrinsicCandidate 821 @FastNative storeFence()822 public native void storeFence(); 823 824 /** 825 * Ensures that loads and stores before the fence will not be reordered 826 * with loads and stores after the fence. Implies the effects of both 827 * loadFence() and storeFence(), and in addition, the effect of a StoreLoad 828 * barrier. 829 * 830 * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst). 831 * @since 1.8 832 */ 833 @IntrinsicCandidate 834 @FastNative fullFence()835 public native void fullFence(); 836 } 837