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