1 /*
   2  * Copyright (c) 2000, 2025, 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 jdk.internal.misc;
  27 
  28 import jdk.internal.value.ValueClass;
  29 import jdk.internal.vm.annotation.AOTRuntimeSetup;
  30 import jdk.internal.vm.annotation.AOTSafeClassInitializer;
  31 import jdk.internal.vm.annotation.ForceInline;
  32 import jdk.internal.vm.annotation.IntrinsicCandidate;
  33 import sun.nio.Cleaner;
  34 import sun.nio.ch.DirectBuffer;
  35 
  36 import java.lang.reflect.Field;
  37 import java.security.ProtectionDomain;
  38 
  39 import static jdk.internal.misc.UnsafeConstants.*;
  40 
  41 /**
  42  * A collection of methods for performing low-level, unsafe operations.
  43  * Although the class and all methods are public, use of this class is
  44  * limited because only trusted code can obtain instances of it.
  45  *
  46  * <em>Note:</em> It is the responsibility of the caller to make sure
  47  * arguments are checked before methods of this class are
  48  * called. While some rudimentary checks are performed on the input,
  49  * the checks are best effort and when performance is an overriding
  50  * priority, as when methods of this class are optimized by the
  51  * runtime compiler, some or all checks (if any) may be elided. Hence,
  52  * the caller must not rely on the checks and corresponding
  53  * exceptions!
  54  *
  55  * @author John R. Rose
  56  * @see #getUnsafe
  57  */
  58 @AOTSafeClassInitializer
  59 public final class Unsafe {
  60 
  61     private static native void registerNatives();
  62     static {
  63         runtimeSetup();
  64     }
  65 
  66     /// BASE_OFFSET, INDEX_SCALE, and ADDRESS_SIZE fields are equivalent if the
  67     /// AOT initialized heap is reused, so just register natives
  68     @AOTRuntimeSetup
  69     private static void runtimeSetup() {
  70         registerNatives();
  71     }
  72 
  73     private Unsafe() {}
  74 
  75     private static final Unsafe theUnsafe = new Unsafe();
  76 
  77     /**
  78      * Provides the caller with the capability of performing unsafe
  79      * operations.
  80      *
  81      * <p>The returned {@code Unsafe} object should be carefully guarded
  82      * by the caller, since it can be used to read and write data at arbitrary
  83      * memory addresses.  It must never be passed to untrusted code.
  84      *
  85      * <p>Most methods in this class are very low-level, and correspond to a
  86      * small number of hardware instructions (on typical machines).  Compilers
  87      * are encouraged to optimize these methods accordingly.
  88      *
  89      * <p>Here is a suggested idiom for using unsafe operations:
  90      *
  91      * <pre> {@code
  92      * class MyTrustedClass {
  93      *   private static final Unsafe unsafe = Unsafe.getUnsafe();
  94      *   ...
  95      *   private long myCountAddress = ...;
  96      *   public int getCount() { return unsafe.getByte(myCountAddress); }
  97      * }}</pre>
  98      *
  99      * (It may assist compilers to make the local variable {@code final}.)
 100      */
 101     public static Unsafe getUnsafe() {
 102         return theUnsafe;
 103     }
 104 
 105     //--- peek and poke operations
 106     // (compilers should optimize these to memory ops)
 107 
 108     // These work on object fields in the Java heap.
 109     // They will not work on elements of packed arrays.
 110 
 111     /**
 112      * Fetches a value from a given Java variable.
 113      * More specifically, fetches a field or array element within the given
 114      * object {@code o} at the given offset, or (if {@code o} is null)
 115      * from the memory address whose numerical value is the given offset.
 116      * <p>
 117      * The results are undefined unless one of the following cases is true:
 118      * <ul>
 119      * <li>The offset was obtained from {@link #objectFieldOffset} on
 120      * the {@link java.lang.reflect.Field} of some Java field and the object
 121      * referred to by {@code o} is of a class compatible with that
 122      * field's class.
 123      *
 124      * <li>The offset and object reference {@code o} (either null or
 125      * non-null) were both obtained via {@link #staticFieldOffset}
 126      * and {@link #staticFieldBase} (respectively) from the
 127      * reflective {@link Field} representation of some Java field.
 128      *
 129      * <li>The object referred to by {@code o} is an array, and the offset
 130      * is an integer of the form {@code B+N*S}, where {@code N} is
 131      * a valid index into the array, and {@code B} and {@code S} are
 132      * the values obtained by {@link #arrayBaseOffset} and {@link
 133      * #arrayIndexScale} (respectively) from the array's class.  The value
 134      * referred to is the {@code N}<em>th</em> element of the array.
 135      *
 136      * </ul>
 137      * <p>
 138      * If one of the above cases is true, the call references a specific Java
 139      * variable (field or array element).  However, the results are undefined
 140      * if that variable is not in fact of the type returned by this method.
 141      * <p>
 142      * This method refers to a variable by means of two parameters, and so
 143      * it provides (in effect) a <em>double-register</em> addressing mode
 144      * for Java variables.  When the object reference is null, this method
 145      * uses its offset as an absolute address.  This is similar in operation
 146      * to methods such as {@link #getInt(long)}, which provide (in effect) a
 147      * <em>single-register</em> addressing mode for non-Java variables.
 148      * However, because Java variables may have a different layout in memory
 149      * from non-Java variables, programmers should not assume that these
 150      * two addressing modes are ever equivalent.  Also, programmers should
 151      * remember that offsets from the double-register addressing mode cannot
 152      * be portably confused with longs used in the single-register addressing
 153      * mode.
 154      *
 155      * @param o Java heap object in which the variable resides, if any, else
 156      *        null
 157      * @param offset indication of where the variable resides in a Java heap
 158      *        object, if any, else a memory address locating the variable
 159      *        statically
 160      * @return the value fetched from the indicated Java variable
 161      * @throws RuntimeException No defined exceptions are thrown, not even
 162      *         {@link NullPointerException}
 163      */
 164     @IntrinsicCandidate
 165     public native int getInt(Object o, long offset);
 166 
 167     /**
 168      * Stores a value into a given Java variable.
 169      * <p>
 170      * The first two parameters are interpreted exactly as with
 171      * {@link #getInt(Object, long)} to refer to a specific
 172      * Java variable (field or array element).  The given value
 173      * is stored into that variable.
 174      * <p>
 175      * The variable must be of the same type as the method
 176      * parameter {@code x}.
 177      *
 178      * @param o Java heap object in which the variable resides, if any, else
 179      *        null
 180      * @param offset indication of where the variable resides in a Java heap
 181      *        object, if any, else a memory address locating the variable
 182      *        statically
 183      * @param x the value to store into the indicated Java variable
 184      * @throws RuntimeException No defined exceptions are thrown, not even
 185      *         {@link NullPointerException}
 186      */
 187     @IntrinsicCandidate
 188     public native void putInt(Object o, long offset, int x);
 189 
 190 
 191     /**
 192      * Returns true if the given field is flattened.
 193      */
 194     public boolean isFlatField(Field f) {
 195         if (f == null) {
 196             throw new NullPointerException();
 197         }
 198         return isFlatField0(f);
 199     }
 200 
 201     private native boolean isFlatField0(Object o);
 202 
 203     /* Returns true if the given field has a null marker
 204      * <p>
 205      * Nullable flat fields are stored in a flattened representation
 206      * and have an associated null marker to indicate if the the field value is
 207      * null or the one stored with the flat representation
 208      */
 209 
 210     public boolean hasNullMarker(Field f) {
 211         if (f == null) {
 212             throw new NullPointerException();
 213         }
 214         return hasNullMarker0(f);
 215     }
 216 
 217     private native boolean hasNullMarker0(Object o);
 218 
 219     /* Returns the offset of the null marker of the field,
 220     * or -1 if the field doesn't have a null marker
 221     */
 222 
 223     public int nullMarkerOffset(Field f) {
 224         if (f == null) {
 225             throw new NullPointerException();
 226         }
 227         return nullMarkerOffset0(f);
 228     }
 229 
 230     private native int nullMarkerOffset0(Object o);
 231 
 232     public static final int NON_FLAT_LAYOUT = 0;
 233 
 234     /* Reports the kind of layout used for an element in the storage
 235      * allocation of the given array. Do not expect to perform any logic
 236      * or layout control with this value, it is just an opaque token
 237      * used for performance reasons.
 238      *
 239      * A layout of 0 indicates this array is not flat.
 240      */
 241     public int arrayLayout(Object[] array) {
 242         if (array == null) {
 243             throw new NullPointerException();
 244         }
 245         return arrayLayout0(array);
 246     }
 247 
 248     @IntrinsicCandidate
 249     private native int arrayLayout0(Object[] array);
 250 
 251 
 252     /* Reports the kind of layout used for a given field in the storage
 253      * allocation of its class.  Do not expect to perform any logic
 254      * or layout control with this value, it is just an opaque token
 255      * used for performance reasons.
 256      *
 257      * A layout of 0 indicates this field is not flat.
 258      */
 259     public int fieldLayout(Field f) {
 260         if (f == null) {
 261             throw new NullPointerException();
 262         }
 263         return fieldLayout0(f);
 264     }
 265 
 266     private native int fieldLayout0(Object o);
 267 
 268     public native Object[] newSpecialArray(Class<?> componentType,
 269                                                   int length, int layoutKind);
 270 
 271     /**
 272      * Fetches a reference value from a given Java variable.
 273      * This method can return a reference to either an object or value
 274      * or a null reference.
 275      *
 276      * @see #getInt(Object, long)
 277      */
 278     @IntrinsicCandidate
 279     public native Object getReference(Object o, long offset);
 280 
 281     /**
 282      * Stores a reference value into a given Java variable.
 283      * This method can store a reference to either an object or value
 284      * or a null reference.
 285      * <p>
 286      * Unless the reference {@code x} being stored is either null
 287      * or matches the field type, the results are undefined.
 288      * If the reference {@code o} is non-null, card marks or
 289      * other store barriers for that object (if the VM requires them)
 290      * are updated.
 291      * @see #putInt(Object, long, int)
 292      */
 293     @IntrinsicCandidate
 294     public native void putReference(Object o, long offset, Object x);
 295 
 296     /**
 297      * Fetches a value of type {@code <V>} from a given Java variable.
 298      * More specifically, fetches a field or array element within the given
 299      * {@code o} object at the given offset, or (if {@code o} is null)
 300      * from the memory address whose numerical value is the given offset.
 301      *
 302      * @apiNote
 303      * The returned object is newly allocated into the heap, because flat
 304      * values lack object headers and thus can't be used as objects directly.
 305      *
 306      * @param o Java heap object in which the variable resides, if any, else
 307      *        null
 308      * @param offset indication of where the variable resides in a Java heap
 309      *        object, if any, else a memory address locating the variable
 310      *        statically
 311      * @param layoutKind opaque value used by the VM to know the layout
 312      *        the field or array element. This value must be retrieved with
 313      *        {@link #fieldLayout} or {@link #arrayLayout}.
 314      * @param valueType value type
 315      * @param <V> the type of a value
 316      * @return the value fetched from the indicated Java variable
 317      * @throws RuntimeException No defined exceptions are thrown, not even
 318      *         {@link NullPointerException}
 319      */
 320     @IntrinsicCandidate
 321     public native <V> V getFlatValue(Object o, long offset, int layoutKind, Class<?> valueType);
 322 
 323     /**
 324      * Stores the given value into a given Java variable.
 325      *
 326      * Unless the reference {@code o} being stored is either null
 327      * or matches the field type, the results are undefined.
 328      *
 329      * @param o Java heap object in which the variable resides, if any, else
 330      *        null
 331      * @param offset indication of where the variable resides in a Java heap
 332      *        object, if any, else a memory address locating the variable
 333      *        statically
 334      * @param layoutKind opaque value used by the VM to know the layout
 335      *        the field or array element. This value must be retrieved with
 336      *        {@link #fieldLayout} or {@link #arrayLayout}.
 337      * @param valueType value type
 338      * @param v the value to store into the indicated Java variable
 339      * @param <V> the type of a value
 340      * @throws RuntimeException No defined exceptions are thrown, not even
 341      *         {@link NullPointerException}
 342      */
 343     @IntrinsicCandidate
 344     public native <V> void putFlatValue(Object o, long offset, int layoutKind, Class<?> valueType, V v);
 345 
 346     /**
 347      * Returns an object instance with a private buffered value whose layout
 348      * and contents is exactly the given value instance.  The return object
 349      * is in the larval state that can be updated using the unsafe put operation.
 350      *
 351      * @param value a value instance
 352      * @param <V> the type of the given value instance
 353      */
 354     @IntrinsicCandidate
 355     public native <V> V makePrivateBuffer(V value);
 356 
 357     /**
 358      * Exits the larval state and returns a value instance.
 359      *
 360      * @param value a value instance
 361      * @param <V> the type of the given value instance
 362      */
 363     @IntrinsicCandidate
 364     public native <V> V finishPrivateBuffer(V value);
 365 
 366     /**
 367      * Returns the header size of the given value type.
 368      *
 369      * @param valueType value type
 370      * @return the header size of the value type
 371      */
 372     public native <V> long valueHeaderSize(Class<V> valueType);
 373 
 374     /** @see #getInt(Object, long) */
 375     @IntrinsicCandidate
 376     public native boolean getBoolean(Object o, long offset);
 377 
 378     /** @see #putInt(Object, long, int) */
 379     @IntrinsicCandidate
 380     public native void    putBoolean(Object o, long offset, boolean x);
 381 
 382     /** @see #getInt(Object, long) */
 383     @IntrinsicCandidate
 384     public native byte    getByte(Object o, long offset);
 385 
 386     /** @see #putInt(Object, long, int) */
 387     @IntrinsicCandidate
 388     public native void    putByte(Object o, long offset, byte x);
 389 
 390     /** @see #getInt(Object, long) */
 391     @IntrinsicCandidate
 392     public native short   getShort(Object o, long offset);
 393 
 394     /** @see #putInt(Object, long, int) */
 395     @IntrinsicCandidate
 396     public native void    putShort(Object o, long offset, short x);
 397 
 398     /** @see #getInt(Object, long) */
 399     @IntrinsicCandidate
 400     public native char    getChar(Object o, long offset);
 401 
 402     /** @see #putInt(Object, long, int) */
 403     @IntrinsicCandidate
 404     public native void    putChar(Object o, long offset, char x);
 405 
 406     /** @see #getInt(Object, long) */
 407     @IntrinsicCandidate
 408     public native long    getLong(Object o, long offset);
 409 
 410     /** @see #putInt(Object, long, int) */
 411     @IntrinsicCandidate
 412     public native void    putLong(Object o, long offset, long x);
 413 
 414     /** @see #getInt(Object, long) */
 415     @IntrinsicCandidate
 416     public native float   getFloat(Object o, long offset);
 417 
 418     /** @see #putInt(Object, long, int) */
 419     @IntrinsicCandidate
 420     public native void    putFloat(Object o, long offset, float x);
 421 
 422     /** @see #getInt(Object, long) */
 423     @IntrinsicCandidate
 424     public native double  getDouble(Object o, long offset);
 425 
 426     /** @see #putInt(Object, long, int) */
 427     @IntrinsicCandidate
 428     public native void    putDouble(Object o, long offset, double x);
 429 
 430     /**
 431      * Fetches a native pointer from a given memory address.  If the address is
 432      * zero, or does not point into a block obtained from {@link
 433      * #allocateMemory}, the results are undefined.
 434      *
 435      * <p>If the native pointer is less than 64 bits wide, it is extended as
 436      * an unsigned number to a Java long.  The pointer may be indexed by any
 437      * given byte offset, simply by adding that offset (as a simple integer) to
 438      * the long representing the pointer.  The number of bytes actually read
 439      * from the target address may be determined by consulting {@link
 440      * #addressSize}.
 441      *
 442      * @see #allocateMemory
 443      * @see #getInt(Object, long)
 444      */
 445     @ForceInline
 446     public long getAddress(Object o, long offset) {
 447         if (ADDRESS_SIZE == 4) {
 448             return Integer.toUnsignedLong(getInt(o, offset));
 449         } else {
 450             return getLong(o, offset);
 451         }
 452     }
 453 
 454     /**
 455      * Stores a native pointer into a given memory address.  If the address is
 456      * zero, or does not point into a block obtained from {@link
 457      * #allocateMemory}, the results are undefined.
 458      *
 459      * <p>The number of bytes actually written at the target address may be
 460      * determined by consulting {@link #addressSize}.
 461      *
 462      * @see #allocateMemory
 463      * @see #putInt(Object, long, int)
 464      */
 465     @ForceInline
 466     public void putAddress(Object o, long offset, long x) {
 467         if (ADDRESS_SIZE == 4) {
 468             putInt(o, offset, (int)x);
 469         } else {
 470             putLong(o, offset, x);
 471         }
 472     }
 473 
 474     // These read VM internal data.
 475 
 476     /**
 477      * Fetches an uncompressed reference value from a given native variable
 478      * ignoring the VM's compressed references mode.
 479      *
 480      * @param address a memory address locating the variable
 481      * @return the value fetched from the indicated native variable
 482      */
 483     public native Object getUncompressedObject(long address);
 484 
 485     // These work on values in the C heap.
 486 
 487     /**
 488      * Fetches a value from a given memory address.  If the address is zero, or
 489      * does not point into a block obtained from {@link #allocateMemory}, the
 490      * results are undefined.
 491      *
 492      * @see #allocateMemory
 493      */
 494     @ForceInline
 495     public byte getByte(long address) {
 496         return getByte(null, address);
 497     }
 498 
 499     /**
 500      * Stores a value into a given memory address.  If the address is zero, or
 501      * does not point into a block obtained from {@link #allocateMemory}, the
 502      * results are undefined.
 503      *
 504      * @see #getByte(long)
 505      */
 506     @ForceInline
 507     public void putByte(long address, byte x) {
 508         putByte(null, address, x);
 509     }
 510 
 511     /** @see #getByte(long) */
 512     @ForceInline
 513     public short getShort(long address) {
 514         return getShort(null, address);
 515     }
 516 
 517     /** @see #putByte(long, byte) */
 518     @ForceInline
 519     public void putShort(long address, short x) {
 520         putShort(null, address, x);
 521     }
 522 
 523     /** @see #getByte(long) */
 524     @ForceInline
 525     public char getChar(long address) {
 526         return getChar(null, address);
 527     }
 528 
 529     /** @see #putByte(long, byte) */
 530     @ForceInline
 531     public void putChar(long address, char x) {
 532         putChar(null, address, x);
 533     }
 534 
 535     /** @see #getByte(long) */
 536     @ForceInline
 537     public int getInt(long address) {
 538         return getInt(null, address);
 539     }
 540 
 541     /** @see #putByte(long, byte) */
 542     @ForceInline
 543     public void putInt(long address, int x) {
 544         putInt(null, address, x);
 545     }
 546 
 547     /** @see #getByte(long) */
 548     @ForceInline
 549     public long getLong(long address) {
 550         return getLong(null, address);
 551     }
 552 
 553     /** @see #putByte(long, byte) */
 554     @ForceInline
 555     public void putLong(long address, long x) {
 556         putLong(null, address, x);
 557     }
 558 
 559     /** @see #getByte(long) */
 560     @ForceInline
 561     public float getFloat(long address) {
 562         return getFloat(null, address);
 563     }
 564 
 565     /** @see #putByte(long, byte) */
 566     @ForceInline
 567     public void putFloat(long address, float x) {
 568         putFloat(null, address, x);
 569     }
 570 
 571     /** @see #getByte(long) */
 572     @ForceInline
 573     public double getDouble(long address) {
 574         return getDouble(null, address);
 575     }
 576 
 577     /** @see #putByte(long, byte) */
 578     @ForceInline
 579     public void putDouble(long address, double x) {
 580         putDouble(null, address, x);
 581     }
 582 
 583     /** @see #getAddress(Object, long) */
 584     @ForceInline
 585     public long getAddress(long address) {
 586         return getAddress(null, address);
 587     }
 588 
 589     /** @see #putAddress(Object, long, long) */
 590     @ForceInline
 591     public void putAddress(long address, long x) {
 592         putAddress(null, address, x);
 593     }
 594 
 595 
 596 
 597     //--- helper methods for validating various types of objects/values
 598 
 599     /**
 600      * Create an exception reflecting that some of the input was invalid
 601      *
 602      * <em>Note:</em> It is the responsibility of the caller to make
 603      * sure arguments are checked before the methods are called. While
 604      * some rudimentary checks are performed on the input, the checks
 605      * are best effort and when performance is an overriding priority,
 606      * as when methods of this class are optimized by the runtime
 607      * compiler, some or all checks (if any) may be elided. Hence, the
 608      * caller must not rely on the checks and corresponding
 609      * exceptions!
 610      *
 611      * @return an exception object
 612      */
 613     private RuntimeException invalidInput() {
 614         return new IllegalArgumentException();
 615     }
 616 
 617     /**
 618      * Check if a value is 32-bit clean (32 MSB are all zero)
 619      *
 620      * @param value the 64-bit value to check
 621      *
 622      * @return true if the value is 32-bit clean
 623      */
 624     private boolean is32BitClean(long value) {
 625         return value >>> 32 == 0;
 626     }
 627 
 628     /**
 629      * Check the validity of a size (the equivalent of a size_t)
 630      *
 631      * @throws RuntimeException if the size is invalid
 632      *         (<em>Note:</em> after optimization, invalid inputs may
 633      *         go undetected, which will lead to unpredictable
 634      *         behavior)
 635      */
 636     private void checkSize(long size) {
 637         if (ADDRESS_SIZE == 4) {
 638             // Note: this will also check for negative sizes
 639             if (!is32BitClean(size)) {
 640                 throw invalidInput();
 641             }
 642         } else if (size < 0) {
 643             throw invalidInput();
 644         }
 645     }
 646 
 647     /**
 648      * Check the validity of a native address (the equivalent of void*)
 649      *
 650      * @throws RuntimeException if the address is invalid
 651      *         (<em>Note:</em> after optimization, invalid inputs may
 652      *         go undetected, which will lead to unpredictable
 653      *         behavior)
 654      */
 655     private void checkNativeAddress(long address) {
 656         if (ADDRESS_SIZE == 4) {
 657             // Accept both zero and sign extended pointers. A valid
 658             // pointer will, after the +1 below, either have produced
 659             // the value 0x0 or 0x1. Masking off the low bit allows
 660             // for testing against 0.
 661             if ((((address >> 32) + 1) & ~1) != 0) {
 662                 throw invalidInput();
 663             }
 664         }
 665     }
 666 
 667     /**
 668      * Check the validity of an offset, relative to a base object
 669      *
 670      * @param o the base object
 671      * @param offset the offset to check
 672      *
 673      * @throws RuntimeException if the size is invalid
 674      *         (<em>Note:</em> after optimization, invalid inputs may
 675      *         go undetected, which will lead to unpredictable
 676      *         behavior)
 677      */
 678     private void checkOffset(Object o, long offset) {
 679         if (ADDRESS_SIZE == 4) {
 680             // Note: this will also check for negative offsets
 681             if (!is32BitClean(offset)) {
 682                 throw invalidInput();
 683             }
 684         } else if (offset < 0) {
 685             throw invalidInput();
 686         }
 687     }
 688 
 689     /**
 690      * Check the validity of a double-register pointer
 691      *
 692      * Note: This code deliberately does *not* check for NPE for (at
 693      * least) three reasons:
 694      *
 695      * 1) NPE is not just NULL/0 - there is a range of values all
 696      * resulting in an NPE, which is not trivial to check for
 697      *
 698      * 2) It is the responsibility of the callers of Unsafe methods
 699      * to verify the input, so throwing an exception here is not really
 700      * useful - passing in a NULL pointer is a critical error and the
 701      * must not expect an exception to be thrown anyway.
 702      *
 703      * 3) the actual operations will detect NULL pointers anyway by
 704      * means of traps and signals (like SIGSEGV).
 705      *
 706      * @param o Java heap object, or null
 707      * @param offset indication of where the variable resides in a Java heap
 708      *        object, if any, else a memory address locating the variable
 709      *        statically
 710      *
 711      * @throws RuntimeException if the pointer is invalid
 712      *         (<em>Note:</em> after optimization, invalid inputs may
 713      *         go undetected, which will lead to unpredictable
 714      *         behavior)
 715      */
 716     private void checkPointer(Object o, long offset) {
 717         if (o == null) {
 718             checkNativeAddress(offset);
 719         } else {
 720             checkOffset(o, offset);
 721         }
 722     }
 723 
 724     /**
 725      * Check if a type is a primitive array type
 726      *
 727      * @param c the type to check
 728      *
 729      * @return true if the type is a primitive array type
 730      */
 731     private void checkPrimitiveArray(Class<?> c) {
 732         Class<?> componentType = c.getComponentType();
 733         if (componentType == null || !componentType.isPrimitive()) {
 734             throw invalidInput();
 735         }
 736     }
 737 
 738     /**
 739      * Check that a pointer is a valid primitive array type pointer
 740      *
 741      * Note: pointers off-heap are considered to be primitive arrays
 742      *
 743      * @throws RuntimeException if the pointer is invalid
 744      *         (<em>Note:</em> after optimization, invalid inputs may
 745      *         go undetected, which will lead to unpredictable
 746      *         behavior)
 747      */
 748     private void checkPrimitivePointer(Object o, long offset) {
 749         checkPointer(o, offset);
 750 
 751         if (o != null) {
 752             // If on heap, it must be a primitive array
 753             checkPrimitiveArray(o.getClass());
 754         }
 755     }
 756 
 757 
 758     //--- wrappers for malloc, realloc, free:
 759 
 760     /**
 761      * Round up allocation size to a multiple of HeapWordSize.
 762      */
 763     private long alignToHeapWordSize(long bytes) {
 764         if (bytes >= 0) {
 765             return (bytes + ADDRESS_SIZE - 1) & ~(ADDRESS_SIZE - 1);
 766         } else {
 767             throw invalidInput();
 768         }
 769     }
 770 
 771     /**
 772      * Allocates a new block of native memory, of the given size in bytes.  The
 773      * contents of the memory are uninitialized; they will generally be
 774      * garbage.  The resulting native pointer will be zero if and only if the
 775      * requested size is zero.  The resulting native pointer will be aligned for
 776      * all value types.   Dispose of this memory by calling {@link #freeMemory}
 777      * or resize it with {@link #reallocateMemory}.
 778      *
 779      * <em>Note:</em> It is the responsibility of the caller to make
 780      * sure arguments are checked before the methods are called. While
 781      * some rudimentary checks are performed on the input, the checks
 782      * are best effort and when performance is an overriding priority,
 783      * as when methods of this class are optimized by the runtime
 784      * compiler, some or all checks (if any) may be elided. Hence, the
 785      * caller must not rely on the checks and corresponding
 786      * exceptions!
 787      *
 788      * @throws RuntimeException if the size is negative or too large
 789      *         for the native size_t type
 790      *
 791      * @throws OutOfMemoryError if the allocation is refused by the system
 792      *
 793      * @see #getByte(long)
 794      * @see #putByte(long, byte)
 795      */
 796     public long allocateMemory(long bytes) {
 797         bytes = alignToHeapWordSize(bytes);
 798 
 799         allocateMemoryChecks(bytes);
 800 
 801         if (bytes == 0) {
 802             return 0;
 803         }
 804 
 805         long p = allocateMemory0(bytes);
 806         if (p == 0) {
 807             throw new OutOfMemoryError("Unable to allocate " + bytes + " bytes");
 808         }
 809 
 810         return p;
 811     }
 812 
 813     /**
 814      * Validate the arguments to allocateMemory
 815      *
 816      * @throws RuntimeException if the arguments are invalid
 817      *         (<em>Note:</em> after optimization, invalid inputs may
 818      *         go undetected, which will lead to unpredictable
 819      *         behavior)
 820      */
 821     private void allocateMemoryChecks(long bytes) {
 822         checkSize(bytes);
 823     }
 824 
 825     /**
 826      * Resizes a new block of native memory, to the given size in bytes.  The
 827      * contents of the new block past the size of the old block are
 828      * uninitialized; they will generally be garbage.  The resulting native
 829      * pointer will be zero if and only if the requested size is zero.  The
 830      * resulting native pointer will be aligned for all value types.  Dispose
 831      * of this memory by calling {@link #freeMemory}, or resize it with {@link
 832      * #reallocateMemory}.  The address passed to this method may be null, in
 833      * which case an allocation will be performed.
 834      *
 835      * <em>Note:</em> It is the responsibility of the caller to make
 836      * sure arguments are checked before the methods are called. While
 837      * some rudimentary checks are performed on the input, the checks
 838      * are best effort and when performance is an overriding priority,
 839      * as when methods of this class are optimized by the runtime
 840      * compiler, some or all checks (if any) may be elided. Hence, the
 841      * caller must not rely on the checks and corresponding
 842      * exceptions!
 843      *
 844      * @throws RuntimeException if the size is negative or too large
 845      *         for the native size_t type
 846      *
 847      * @throws OutOfMemoryError if the allocation is refused by the system
 848      *
 849      * @see #allocateMemory
 850      */
 851     public long reallocateMemory(long address, long bytes) {
 852         bytes = alignToHeapWordSize(bytes);
 853 
 854         reallocateMemoryChecks(address, bytes);
 855 
 856         if (bytes == 0) {
 857             freeMemory(address);
 858             return 0;
 859         }
 860 
 861         long p = (address == 0) ? allocateMemory0(bytes) : reallocateMemory0(address, bytes);
 862         if (p == 0) {
 863             throw new OutOfMemoryError("Unable to allocate " + bytes + " bytes");
 864         }
 865 
 866         return p;
 867     }
 868 
 869     /**
 870      * Validate the arguments to reallocateMemory
 871      *
 872      * @throws RuntimeException if the arguments are invalid
 873      *         (<em>Note:</em> after optimization, invalid inputs may
 874      *         go undetected, which will lead to unpredictable
 875      *         behavior)
 876      */
 877     private void reallocateMemoryChecks(long address, long bytes) {
 878         checkPointer(null, address);
 879         checkSize(bytes);
 880     }
 881 
 882     /**
 883      * Sets all bytes in a given block of memory to a fixed value
 884      * (usually zero).
 885      *
 886      * <p>This method determines a block's base address by means of two parameters,
 887      * and so it provides (in effect) a <em>double-register</em> addressing mode,
 888      * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
 889      * the offset supplies an absolute base address.
 890      *
 891      * <p>The stores are in coherent (atomic) units of a size determined
 892      * by the address and length parameters.  If the effective address and
 893      * length are all even modulo 8, the stores take place in 'long' units.
 894      * If the effective address and length are (resp.) even modulo 4 or 2,
 895      * the stores take place in units of 'int' or 'short'.
 896      *
 897      * <em>Note:</em> It is the responsibility of the caller to make
 898      * sure arguments are checked before the methods are called. While
 899      * some rudimentary checks are performed on the input, the checks
 900      * are best effort and when performance is an overriding priority,
 901      * as when methods of this class are optimized by the runtime
 902      * compiler, some or all checks (if any) may be elided. Hence, the
 903      * caller must not rely on the checks and corresponding
 904      * exceptions!
 905      *
 906      * @throws RuntimeException if any of the arguments is invalid
 907      *
 908      * @since 1.7
 909      */
 910     public void setMemory(Object o, long offset, long bytes, byte value) {
 911         setMemoryChecks(o, offset, bytes, value);
 912 
 913         if (bytes == 0) {
 914             return;
 915         }
 916 
 917         setMemory0(o, offset, bytes, value);
 918     }
 919 
 920     /**
 921      * Sets all bytes in a given block of memory to a fixed value
 922      * (usually zero).  This provides a <em>single-register</em> addressing mode,
 923      * as discussed in {@link #getInt(Object,long)}.
 924      *
 925      * <p>Equivalent to {@code setMemory(null, address, bytes, value)}.
 926      */
 927     public void setMemory(long address, long bytes, byte value) {
 928         setMemory(null, address, bytes, value);
 929     }
 930 
 931     /**
 932      * Validate the arguments to setMemory
 933      *
 934      * @throws RuntimeException if the arguments are invalid
 935      *         (<em>Note:</em> after optimization, invalid inputs may
 936      *         go undetected, which will lead to unpredictable
 937      *         behavior)
 938      */
 939     private void setMemoryChecks(Object o, long offset, long bytes, byte value) {
 940         checkPrimitivePointer(o, offset);
 941         checkSize(bytes);
 942     }
 943 
 944     /**
 945      * Sets all bytes in a given block of memory to a copy of another
 946      * block.
 947      *
 948      * <p>This method determines each block's base address by means of two parameters,
 949      * and so it provides (in effect) a <em>double-register</em> addressing mode,
 950      * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
 951      * the offset supplies an absolute base address.
 952      *
 953      * <p>The transfers are in coherent (atomic) units of a size determined
 954      * by the address and length parameters.  If the effective addresses and
 955      * length are all even modulo 8, the transfer takes place in 'long' units.
 956      * If the effective addresses and length are (resp.) even modulo 4 or 2,
 957      * the transfer takes place in units of 'int' or 'short'.
 958      *
 959      * <em>Note:</em> It is the responsibility of the caller to make
 960      * sure arguments are checked before the methods are called. While
 961      * some rudimentary checks are performed on the input, the checks
 962      * are best effort and when performance is an overriding priority,
 963      * as when methods of this class are optimized by the runtime
 964      * compiler, some or all checks (if any) may be elided. Hence, the
 965      * caller must not rely on the checks and corresponding
 966      * exceptions!
 967      *
 968      * @throws RuntimeException if any of the arguments is invalid
 969      *
 970      * @since 1.7
 971      */
 972     public void copyMemory(Object srcBase, long srcOffset,
 973                            Object destBase, long destOffset,
 974                            long bytes) {
 975         copyMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes);
 976 
 977         if (bytes == 0) {
 978             return;
 979         }
 980 
 981         copyMemory0(srcBase, srcOffset, destBase, destOffset, bytes);
 982     }
 983 
 984     /**
 985      * Sets all bytes in a given block of memory to a copy of another
 986      * block.  This provides a <em>single-register</em> addressing mode,
 987      * as discussed in {@link #getInt(Object,long)}.
 988      *
 989      * Equivalent to {@code copyMemory(null, srcAddress, null, destAddress, bytes)}.
 990      */
 991     public void copyMemory(long srcAddress, long destAddress, long bytes) {
 992         copyMemory(null, srcAddress, null, destAddress, bytes);
 993     }
 994 
 995     /**
 996      * Validate the arguments to copyMemory
 997      *
 998      * @throws RuntimeException if any of the arguments is invalid
 999      *         (<em>Note:</em> after optimization, invalid inputs may
1000      *         go undetected, which will lead to unpredictable
1001      *         behavior)
1002      */
1003     private void copyMemoryChecks(Object srcBase, long srcOffset,
1004                                   Object destBase, long destOffset,
1005                                   long bytes) {
1006         checkSize(bytes);
1007         checkPrimitivePointer(srcBase, srcOffset);
1008         checkPrimitivePointer(destBase, destOffset);
1009     }
1010 
1011     /**
1012      * Copies all elements from one block of memory to another block,
1013      * *unconditionally* byte swapping the elements on the fly.
1014      *
1015      * <p>This method determines each block's base address by means of two parameters,
1016      * and so it provides (in effect) a <em>double-register</em> addressing mode,
1017      * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
1018      * the offset supplies an absolute base address.
1019      *
1020      * <em>Note:</em> It is the responsibility of the caller to make
1021      * sure arguments are checked before the methods are called. While
1022      * some rudimentary checks are performed on the input, the checks
1023      * are best effort and when performance is an overriding priority,
1024      * as when methods of this class are optimized by the runtime
1025      * compiler, some or all checks (if any) may be elided. Hence, the
1026      * caller must not rely on the checks and corresponding
1027      * exceptions!
1028      *
1029      * @throws RuntimeException if any of the arguments is invalid
1030      *
1031      * @since 9
1032      */
1033     public void copySwapMemory(Object srcBase, long srcOffset,
1034                                Object destBase, long destOffset,
1035                                long bytes, long elemSize) {
1036         copySwapMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
1037 
1038         if (bytes == 0) {
1039             return;
1040         }
1041 
1042         copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
1043     }
1044 
1045     private void copySwapMemoryChecks(Object srcBase, long srcOffset,
1046                                       Object destBase, long destOffset,
1047                                       long bytes, long elemSize) {
1048         checkSize(bytes);
1049 
1050         if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
1051             throw invalidInput();
1052         }
1053         if (bytes % elemSize != 0) {
1054             throw invalidInput();
1055         }
1056 
1057         checkPrimitivePointer(srcBase, srcOffset);
1058         checkPrimitivePointer(destBase, destOffset);
1059     }
1060 
1061     /**
1062      * Copies all elements from one block of memory to another block, byte swapping the
1063      * elements on the fly.
1064      *
1065      * This provides a <em>single-register</em> addressing mode, as
1066      * discussed in {@link #getInt(Object,long)}.
1067      *
1068      * Equivalent to {@code copySwapMemory(null, srcAddress, null, destAddress, bytes, elemSize)}.
1069      */
1070     public void copySwapMemory(long srcAddress, long destAddress, long bytes, long elemSize) {
1071         copySwapMemory(null, srcAddress, null, destAddress, bytes, elemSize);
1072     }
1073 
1074     /**
1075      * Disposes of a block of native memory, as obtained from {@link
1076      * #allocateMemory} or {@link #reallocateMemory}.  The address passed to
1077      * this method may be null, in which case no action is taken.
1078      *
1079      * <em>Note:</em> It is the responsibility of the caller to make
1080      * sure arguments are checked before the methods are called. While
1081      * some rudimentary checks are performed on the input, the checks
1082      * are best effort and when performance is an overriding priority,
1083      * as when methods of this class are optimized by the runtime
1084      * compiler, some or all checks (if any) may be elided. Hence, the
1085      * caller must not rely on the checks and corresponding
1086      * exceptions!
1087      *
1088      * @throws RuntimeException if any of the arguments is invalid
1089      *
1090      * @see #allocateMemory
1091      */
1092     public void freeMemory(long address) {
1093         freeMemoryChecks(address);
1094 
1095         if (address == 0) {
1096             return;
1097         }
1098 
1099         freeMemory0(address);
1100     }
1101 
1102     /**
1103      * Validate the arguments to freeMemory
1104      *
1105      * @throws RuntimeException if the arguments are invalid
1106      *         (<em>Note:</em> after optimization, invalid inputs may
1107      *         go undetected, which will lead to unpredictable
1108      *         behavior)
1109      */
1110     private void freeMemoryChecks(long address) {
1111         checkPointer(null, address);
1112     }
1113 
1114     /**
1115      * Ensure writeback of a specified virtual memory address range
1116      * from cache to physical memory. All bytes in the address range
1117      * are guaranteed to have been written back to physical memory on
1118      * return from this call i.e. subsequently executed store
1119      * instructions are guaranteed not to be visible before the
1120      * writeback is completed.
1121      *
1122      * @param address
1123      *        the lowest byte address that must be guaranteed written
1124      *        back to memory. bytes at lower addresses may also be
1125      *        written back.
1126      *
1127      * @param length
1128      *        the length in bytes of the region starting at address
1129      *        that must be guaranteed written back to memory.
1130      *
1131      * @throws RuntimeException if memory writeback is not supported
1132      *         on the current hardware of if the arguments are invalid.
1133      *         (<em>Note:</em> after optimization, invalid inputs may
1134      *         go undetected, which will lead to unpredictable
1135      *         behavior)
1136      *
1137      * @since 14
1138      */
1139 
1140     public void writebackMemory(long address, long length) {
1141         checkWritebackEnabled();
1142         checkWritebackMemory(address, length);
1143 
1144         // perform any required pre-writeback barrier
1145         writebackPreSync0();
1146 
1147         // write back one cache line at a time
1148         long line = dataCacheLineAlignDown(address);
1149         long end = address + length;
1150         while (line < end) {
1151             writeback0(line);
1152             line += dataCacheLineFlushSize();
1153         }
1154 
1155         // perform any required post-writeback barrier
1156         writebackPostSync0();
1157     }
1158 
1159     /**
1160      * Validate the arguments to writebackMemory
1161      *
1162      * @throws RuntimeException if the arguments are invalid
1163      *         (<em>Note:</em> after optimization, invalid inputs may
1164      *         go undetected, which will lead to unpredictable
1165      *         behavior)
1166      */
1167     private void checkWritebackMemory(long address, long length) {
1168         checkNativeAddress(address);
1169         checkSize(length);
1170     }
1171 
1172     /**
1173      * Validate that the current hardware supports memory writeback.
1174      * (<em>Note:</em> this is a belt and braces check.  Clients are
1175      * expected to test whether writeback is enabled by calling
1176      * ({@link isWritebackEnabled #isWritebackEnabled} and avoid
1177      * calling method {@link writeback #writeback} if it is disabled).
1178      *
1179      *
1180      * @throws RuntimeException if memory writeback is not supported
1181      */
1182     private void checkWritebackEnabled() {
1183         if (!isWritebackEnabled()) {
1184             throw new RuntimeException("writebackMemory not enabled!");
1185         }
1186     }
1187 
1188     /**
1189      * force writeback of an individual cache line.
1190      *
1191      * @param address
1192      *        the start address of the cache line to be written back
1193      */
1194     @IntrinsicCandidate
1195     private native void writeback0(long address);
1196 
1197      /**
1198       * Serialize writeback operations relative to preceding memory writes.
1199       */
1200     @IntrinsicCandidate
1201     private native void writebackPreSync0();
1202 
1203      /**
1204       * Serialize writeback operations relative to following memory writes.
1205       */
1206     @IntrinsicCandidate
1207     private native void writebackPostSync0();
1208 
1209     //--- random queries
1210 
1211     /**
1212      * This constant differs from all results that will ever be returned from
1213      * {@link #staticFieldOffset}, {@link #objectFieldOffset},
1214      * or {@link #arrayBaseOffset}.
1215      * <p>
1216      * The static type is @code long} to emphasize that long arithmetic should
1217      * always be used for offset calculations to avoid overflows.
1218      */
1219     public static final long INVALID_FIELD_OFFSET = -1;
1220 
1221     /**
1222      * Reports the location of a given field in the storage allocation of its
1223      * class.  Do not expect to perform any sort of arithmetic on this offset;
1224      * it is just a cookie which is passed to the unsafe heap memory accessors.
1225      *
1226      * <p>Any given field will always have the same offset and base, and no
1227      * two distinct fields of the same class will ever have the same offset
1228      * and base.
1229      *
1230      * <p>As of 1.4.1, offsets for fields are represented as long values,
1231      * although the Sun JVM does not use the most significant 32 bits.
1232      * However, JVM implementations which store static fields at absolute
1233      * addresses can use long offsets and null base pointers to express
1234      * the field locations in a form usable by {@link #getInt(Object,long)}.
1235      * Therefore, code which will be ported to such JVMs on 64-bit platforms
1236      * must preserve all bits of static field offsets.
1237      *
1238      * @throws NullPointerException if the field is {@code null}
1239      * @throws IllegalArgumentException if the field is static
1240      * @see #getInt(Object, long)
1241      */
1242     public long objectFieldOffset(Field f) {
1243         if (f == null) {
1244             throw new NullPointerException();
1245         }
1246 
1247         return objectFieldOffset0(f);
1248     }
1249 
1250     /**
1251      * (For compile-time known instance fields in JDK code only) Reports the
1252      * location of the field with a given name in the storage allocation of its
1253      * class.
1254      * <p>
1255      * This API is used to avoid creating reflective Objects in Java code at
1256      * startup.  This should not be used to find fields in non-trusted code.
1257      * Use the {@link #objectFieldOffset(Field) Field}-accepting version for
1258      * arbitrary fields instead.
1259      *
1260      * @throws NullPointerException if any parameter is {@code null}.
1261      * @throws InternalError if the presumably known field couldn't be found
1262      *
1263      * @see #objectFieldOffset(Field)
1264      */
1265     public long objectFieldOffset(Class<?> c, String name) {
1266         if (c == null || name == null) {
1267             throw new NullPointerException();
1268         }
1269 
1270         long result = knownObjectFieldOffset0(c, name);
1271         if (result < 0) {
1272             String type = switch ((int) result) {
1273                 case -2 -> "a static field";
1274                 case -1 -> "not found";
1275                 default -> "unknown";
1276             };
1277             throw new InternalError("Field %s.%s %s".formatted(c.getTypeName(), name, type));
1278         }
1279         return result;
1280     }
1281 
1282     /**
1283      * Reports the location of a given static field, in conjunction with {@link
1284      * #staticFieldBase}.
1285      * <p>Do not expect to perform any sort of arithmetic on this offset;
1286      * it is just a cookie which is passed to the unsafe heap memory accessors.
1287      *
1288      * <p>Any given field will always have the same offset, and no two distinct
1289      * fields of the same class will ever have the same offset.
1290      *
1291      * <p>As of 1.4.1, offsets for fields are represented as long values,
1292      * although the Sun JVM does not use the most significant 32 bits.
1293      * It is hard to imagine a JVM technology which needs more than
1294      * a few bits to encode an offset within a non-array object,
1295      * However, for consistency with other methods in this class,
1296      * this method reports its result as a long value.
1297      *
1298      * @throws NullPointerException if the field is {@code null}
1299      * @throws IllegalArgumentException if the field is not static
1300      * @see #getInt(Object, long)
1301      */
1302     public long staticFieldOffset(Field f) {
1303         if (f == null) {
1304             throw new NullPointerException();
1305         }
1306 
1307         return staticFieldOffset0(f);
1308     }
1309 
1310     /**
1311      * Reports the location of a given static field, in conjunction with {@link
1312      * #staticFieldOffset}.
1313      * <p>Fetch the base "Object", if any, with which static fields of the
1314      * given class can be accessed via methods like {@link #getInt(Object,
1315      * long)}.  This value may be null.  This value may refer to an object
1316      * which is a "cookie", not guaranteed to be a real Object, and it should
1317      * not be used in any way except as argument to the get and put routines in
1318      * this class.
1319      *
1320      * @throws NullPointerException if the field is {@code null}
1321      * @throws IllegalArgumentException if the field is not static
1322      */
1323     public Object staticFieldBase(Field f) {
1324         if (f == null) {
1325             throw new NullPointerException();
1326         }
1327 
1328         return staticFieldBase0(f);
1329     }
1330 
1331     /**
1332      * Detects if the given class may need to be initialized. This is often
1333      * needed in conjunction with obtaining the static field base of a
1334      * class.
1335      * @return false only if a call to {@code ensureClassInitialized} would have no effect
1336      */
1337     public boolean shouldBeInitialized(Class<?> c) {
1338         if (c == null) {
1339             throw new NullPointerException();
1340         }
1341 
1342         return shouldBeInitialized0(c);
1343     }
1344 
1345     /**
1346      * Ensures the given class has been initialized (see JVMS-5.5 for details).
1347      * This is often needed in conjunction with obtaining the static field base
1348      * of a class.
1349      *
1350      * The call returns when either class {@code c} is fully initialized or
1351      * class {@code c} is being initialized and the call is performed from
1352      * the initializing thread. In the latter case a subsequent call to
1353      * {@link #shouldBeInitialized} will return {@code true}.
1354      */
1355     public void ensureClassInitialized(Class<?> c) {
1356         if (c == null) {
1357             throw new NullPointerException();
1358         }
1359 
1360         ensureClassInitialized0(c);
1361     }
1362 
1363     /**
1364      * The reading or writing of strict static fields may require
1365      * special processing.  Notify the VM that such an event is about
1366      * to happen.  The VM may respond by throwing an exception, in the
1367      * case of a read of an uninitialized field.  If the VM allows the
1368      * method to return normally, no further calls are needed, with
1369      * the same arguments.
1370      */
1371     public void notifyStrictStaticAccess(Class<?> c, long staticFieldOffset, boolean writing) {
1372         if (c == null) {
1373             throw new NullPointerException();
1374         }
1375         notifyStrictStaticAccess0(c, staticFieldOffset, writing);
1376     }
1377 
1378     /**
1379      * Reports the offset of the first element in the storage allocation of a
1380      * given array class.  If {@link #arrayIndexScale} returns a non-zero value
1381      * for the same class, you may use that scale factor, together with this
1382      * base offset, to form new offsets to access elements of arrays of the
1383      * given class.
1384      * <p>
1385      * The return value is in the range of a {@code int}.  The return type is
1386      * {@code long} to emphasize that long arithmetic should always be used
1387      * for offset calculations to avoid overflows.
1388      * <p>
1389      * This method doesn't support arrays with an element type that is
1390      * a value class, because this type of array can have multiple layouts.
1391      * For these arrays, {@code arrayInstanceBaseOffset(Object[] array)}
1392      * must be used instead.
1393      *
1394      * @see #getInt(Object, long)
1395      * @see #putInt(Object, long, int)
1396      */
1397     public long arrayBaseOffset(Class<?> arrayClass) {
1398         if (arrayClass == null) {
1399             throw new NullPointerException();
1400         }
1401 
1402         return arrayBaseOffset0(arrayClass);
1403     }
1404 
1405     public long arrayInstanceBaseOffset(Object[] array) {
1406         if (array == null) {
1407             throw new NullPointerException();
1408         }
1409 
1410         return arrayInstanceBaseOffset0(array);
1411     }
1412 
1413     /** The value of {@code arrayBaseOffset(boolean[].class)} */
1414     public static final long ARRAY_BOOLEAN_BASE_OFFSET
1415             = theUnsafe.arrayBaseOffset(boolean[].class);
1416 
1417     /** The value of {@code arrayBaseOffset(byte[].class)} */
1418     public static final long ARRAY_BYTE_BASE_OFFSET
1419             = theUnsafe.arrayBaseOffset(byte[].class);
1420 
1421     /** The value of {@code arrayBaseOffset(short[].class)} */
1422     public static final long ARRAY_SHORT_BASE_OFFSET
1423             = theUnsafe.arrayBaseOffset(short[].class);
1424 
1425     /** The value of {@code arrayBaseOffset(char[].class)} */
1426     public static final long ARRAY_CHAR_BASE_OFFSET
1427             = theUnsafe.arrayBaseOffset(char[].class);
1428 
1429     /** The value of {@code arrayBaseOffset(int[].class)} */
1430     public static final long ARRAY_INT_BASE_OFFSET
1431             = theUnsafe.arrayBaseOffset(int[].class);
1432 
1433     /** The value of {@code arrayBaseOffset(long[].class)} */
1434     public static final long ARRAY_LONG_BASE_OFFSET
1435             = theUnsafe.arrayBaseOffset(long[].class);
1436 
1437     /** The value of {@code arrayBaseOffset(float[].class)} */
1438     public static final long ARRAY_FLOAT_BASE_OFFSET
1439             = theUnsafe.arrayBaseOffset(float[].class);
1440 
1441     /** The value of {@code arrayBaseOffset(double[].class)} */
1442     public static final long ARRAY_DOUBLE_BASE_OFFSET
1443             = theUnsafe.arrayBaseOffset(double[].class);
1444 
1445     /** The value of {@code arrayBaseOffset(Object[].class)} */
1446     public static final long ARRAY_OBJECT_BASE_OFFSET
1447             = theUnsafe.arrayBaseOffset(Object[].class);
1448 
1449     /**
1450      * Reports the scale factor for addressing elements in the storage
1451      * allocation of a given array class.  However, arrays of "narrow" types
1452      * will generally not work properly with accessors like {@link
1453      * #getByte(Object, long)}, so the scale factor for such classes is reported
1454      * as zero.
1455      * <p>
1456      * The computation of the actual memory offset should always use {@code
1457      * long} arithmetic to avoid overflows.
1458      * <p>
1459      * This method doesn't support arrays with an element type that is
1460      * a value class, because this type of array can have multiple layouts.
1461      * For these arrays, {@code arrayInstanceIndexScale(Object[] array)}
1462      * must be used instead.
1463      *
1464      * @see #arrayBaseOffset
1465      * @see #getInt(Object, long)
1466      * @see #putInt(Object, long, int)
1467      */
1468     public int arrayIndexScale(Class<?> arrayClass) {
1469         if (arrayClass == null) {
1470             throw new NullPointerException();
1471         }
1472 
1473         return arrayIndexScale0(arrayClass);
1474     }
1475 
1476     public int arrayInstanceIndexScale(Object[] array) {
1477         if (array == null) {
1478             throw new NullPointerException();
1479         }
1480 
1481         return arrayInstanceIndexScale0(array);
1482     }
1483 
1484     public int[] getFieldMap(Class<? extends Object> c) {
1485       if (c == null) {
1486         throw new NullPointerException();
1487       }
1488       return getFieldMap0(c);
1489     }
1490 
1491     /**
1492      * Return the size of the object in the heap.
1493      * @param o an object
1494      * @return the objects's size
1495      * @since Valhalla
1496      */
1497     public long getObjectSize(Object o) {
1498         if (o == null)
1499             throw new NullPointerException();
1500         return getObjectSize0(o);
1501     }
1502 
1503     /** The value of {@code arrayIndexScale(boolean[].class)} */
1504     public static final int ARRAY_BOOLEAN_INDEX_SCALE
1505             = theUnsafe.arrayIndexScale(boolean[].class);
1506 
1507     /** The value of {@code arrayIndexScale(byte[].class)} */
1508     public static final int ARRAY_BYTE_INDEX_SCALE
1509             = theUnsafe.arrayIndexScale(byte[].class);
1510 
1511     /** The value of {@code arrayIndexScale(short[].class)} */
1512     public static final int ARRAY_SHORT_INDEX_SCALE
1513             = theUnsafe.arrayIndexScale(short[].class);
1514 
1515     /** The value of {@code arrayIndexScale(char[].class)} */
1516     public static final int ARRAY_CHAR_INDEX_SCALE
1517             = theUnsafe.arrayIndexScale(char[].class);
1518 
1519     /** The value of {@code arrayIndexScale(int[].class)} */
1520     public static final int ARRAY_INT_INDEX_SCALE
1521             = theUnsafe.arrayIndexScale(int[].class);
1522 
1523     /** The value of {@code arrayIndexScale(long[].class)} */
1524     public static final int ARRAY_LONG_INDEX_SCALE
1525             = theUnsafe.arrayIndexScale(long[].class);
1526 
1527     /** The value of {@code arrayIndexScale(float[].class)} */
1528     public static final int ARRAY_FLOAT_INDEX_SCALE
1529             = theUnsafe.arrayIndexScale(float[].class);
1530 
1531     /** The value of {@code arrayIndexScale(double[].class)} */
1532     public static final int ARRAY_DOUBLE_INDEX_SCALE
1533             = theUnsafe.arrayIndexScale(double[].class);
1534 
1535     /** The value of {@code arrayIndexScale(Object[].class)} */
1536     public static final int ARRAY_OBJECT_INDEX_SCALE
1537             = theUnsafe.arrayIndexScale(Object[].class);
1538 
1539     /**
1540      * Reports the size in bytes of a native pointer, as stored via {@link
1541      * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
1542      * other primitive types (as stored in native memory blocks) is determined
1543      * fully by their information content.
1544      */
1545     public int addressSize() {
1546         return ADDRESS_SIZE;
1547     }
1548 
1549     /** The value of {@code addressSize()} */
1550     public static final int ADDRESS_SIZE = ADDRESS_SIZE0;
1551 
1552     /**
1553      * Reports the size in bytes of a native memory page (whatever that is).
1554      * This value will always be a power of two.
1555      */
1556     public int pageSize() { return PAGE_SIZE; }
1557 
1558     /**
1559      * Reports the size in bytes of a data cache line written back by
1560      * the hardware cache line flush operation available to the JVM or
1561      * 0 if data cache line flushing is not enabled.
1562      */
1563     public int dataCacheLineFlushSize() { return DATA_CACHE_LINE_FLUSH_SIZE; }
1564 
1565     /**
1566      * Rounds down address to a data cache line boundary as
1567      * determined by {@link #dataCacheLineFlushSize}
1568      * @return the rounded down address
1569      */
1570     public long dataCacheLineAlignDown(long address) {
1571         return (address & ~(DATA_CACHE_LINE_FLUSH_SIZE - 1));
1572     }
1573 
1574     /**
1575      * Returns true if data cache line writeback
1576      */
1577     public static boolean isWritebackEnabled() { return DATA_CACHE_LINE_FLUSH_SIZE != 0; }
1578 
1579     //--- random trusted operations from JNI:
1580 
1581     /**
1582      * Tells the VM to define a class, without security checks.  By default, the
1583      * class loader and protection domain come from the caller's class.
1584      */
1585     public Class<?> defineClass(String name, byte[] b, int off, int len,
1586                                 ClassLoader loader,
1587                                 ProtectionDomain protectionDomain) {
1588         if (b == null) {
1589             throw new NullPointerException();
1590         }
1591         if (len < 0) {
1592             throw new ArrayIndexOutOfBoundsException();
1593         }
1594 
1595         return defineClass0(name, b, off, len, loader, protectionDomain);
1596     }
1597 
1598     public native Class<?> defineClass0(String name, byte[] b, int off, int len,
1599                                         ClassLoader loader,
1600                                         ProtectionDomain protectionDomain);
1601 
1602     /**
1603      * Allocates an instance but does not run any constructor.
1604      * Initializes the class if it has not yet been.
1605      */
1606     @IntrinsicCandidate
1607     public native Object allocateInstance(Class<?> cls)
1608         throws InstantiationException;
1609 
1610     /**
1611      * Allocates an array of a given type, but does not do zeroing.
1612      * <p>
1613      * This method should only be used in the very rare cases where a high-performance code
1614      * overwrites the destination array completely, and compilers cannot assist in zeroing elimination.
1615      * In an overwhelming majority of cases, a normal Java allocation should be used instead.
1616      * <p>
1617      * Users of this method are <b>required</b> to overwrite the initial (garbage) array contents
1618      * before allowing untrusted code, or code in other threads, to observe the reference
1619      * to the newly allocated array. In addition, the publication of the array reference must be
1620      * safe according to the Java Memory Model requirements.
1621      * <p>
1622      * The safest approach to deal with an uninitialized array is to keep the reference to it in local
1623      * variable at least until the initialization is complete, and then publish it <b>once</b>, either
1624      * by writing it to a <em>volatile</em> field, or storing it into a <em>final</em> field in constructor,
1625      * or issuing a {@link #storeFence} before publishing the reference.
1626      * <p>
1627      * @implnote This method can only allocate primitive arrays, to avoid garbage reference
1628      * elements that could break heap integrity.
1629      *
1630      * @param componentType array component type to allocate
1631      * @param length array size to allocate
1632      * @throws IllegalArgumentException if component type is null, or not a primitive class;
1633      *                                  or the length is negative
1634      */
1635     public Object allocateUninitializedArray(Class<?> componentType, int length) {
1636        if (componentType == null) {
1637            throw new IllegalArgumentException("Component type is null");
1638        }
1639        if (!componentType.isPrimitive()) {
1640            throw new IllegalArgumentException("Component type is not primitive");
1641        }
1642        if (length < 0) {
1643            throw new IllegalArgumentException("Negative length");
1644        }
1645        return allocateUninitializedArray0(componentType, length);
1646     }
1647 
1648     @IntrinsicCandidate
1649     private Object allocateUninitializedArray0(Class<?> componentType, int length) {
1650        // These fallbacks provide zeroed arrays, but intrinsic is not required to
1651        // return the zeroed arrays.
1652        if (componentType == byte.class)    return new byte[length];
1653        if (componentType == boolean.class) return new boolean[length];
1654        if (componentType == short.class)   return new short[length];
1655        if (componentType == char.class)    return new char[length];
1656        if (componentType == int.class)     return new int[length];
1657        if (componentType == float.class)   return new float[length];
1658        if (componentType == long.class)    return new long[length];
1659        if (componentType == double.class)  return new double[length];
1660        return null;
1661     }
1662 
1663     /** Throws the exception without telling the verifier. */
1664     public native void throwException(Throwable ee);
1665 
1666     /**
1667      * Atomically updates Java variable to {@code x} if it is currently
1668      * holding {@code expected}.
1669      *
1670      * <p>This operation has memory semantics of a {@code volatile} read
1671      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1672      *
1673      * @return {@code true} if successful
1674      */
1675     @IntrinsicCandidate
1676     public final native boolean compareAndSetReference(Object o, long offset,
1677                                                        Object expected,
1678                                                        Object x);
1679 
1680     private final boolean isValueObject(Object o) {
1681         return o != null && o.getClass().isValue();
1682     }
1683 
1684     /*
1685      * For value type, CAS should do substitutability test as opposed
1686      * to two pointers comparison.
1687      */
1688     @ForceInline
1689     public final <V> boolean compareAndSetReference(Object o, long offset,
1690                                                     Class<?> type,
1691                                                     V expected,
1692                                                     V x) {
1693         if (type.isValue() || isValueObject(expected)) {
1694             while (true) {
1695                 Object witness = getReferenceVolatile(o, offset);
1696                 if (witness != expected) {
1697                     return false;
1698                 }
1699                 if (compareAndSetReference(o, offset, witness, x)) {
1700                     return true;
1701                 }
1702             }
1703         } else {
1704             return compareAndSetReference(o, offset, expected, x);
1705         }
1706     }
1707 
1708     @ForceInline
1709     public final <V> boolean compareAndSetFlatValue(Object o, long offset,
1710                                                 int layout,
1711                                                 Class<?> valueType,
1712                                                 V expected,
1713                                                 V x) {
1714         while (true) {
1715             Object witness = getFlatValueVolatile(o, offset, layout, valueType);
1716             if (witness != expected) {
1717                 return false;
1718             }
1719             if (compareAndSetFlatValueAsBytes(o, offset, layout, valueType, witness, x)) {
1720                 return true;
1721             }
1722         }
1723     }
1724 
1725     @IntrinsicCandidate
1726     public final native Object compareAndExchangeReference(Object o, long offset,
1727                                                            Object expected,
1728                                                            Object x);
1729 
1730     @ForceInline
1731     public final <V> Object compareAndExchangeReference(Object o, long offset,
1732                                                         Class<?> valueType,
1733                                                         V expected,
1734                                                         V x) {
1735         if (valueType.isValue() || isValueObject(expected)) {
1736             while (true) {
1737                 Object witness = getReferenceVolatile(o, offset);
1738                 if (witness != expected) {
1739                     return witness;
1740                 }
1741                 if (compareAndSetReference(o, offset, witness, x)) {
1742                     return witness;
1743                 }
1744             }
1745         } else {
1746             return compareAndExchangeReference(o, offset, expected, x);
1747         }
1748     }
1749 
1750     @ForceInline
1751     public final <V> Object compareAndExchangeFlatValue(Object o, long offset,
1752                                                     int layout,
1753                                                     Class<?> valueType,
1754                                                     V expected,
1755                                                     V x) {
1756         while (true) {
1757             Object witness = getFlatValueVolatile(o, offset, layout, valueType);
1758             if (witness != expected) {
1759                 return witness;
1760             }
1761             if (compareAndSetFlatValueAsBytes(o, offset, layout, valueType, witness, x)) {
1762                 return witness;
1763             }
1764         }
1765     }
1766 
1767     @IntrinsicCandidate
1768     public final Object compareAndExchangeReferenceAcquire(Object o, long offset,
1769                                                            Object expected,
1770                                                            Object x) {
1771         return compareAndExchangeReference(o, offset, expected, x);
1772     }
1773 
1774     public final <V> Object compareAndExchangeReferenceAcquire(Object o, long offset,
1775                                                                Class<?> valueType,
1776                                                                V expected,
1777                                                                V x) {
1778         return compareAndExchangeReference(o, offset, valueType, expected, x);
1779     }
1780 
1781     @ForceInline
1782     public final <V> Object compareAndExchangeFlatValueAcquire(Object o, long offset,
1783                                                            int layout,
1784                                                            Class<?> valueType,
1785                                                            V expected,
1786                                                            V x) {
1787         return compareAndExchangeFlatValue(o, offset, layout, valueType, expected, x);
1788     }
1789 
1790     @IntrinsicCandidate
1791     public final Object compareAndExchangeReferenceRelease(Object o, long offset,
1792                                                            Object expected,
1793                                                            Object x) {
1794         return compareAndExchangeReference(o, offset, expected, x);
1795     }
1796 
1797     public final <V> Object compareAndExchangeReferenceRelease(Object o, long offset,
1798                                                                Class<?> valueType,
1799                                                                V expected,
1800                                                                V x) {
1801         return compareAndExchangeReference(o, offset, valueType, expected, x);
1802     }
1803 
1804     @ForceInline
1805     public final <V> Object compareAndExchangeFlatValueRelease(Object o, long offset,
1806                                                            int layout,
1807                                                            Class<?> valueType,
1808                                                            V expected,
1809                                                            V x) {
1810         return compareAndExchangeFlatValue(o, offset, layout, valueType, expected, x);
1811     }
1812 
1813     @IntrinsicCandidate
1814     public final boolean weakCompareAndSetReferencePlain(Object o, long offset,
1815                                                          Object expected,
1816                                                          Object x) {
1817         return compareAndSetReference(o, offset, expected, x);
1818     }
1819 
1820     public final <V> boolean weakCompareAndSetReferencePlain(Object o, long offset,
1821                                                              Class<?> valueType,
1822                                                              V expected,
1823                                                              V x) {
1824         if (valueType.isValue() || isValueObject(expected)) {
1825             return compareAndSetReference(o, offset, valueType, expected, x);
1826         } else {
1827             return weakCompareAndSetReferencePlain(o, offset, expected, x);
1828         }
1829     }
1830 
1831     @ForceInline
1832     public final <V> boolean weakCompareAndSetFlatValuePlain(Object o, long offset,
1833                                                          int layout,
1834                                                          Class<?> valueType,
1835                                                          V expected,
1836                                                          V x) {
1837         return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1838     }
1839 
1840     @IntrinsicCandidate
1841     public final boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
1842                                                            Object expected,
1843                                                            Object x) {
1844         return compareAndSetReference(o, offset, expected, x);
1845     }
1846 
1847     public final <V> boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
1848                                                                Class<?> valueType,
1849                                                                V expected,
1850                                                                V x) {
1851         if (valueType.isValue() || isValueObject(expected)) {
1852             return compareAndSetReference(o, offset, valueType, expected, x);
1853         } else {
1854             return weakCompareAndSetReferencePlain(o, offset, expected, x);
1855         }
1856     }
1857 
1858     @ForceInline
1859     public final <V> boolean weakCompareAndSetFlatValueAcquire(Object o, long offset,
1860                                                            int layout,
1861                                                            Class<?> valueType,
1862                                                            V expected,
1863                                                            V x) {
1864         return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1865     }
1866 
1867     @IntrinsicCandidate
1868     public final boolean weakCompareAndSetReferenceRelease(Object o, long offset,
1869                                                            Object expected,
1870                                                            Object x) {
1871         return compareAndSetReference(o, offset, expected, x);
1872     }
1873 
1874     public final <V> boolean weakCompareAndSetReferenceRelease(Object o, long offset,
1875                                                                Class<?> valueType,
1876                                                                V expected,
1877                                                                V x) {
1878         if (valueType.isValue() || isValueObject(expected)) {
1879             return compareAndSetReference(o, offset, valueType, expected, x);
1880         } else {
1881             return weakCompareAndSetReferencePlain(o, offset, expected, x);
1882         }
1883     }
1884 
1885     @ForceInline
1886     public final <V> boolean weakCompareAndSetFlatValueRelease(Object o, long offset,
1887                                                            int layout,
1888                                                            Class<?> valueType,
1889                                                            V expected,
1890                                                            V x) {
1891         return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1892     }
1893 
1894     @IntrinsicCandidate
1895     public final boolean weakCompareAndSetReference(Object o, long offset,
1896                                                     Object expected,
1897                                                     Object x) {
1898         return compareAndSetReference(o, offset, expected, x);
1899     }
1900 
1901     public final <V> boolean weakCompareAndSetReference(Object o, long offset,
1902                                                         Class<?> valueType,
1903                                                         V expected,
1904                                                         V x) {
1905         if (valueType.isValue() || isValueObject(expected)) {
1906             return compareAndSetReference(o, offset, valueType, expected, x);
1907         } else {
1908             return weakCompareAndSetReferencePlain(o, offset, expected, x);
1909         }
1910     }
1911 
1912     @ForceInline
1913     public final <V> boolean weakCompareAndSetFlatValue(Object o, long offset,
1914                                                     int layout,
1915                                                     Class<?> valueType,
1916                                                     V expected,
1917                                                     V x) {
1918         return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1919     }
1920 
1921     /**
1922      * Atomically updates Java variable to {@code x} if it is currently
1923      * holding {@code expected}.
1924      *
1925      * <p>This operation has memory semantics of a {@code volatile} read
1926      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1927      *
1928      * @return {@code true} if successful
1929      */
1930     @IntrinsicCandidate
1931     public final native boolean compareAndSetInt(Object o, long offset,
1932                                                  int expected,
1933                                                  int x);
1934 
1935     @IntrinsicCandidate
1936     public final native int compareAndExchangeInt(Object o, long offset,
1937                                                   int expected,
1938                                                   int x);
1939 
1940     @IntrinsicCandidate
1941     public final int compareAndExchangeIntAcquire(Object o, long offset,
1942                                                          int expected,
1943                                                          int x) {
1944         return compareAndExchangeInt(o, offset, expected, x);
1945     }
1946 
1947     @IntrinsicCandidate
1948     public final int compareAndExchangeIntRelease(Object o, long offset,
1949                                                          int expected,
1950                                                          int x) {
1951         return compareAndExchangeInt(o, offset, expected, x);
1952     }
1953 
1954     @IntrinsicCandidate
1955     public final boolean weakCompareAndSetIntPlain(Object o, long offset,
1956                                                    int expected,
1957                                                    int x) {
1958         return compareAndSetInt(o, offset, expected, x);
1959     }
1960 
1961     @IntrinsicCandidate
1962     public final boolean weakCompareAndSetIntAcquire(Object o, long offset,
1963                                                      int expected,
1964                                                      int x) {
1965         return compareAndSetInt(o, offset, expected, x);
1966     }
1967 
1968     @IntrinsicCandidate
1969     public final boolean weakCompareAndSetIntRelease(Object o, long offset,
1970                                                      int expected,
1971                                                      int x) {
1972         return compareAndSetInt(o, offset, expected, x);
1973     }
1974 
1975     @IntrinsicCandidate
1976     public final boolean weakCompareAndSetInt(Object o, long offset,
1977                                               int expected,
1978                                               int x) {
1979         return compareAndSetInt(o, offset, expected, x);
1980     }
1981 
1982     @IntrinsicCandidate
1983     public final byte compareAndExchangeByte(Object o, long offset,
1984                                              byte expected,
1985                                              byte x) {
1986         long wordOffset = offset & ~3;
1987         int shift = (int) (offset & 3) << 3;
1988         if (BIG_ENDIAN) {
1989             shift = 24 - shift;
1990         }
1991         int mask           = 0xFF << shift;
1992         int maskedExpected = (expected & 0xFF) << shift;
1993         int maskedX        = (x & 0xFF) << shift;
1994         int fullWord;
1995         do {
1996             fullWord = getIntVolatile(o, wordOffset);
1997             if ((fullWord & mask) != maskedExpected)
1998                 return (byte) ((fullWord & mask) >> shift);
1999         } while (!weakCompareAndSetInt(o, wordOffset,
2000                                                 fullWord, (fullWord & ~mask) | maskedX));
2001         return expected;
2002     }
2003 
2004     @IntrinsicCandidate
2005     public final boolean compareAndSetByte(Object o, long offset,
2006                                            byte expected,
2007                                            byte x) {
2008         return compareAndExchangeByte(o, offset, expected, x) == expected;
2009     }
2010 
2011     @IntrinsicCandidate
2012     public final boolean weakCompareAndSetByte(Object o, long offset,
2013                                                byte expected,
2014                                                byte x) {
2015         return compareAndSetByte(o, offset, expected, x);
2016     }
2017 
2018     @IntrinsicCandidate
2019     public final boolean weakCompareAndSetByteAcquire(Object o, long offset,
2020                                                       byte expected,
2021                                                       byte x) {
2022         return weakCompareAndSetByte(o, offset, expected, x);
2023     }
2024 
2025     @IntrinsicCandidate
2026     public final boolean weakCompareAndSetByteRelease(Object o, long offset,
2027                                                       byte expected,
2028                                                       byte x) {
2029         return weakCompareAndSetByte(o, offset, expected, x);
2030     }
2031 
2032     @IntrinsicCandidate
2033     public final boolean weakCompareAndSetBytePlain(Object o, long offset,
2034                                                     byte expected,
2035                                                     byte x) {
2036         return weakCompareAndSetByte(o, offset, expected, x);
2037     }
2038 
2039     @IntrinsicCandidate
2040     public final byte compareAndExchangeByteAcquire(Object o, long offset,
2041                                                     byte expected,
2042                                                     byte x) {
2043         return compareAndExchangeByte(o, offset, expected, x);
2044     }
2045 
2046     @IntrinsicCandidate
2047     public final byte compareAndExchangeByteRelease(Object o, long offset,
2048                                                     byte expected,
2049                                                     byte x) {
2050         return compareAndExchangeByte(o, offset, expected, x);
2051     }
2052 
2053     @IntrinsicCandidate
2054     public final short compareAndExchangeShort(Object o, long offset,
2055                                                short expected,
2056                                                short x) {
2057         if ((offset & 3) == 3) {
2058             throw new IllegalArgumentException("Update spans the word, not supported");
2059         }
2060         long wordOffset = offset & ~3;
2061         int shift = (int) (offset & 3) << 3;
2062         if (BIG_ENDIAN) {
2063             shift = 16 - shift;
2064         }
2065         int mask           = 0xFFFF << shift;
2066         int maskedExpected = (expected & 0xFFFF) << shift;
2067         int maskedX        = (x & 0xFFFF) << shift;
2068         int fullWord;
2069         do {
2070             fullWord = getIntVolatile(o, wordOffset);
2071             if ((fullWord & mask) != maskedExpected) {
2072                 return (short) ((fullWord & mask) >> shift);
2073             }
2074         } while (!weakCompareAndSetInt(o, wordOffset,
2075                                                 fullWord, (fullWord & ~mask) | maskedX));
2076         return expected;
2077     }
2078 
2079     @IntrinsicCandidate
2080     public final boolean compareAndSetShort(Object o, long offset,
2081                                             short expected,
2082                                             short x) {
2083         return compareAndExchangeShort(o, offset, expected, x) == expected;
2084     }
2085 
2086     @IntrinsicCandidate
2087     public final boolean weakCompareAndSetShort(Object o, long offset,
2088                                                 short expected,
2089                                                 short x) {
2090         return compareAndSetShort(o, offset, expected, x);
2091     }
2092 
2093     @IntrinsicCandidate
2094     public final boolean weakCompareAndSetShortAcquire(Object o, long offset,
2095                                                        short expected,
2096                                                        short x) {
2097         return weakCompareAndSetShort(o, offset, expected, x);
2098     }
2099 
2100     @IntrinsicCandidate
2101     public final boolean weakCompareAndSetShortRelease(Object o, long offset,
2102                                                        short expected,
2103                                                        short x) {
2104         return weakCompareAndSetShort(o, offset, expected, x);
2105     }
2106 
2107     @IntrinsicCandidate
2108     public final boolean weakCompareAndSetShortPlain(Object o, long offset,
2109                                                      short expected,
2110                                                      short x) {
2111         return weakCompareAndSetShort(o, offset, expected, x);
2112     }
2113 
2114 
2115     @IntrinsicCandidate
2116     public final short compareAndExchangeShortAcquire(Object o, long offset,
2117                                                      short expected,
2118                                                      short x) {
2119         return compareAndExchangeShort(o, offset, expected, x);
2120     }
2121 
2122     @IntrinsicCandidate
2123     public final short compareAndExchangeShortRelease(Object o, long offset,
2124                                                     short expected,
2125                                                     short x) {
2126         return compareAndExchangeShort(o, offset, expected, x);
2127     }
2128 
2129     @ForceInline
2130     private char s2c(short s) {
2131         return (char) s;
2132     }
2133 
2134     @ForceInline
2135     private short c2s(char s) {
2136         return (short) s;
2137     }
2138 
2139     @ForceInline
2140     public final boolean compareAndSetChar(Object o, long offset,
2141                                            char expected,
2142                                            char x) {
2143         return compareAndSetShort(o, offset, c2s(expected), c2s(x));
2144     }
2145 
2146     @ForceInline
2147     public final char compareAndExchangeChar(Object o, long offset,
2148                                              char expected,
2149                                              char x) {
2150         return s2c(compareAndExchangeShort(o, offset, c2s(expected), c2s(x)));
2151     }
2152 
2153     @ForceInline
2154     public final char compareAndExchangeCharAcquire(Object o, long offset,
2155                                             char expected,
2156                                             char x) {
2157         return s2c(compareAndExchangeShortAcquire(o, offset, c2s(expected), c2s(x)));
2158     }
2159 
2160     @ForceInline
2161     public final char compareAndExchangeCharRelease(Object o, long offset,
2162                                             char expected,
2163                                             char x) {
2164         return s2c(compareAndExchangeShortRelease(o, offset, c2s(expected), c2s(x)));
2165     }
2166 
2167     @ForceInline
2168     public final boolean weakCompareAndSetChar(Object o, long offset,
2169                                                char expected,
2170                                                char x) {
2171         return weakCompareAndSetShort(o, offset, c2s(expected), c2s(x));
2172     }
2173 
2174     @ForceInline
2175     public final boolean weakCompareAndSetCharAcquire(Object o, long offset,
2176                                                       char expected,
2177                                                       char x) {
2178         return weakCompareAndSetShortAcquire(o, offset, c2s(expected), c2s(x));
2179     }
2180 
2181     @ForceInline
2182     public final boolean weakCompareAndSetCharRelease(Object o, long offset,
2183                                                       char expected,
2184                                                       char x) {
2185         return weakCompareAndSetShortRelease(o, offset, c2s(expected), c2s(x));
2186     }
2187 
2188     @ForceInline
2189     public final boolean weakCompareAndSetCharPlain(Object o, long offset,
2190                                                     char expected,
2191                                                     char x) {
2192         return weakCompareAndSetShortPlain(o, offset, c2s(expected), c2s(x));
2193     }
2194 
2195     /**
2196      * The JVM converts integral values to boolean values using two
2197      * different conventions, byte testing against zero and truncation
2198      * to least-significant bit.
2199      *
2200      * <p>The JNI documents specify that, at least for returning
2201      * values from native methods, a Java boolean value is converted
2202      * to the value-set 0..1 by first truncating to a byte (0..255 or
2203      * maybe -128..127) and then testing against zero. Thus, Java
2204      * booleans in non-Java data structures are by convention
2205      * represented as 8-bit containers containing either zero (for
2206      * false) or any non-zero value (for true).
2207      *
2208      * <p>Java booleans in the heap are also stored in bytes, but are
2209      * strongly normalized to the value-set 0..1 (i.e., they are
2210      * truncated to the least-significant bit).
2211      *
2212      * <p>The main reason for having different conventions for
2213      * conversion is performance: Truncation to the least-significant
2214      * bit can be usually implemented with fewer (machine)
2215      * instructions than byte testing against zero.
2216      *
2217      * <p>A number of Unsafe methods load boolean values from the heap
2218      * as bytes. Unsafe converts those values according to the JNI
2219      * rules (i.e, using the "testing against zero" convention). The
2220      * method {@code byte2bool} implements that conversion.
2221      *
2222      * @param b the byte to be converted to boolean
2223      * @return the result of the conversion
2224      */
2225     @ForceInline
2226     private boolean byte2bool(byte b) {
2227         return b != 0;
2228     }
2229 
2230     /**
2231      * Convert a boolean value to a byte. The return value is strongly
2232      * normalized to the value-set 0..1 (i.e., the value is truncated
2233      * to the least-significant bit). See {@link #byte2bool(byte)} for
2234      * more details on conversion conventions.
2235      *
2236      * @param b the boolean to be converted to byte (and then normalized)
2237      * @return the result of the conversion
2238      */
2239     @ForceInline
2240     private byte bool2byte(boolean b) {
2241         return b ? (byte)1 : (byte)0;
2242     }
2243 
2244     @ForceInline
2245     public final boolean compareAndSetBoolean(Object o, long offset,
2246                                               boolean expected,
2247                                               boolean x) {
2248         return compareAndSetByte(o, offset, bool2byte(expected), bool2byte(x));
2249     }
2250 
2251     @ForceInline
2252     public final boolean compareAndExchangeBoolean(Object o, long offset,
2253                                                    boolean expected,
2254                                                    boolean x) {
2255         return byte2bool(compareAndExchangeByte(o, offset, bool2byte(expected), bool2byte(x)));
2256     }
2257 
2258     @ForceInline
2259     public final boolean compareAndExchangeBooleanAcquire(Object o, long offset,
2260                                                     boolean expected,
2261                                                     boolean x) {
2262         return byte2bool(compareAndExchangeByteAcquire(o, offset, bool2byte(expected), bool2byte(x)));
2263     }
2264 
2265     @ForceInline
2266     public final boolean compareAndExchangeBooleanRelease(Object o, long offset,
2267                                                        boolean expected,
2268                                                        boolean x) {
2269         return byte2bool(compareAndExchangeByteRelease(o, offset, bool2byte(expected), bool2byte(x)));
2270     }
2271 
2272     @ForceInline
2273     public final boolean weakCompareAndSetBoolean(Object o, long offset,
2274                                                   boolean expected,
2275                                                   boolean x) {
2276         return weakCompareAndSetByte(o, offset, bool2byte(expected), bool2byte(x));
2277     }
2278 
2279     @ForceInline
2280     public final boolean weakCompareAndSetBooleanAcquire(Object o, long offset,
2281                                                          boolean expected,
2282                                                          boolean x) {
2283         return weakCompareAndSetByteAcquire(o, offset, bool2byte(expected), bool2byte(x));
2284     }
2285 
2286     @ForceInline
2287     public final boolean weakCompareAndSetBooleanRelease(Object o, long offset,
2288                                                          boolean expected,
2289                                                          boolean x) {
2290         return weakCompareAndSetByteRelease(o, offset, bool2byte(expected), bool2byte(x));
2291     }
2292 
2293     @ForceInline
2294     public final boolean weakCompareAndSetBooleanPlain(Object o, long offset,
2295                                                        boolean expected,
2296                                                        boolean x) {
2297         return weakCompareAndSetBytePlain(o, offset, bool2byte(expected), bool2byte(x));
2298     }
2299 
2300     /**
2301      * Atomically updates Java variable to {@code x} if it is currently
2302      * holding {@code expected}.
2303      *
2304      * <p>This operation has memory semantics of a {@code volatile} read
2305      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
2306      *
2307      * @return {@code true} if successful
2308      */
2309     @ForceInline
2310     public final boolean compareAndSetFloat(Object o, long offset,
2311                                             float expected,
2312                                             float x) {
2313         return compareAndSetInt(o, offset,
2314                                  Float.floatToRawIntBits(expected),
2315                                  Float.floatToRawIntBits(x));
2316     }
2317 
2318     @ForceInline
2319     public final float compareAndExchangeFloat(Object o, long offset,
2320                                                float expected,
2321                                                float x) {
2322         int w = compareAndExchangeInt(o, offset,
2323                                       Float.floatToRawIntBits(expected),
2324                                       Float.floatToRawIntBits(x));
2325         return Float.intBitsToFloat(w);
2326     }
2327 
2328     @ForceInline
2329     public final float compareAndExchangeFloatAcquire(Object o, long offset,
2330                                                   float expected,
2331                                                   float x) {
2332         int w = compareAndExchangeIntAcquire(o, offset,
2333                                              Float.floatToRawIntBits(expected),
2334                                              Float.floatToRawIntBits(x));
2335         return Float.intBitsToFloat(w);
2336     }
2337 
2338     @ForceInline
2339     public final float compareAndExchangeFloatRelease(Object o, long offset,
2340                                                   float expected,
2341                                                   float x) {
2342         int w = compareAndExchangeIntRelease(o, offset,
2343                                              Float.floatToRawIntBits(expected),
2344                                              Float.floatToRawIntBits(x));
2345         return Float.intBitsToFloat(w);
2346     }
2347 
2348     @ForceInline
2349     public final boolean weakCompareAndSetFloatPlain(Object o, long offset,
2350                                                      float expected,
2351                                                      float x) {
2352         return weakCompareAndSetIntPlain(o, offset,
2353                                      Float.floatToRawIntBits(expected),
2354                                      Float.floatToRawIntBits(x));
2355     }
2356 
2357     @ForceInline
2358     public final boolean weakCompareAndSetFloatAcquire(Object o, long offset,
2359                                                        float expected,
2360                                                        float x) {
2361         return weakCompareAndSetIntAcquire(o, offset,
2362                                             Float.floatToRawIntBits(expected),
2363                                             Float.floatToRawIntBits(x));
2364     }
2365 
2366     @ForceInline
2367     public final boolean weakCompareAndSetFloatRelease(Object o, long offset,
2368                                                        float expected,
2369                                                        float x) {
2370         return weakCompareAndSetIntRelease(o, offset,
2371                                             Float.floatToRawIntBits(expected),
2372                                             Float.floatToRawIntBits(x));
2373     }
2374 
2375     @ForceInline
2376     public final boolean weakCompareAndSetFloat(Object o, long offset,
2377                                                 float expected,
2378                                                 float x) {
2379         return weakCompareAndSetInt(o, offset,
2380                                              Float.floatToRawIntBits(expected),
2381                                              Float.floatToRawIntBits(x));
2382     }
2383 
2384     /**
2385      * Atomically updates Java variable to {@code x} if it is currently
2386      * holding {@code expected}.
2387      *
2388      * <p>This operation has memory semantics of a {@code volatile} read
2389      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
2390      *
2391      * @return {@code true} if successful
2392      */
2393     @ForceInline
2394     public final boolean compareAndSetDouble(Object o, long offset,
2395                                              double expected,
2396                                              double x) {
2397         return compareAndSetLong(o, offset,
2398                                  Double.doubleToRawLongBits(expected),
2399                                  Double.doubleToRawLongBits(x));
2400     }
2401 
2402     @ForceInline
2403     public final double compareAndExchangeDouble(Object o, long offset,
2404                                                  double expected,
2405                                                  double x) {
2406         long w = compareAndExchangeLong(o, offset,
2407                                         Double.doubleToRawLongBits(expected),
2408                                         Double.doubleToRawLongBits(x));
2409         return Double.longBitsToDouble(w);
2410     }
2411 
2412     @ForceInline
2413     public final double compareAndExchangeDoubleAcquire(Object o, long offset,
2414                                                         double expected,
2415                                                         double x) {
2416         long w = compareAndExchangeLongAcquire(o, offset,
2417                                                Double.doubleToRawLongBits(expected),
2418                                                Double.doubleToRawLongBits(x));
2419         return Double.longBitsToDouble(w);
2420     }
2421 
2422     @ForceInline
2423     public final double compareAndExchangeDoubleRelease(Object o, long offset,
2424                                                         double expected,
2425                                                         double x) {
2426         long w = compareAndExchangeLongRelease(o, offset,
2427                                                Double.doubleToRawLongBits(expected),
2428                                                Double.doubleToRawLongBits(x));
2429         return Double.longBitsToDouble(w);
2430     }
2431 
2432     @ForceInline
2433     public final boolean weakCompareAndSetDoublePlain(Object o, long offset,
2434                                                       double expected,
2435                                                       double x) {
2436         return weakCompareAndSetLongPlain(o, offset,
2437                                      Double.doubleToRawLongBits(expected),
2438                                      Double.doubleToRawLongBits(x));
2439     }
2440 
2441     @ForceInline
2442     public final boolean weakCompareAndSetDoubleAcquire(Object o, long offset,
2443                                                         double expected,
2444                                                         double x) {
2445         return weakCompareAndSetLongAcquire(o, offset,
2446                                              Double.doubleToRawLongBits(expected),
2447                                              Double.doubleToRawLongBits(x));
2448     }
2449 
2450     @ForceInline
2451     public final boolean weakCompareAndSetDoubleRelease(Object o, long offset,
2452                                                         double expected,
2453                                                         double x) {
2454         return weakCompareAndSetLongRelease(o, offset,
2455                                              Double.doubleToRawLongBits(expected),
2456                                              Double.doubleToRawLongBits(x));
2457     }
2458 
2459     @ForceInline
2460     public final boolean weakCompareAndSetDouble(Object o, long offset,
2461                                                  double expected,
2462                                                  double x) {
2463         return weakCompareAndSetLong(o, offset,
2464                                               Double.doubleToRawLongBits(expected),
2465                                               Double.doubleToRawLongBits(x));
2466     }
2467 
2468     /**
2469      * Atomically updates Java variable to {@code x} if it is currently
2470      * holding {@code expected}.
2471      *
2472      * <p>This operation has memory semantics of a {@code volatile} read
2473      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
2474      *
2475      * @return {@code true} if successful
2476      */
2477     @IntrinsicCandidate
2478     public final native boolean compareAndSetLong(Object o, long offset,
2479                                                   long expected,
2480                                                   long x);
2481 
2482     @IntrinsicCandidate
2483     public final native long compareAndExchangeLong(Object o, long offset,
2484                                                     long expected,
2485                                                     long x);
2486 
2487     @IntrinsicCandidate
2488     public final long compareAndExchangeLongAcquire(Object o, long offset,
2489                                                            long expected,
2490                                                            long x) {
2491         return compareAndExchangeLong(o, offset, expected, x);
2492     }
2493 
2494     @IntrinsicCandidate
2495     public final long compareAndExchangeLongRelease(Object o, long offset,
2496                                                            long expected,
2497                                                            long x) {
2498         return compareAndExchangeLong(o, offset, expected, x);
2499     }
2500 
2501     @IntrinsicCandidate
2502     public final boolean weakCompareAndSetLongPlain(Object o, long offset,
2503                                                     long expected,
2504                                                     long x) {
2505         return compareAndSetLong(o, offset, expected, x);
2506     }
2507 
2508     @IntrinsicCandidate
2509     public final boolean weakCompareAndSetLongAcquire(Object o, long offset,
2510                                                       long expected,
2511                                                       long x) {
2512         return compareAndSetLong(o, offset, expected, x);
2513     }
2514 
2515     @IntrinsicCandidate
2516     public final boolean weakCompareAndSetLongRelease(Object o, long offset,
2517                                                       long expected,
2518                                                       long x) {
2519         return compareAndSetLong(o, offset, expected, x);
2520     }
2521 
2522     @IntrinsicCandidate
2523     public final boolean weakCompareAndSetLong(Object o, long offset,
2524                                                long expected,
2525                                                long x) {
2526         return compareAndSetLong(o, offset, expected, x);
2527     }
2528 
2529     /**
2530      * Fetches a reference value from a given Java variable, with volatile
2531      * load semantics. Otherwise identical to {@link #getReference(Object, long)}
2532      */
2533     @IntrinsicCandidate
2534     public native Object getReferenceVolatile(Object o, long offset);
2535 
2536     @ForceInline
2537     public final <V> Object getFlatValueVolatile(Object o, long offset, int layout, Class<?> valueType) {
2538         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2539         Object res = getFlatValue(o, offset, layout, valueType);
2540         fullFence();
2541         return res;
2542     }
2543 
2544     /**
2545      * Stores a reference value into a given Java variable, with
2546      * volatile store semantics. Otherwise identical to {@link #putReference(Object, long, Object)}
2547      */
2548     @IntrinsicCandidate
2549     public native void putReferenceVolatile(Object o, long offset, Object x);
2550 
2551     @ForceInline
2552     public final <V> void putFlatValueVolatile(Object o, long offset, int layout, Class<?> valueType, V x) {
2553         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2554         putFlatValueRelease(o, offset, layout, valueType, x);
2555         fullFence();
2556     }
2557 
2558     /** Volatile version of {@link #getInt(Object, long)}  */
2559     @IntrinsicCandidate
2560     public native int     getIntVolatile(Object o, long offset);
2561 
2562     /** Volatile version of {@link #putInt(Object, long, int)}  */
2563     @IntrinsicCandidate
2564     public native void    putIntVolatile(Object o, long offset, int x);
2565 
2566     /** Volatile version of {@link #getBoolean(Object, long)}  */
2567     @IntrinsicCandidate
2568     public native boolean getBooleanVolatile(Object o, long offset);
2569 
2570     /** Volatile version of {@link #putBoolean(Object, long, boolean)}  */
2571     @IntrinsicCandidate
2572     public native void    putBooleanVolatile(Object o, long offset, boolean x);
2573 
2574     /** Volatile version of {@link #getByte(Object, long)}  */
2575     @IntrinsicCandidate
2576     public native byte    getByteVolatile(Object o, long offset);
2577 
2578     /** Volatile version of {@link #putByte(Object, long, byte)}  */
2579     @IntrinsicCandidate
2580     public native void    putByteVolatile(Object o, long offset, byte x);
2581 
2582     /** Volatile version of {@link #getShort(Object, long)}  */
2583     @IntrinsicCandidate
2584     public native short   getShortVolatile(Object o, long offset);
2585 
2586     /** Volatile version of {@link #putShort(Object, long, short)}  */
2587     @IntrinsicCandidate
2588     public native void    putShortVolatile(Object o, long offset, short x);
2589 
2590     /** Volatile version of {@link #getChar(Object, long)}  */
2591     @IntrinsicCandidate
2592     public native char    getCharVolatile(Object o, long offset);
2593 
2594     /** Volatile version of {@link #putChar(Object, long, char)}  */
2595     @IntrinsicCandidate
2596     public native void    putCharVolatile(Object o, long offset, char x);
2597 
2598     /** Volatile version of {@link #getLong(Object, long)}  */
2599     @IntrinsicCandidate
2600     public native long    getLongVolatile(Object o, long offset);
2601 
2602     /** Volatile version of {@link #putLong(Object, long, long)}  */
2603     @IntrinsicCandidate
2604     public native void    putLongVolatile(Object o, long offset, long x);
2605 
2606     /** Volatile version of {@link #getFloat(Object, long)}  */
2607     @IntrinsicCandidate
2608     public native float   getFloatVolatile(Object o, long offset);
2609 
2610     /** Volatile version of {@link #putFloat(Object, long, float)}  */
2611     @IntrinsicCandidate
2612     public native void    putFloatVolatile(Object o, long offset, float x);
2613 
2614     /** Volatile version of {@link #getDouble(Object, long)}  */
2615     @IntrinsicCandidate
2616     public native double  getDoubleVolatile(Object o, long offset);
2617 
2618     /** Volatile version of {@link #putDouble(Object, long, double)}  */
2619     @IntrinsicCandidate
2620     public native void    putDoubleVolatile(Object o, long offset, double x);
2621 
2622 
2623 
2624     /** Acquire version of {@link #getReferenceVolatile(Object, long)} */
2625     @IntrinsicCandidate
2626     public final Object getReferenceAcquire(Object o, long offset) {
2627         return getReferenceVolatile(o, offset);
2628     }
2629 
2630     @ForceInline
2631     public final <V> Object getFlatValueAcquire(Object o, long offset, int layout, Class<?> valueType) {
2632         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2633         Object res = getFlatValue(o, offset, layout, valueType);
2634         loadFence();
2635         return res;
2636     }
2637 
2638     /** Acquire version of {@link #getBooleanVolatile(Object, long)} */
2639     @IntrinsicCandidate
2640     public final boolean getBooleanAcquire(Object o, long offset) {
2641         return getBooleanVolatile(o, offset);
2642     }
2643 
2644     /** Acquire version of {@link #getByteVolatile(Object, long)} */
2645     @IntrinsicCandidate
2646     public final byte getByteAcquire(Object o, long offset) {
2647         return getByteVolatile(o, offset);
2648     }
2649 
2650     /** Acquire version of {@link #getShortVolatile(Object, long)} */
2651     @IntrinsicCandidate
2652     public final short getShortAcquire(Object o, long offset) {
2653         return getShortVolatile(o, offset);
2654     }
2655 
2656     /** Acquire version of {@link #getCharVolatile(Object, long)} */
2657     @IntrinsicCandidate
2658     public final char getCharAcquire(Object o, long offset) {
2659         return getCharVolatile(o, offset);
2660     }
2661 
2662     /** Acquire version of {@link #getIntVolatile(Object, long)} */
2663     @IntrinsicCandidate
2664     public final int getIntAcquire(Object o, long offset) {
2665         return getIntVolatile(o, offset);
2666     }
2667 
2668     /** Acquire version of {@link #getFloatVolatile(Object, long)} */
2669     @IntrinsicCandidate
2670     public final float getFloatAcquire(Object o, long offset) {
2671         return getFloatVolatile(o, offset);
2672     }
2673 
2674     /** Acquire version of {@link #getLongVolatile(Object, long)} */
2675     @IntrinsicCandidate
2676     public final long getLongAcquire(Object o, long offset) {
2677         return getLongVolatile(o, offset);
2678     }
2679 
2680     /** Acquire version of {@link #getDoubleVolatile(Object, long)} */
2681     @IntrinsicCandidate
2682     public final double getDoubleAcquire(Object o, long offset) {
2683         return getDoubleVolatile(o, offset);
2684     }
2685 
2686     /*
2687      * Versions of {@link #putReferenceVolatile(Object, long, Object)}
2688      * that do not guarantee immediate visibility of the store to
2689      * other threads. This method is generally only useful if the
2690      * underlying field is a Java volatile (or if an array cell, one
2691      * that is otherwise only accessed using volatile accesses).
2692      *
2693      * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
2694      */
2695 
2696     /** Release version of {@link #putReferenceVolatile(Object, long, Object)} */
2697     @IntrinsicCandidate
2698     public final void putReferenceRelease(Object o, long offset, Object x) {
2699         putReferenceVolatile(o, offset, x);
2700     }
2701 
2702     @ForceInline
2703     public final <V> void putFlatValueRelease(Object o, long offset, int layout, Class<?> valueType, V x) {
2704         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2705         storeFence();
2706         putFlatValue(o, offset, layout, valueType, x);
2707     }
2708 
2709     /** Release version of {@link #putBooleanVolatile(Object, long, boolean)} */
2710     @IntrinsicCandidate
2711     public final void putBooleanRelease(Object o, long offset, boolean x) {
2712         putBooleanVolatile(o, offset, x);
2713     }
2714 
2715     /** Release version of {@link #putByteVolatile(Object, long, byte)} */
2716     @IntrinsicCandidate
2717     public final void putByteRelease(Object o, long offset, byte x) {
2718         putByteVolatile(o, offset, x);
2719     }
2720 
2721     /** Release version of {@link #putShortVolatile(Object, long, short)} */
2722     @IntrinsicCandidate
2723     public final void putShortRelease(Object o, long offset, short x) {
2724         putShortVolatile(o, offset, x);
2725     }
2726 
2727     /** Release version of {@link #putCharVolatile(Object, long, char)} */
2728     @IntrinsicCandidate
2729     public final void putCharRelease(Object o, long offset, char x) {
2730         putCharVolatile(o, offset, x);
2731     }
2732 
2733     /** Release version of {@link #putIntVolatile(Object, long, int)} */
2734     @IntrinsicCandidate
2735     public final void putIntRelease(Object o, long offset, int x) {
2736         putIntVolatile(o, offset, x);
2737     }
2738 
2739     /** Release version of {@link #putFloatVolatile(Object, long, float)} */
2740     @IntrinsicCandidate
2741     public final void putFloatRelease(Object o, long offset, float x) {
2742         putFloatVolatile(o, offset, x);
2743     }
2744 
2745     /** Release version of {@link #putLongVolatile(Object, long, long)} */
2746     @IntrinsicCandidate
2747     public final void putLongRelease(Object o, long offset, long x) {
2748         putLongVolatile(o, offset, x);
2749     }
2750 
2751     /** Release version of {@link #putDoubleVolatile(Object, long, double)} */
2752     @IntrinsicCandidate
2753     public final void putDoubleRelease(Object o, long offset, double x) {
2754         putDoubleVolatile(o, offset, x);
2755     }
2756 
2757     // ------------------------------ Opaque --------------------------------------
2758 
2759     /** Opaque version of {@link #getReferenceVolatile(Object, long)} */
2760     @IntrinsicCandidate
2761     public final Object getReferenceOpaque(Object o, long offset) {
2762         return getReferenceVolatile(o, offset);
2763     }
2764 
2765     @ForceInline
2766     public final <V> Object getFlatValueOpaque(Object o, long offset, int layout, Class<?> valueType) {
2767         // this is stronger than opaque semantics
2768         return getFlatValueAcquire(o, offset, layout, valueType);
2769     }
2770 
2771     /** Opaque version of {@link #getBooleanVolatile(Object, long)} */
2772     @IntrinsicCandidate
2773     public final boolean getBooleanOpaque(Object o, long offset) {
2774         return getBooleanVolatile(o, offset);
2775     }
2776 
2777     /** Opaque version of {@link #getByteVolatile(Object, long)} */
2778     @IntrinsicCandidate
2779     public final byte getByteOpaque(Object o, long offset) {
2780         return getByteVolatile(o, offset);
2781     }
2782 
2783     /** Opaque version of {@link #getShortVolatile(Object, long)} */
2784     @IntrinsicCandidate
2785     public final short getShortOpaque(Object o, long offset) {
2786         return getShortVolatile(o, offset);
2787     }
2788 
2789     /** Opaque version of {@link #getCharVolatile(Object, long)} */
2790     @IntrinsicCandidate
2791     public final char getCharOpaque(Object o, long offset) {
2792         return getCharVolatile(o, offset);
2793     }
2794 
2795     /** Opaque version of {@link #getIntVolatile(Object, long)} */
2796     @IntrinsicCandidate
2797     public final int getIntOpaque(Object o, long offset) {
2798         return getIntVolatile(o, offset);
2799     }
2800 
2801     /** Opaque version of {@link #getFloatVolatile(Object, long)} */
2802     @IntrinsicCandidate
2803     public final float getFloatOpaque(Object o, long offset) {
2804         return getFloatVolatile(o, offset);
2805     }
2806 
2807     /** Opaque version of {@link #getLongVolatile(Object, long)} */
2808     @IntrinsicCandidate
2809     public final long getLongOpaque(Object o, long offset) {
2810         return getLongVolatile(o, offset);
2811     }
2812 
2813     /** Opaque version of {@link #getDoubleVolatile(Object, long)} */
2814     @IntrinsicCandidate
2815     public final double getDoubleOpaque(Object o, long offset) {
2816         return getDoubleVolatile(o, offset);
2817     }
2818 
2819     /** Opaque version of {@link #putReferenceVolatile(Object, long, Object)} */
2820     @IntrinsicCandidate
2821     public final void putReferenceOpaque(Object o, long offset, Object x) {
2822         putReferenceVolatile(o, offset, x);
2823     }
2824 
2825     @ForceInline
2826     public final <V> void putFlatValueOpaque(Object o, long offset, int layout, Class<?> valueType, V x) {
2827         // this is stronger than opaque semantics
2828         putFlatValueRelease(o, offset, layout, valueType, x);
2829     }
2830 
2831     /** Opaque version of {@link #putBooleanVolatile(Object, long, boolean)} */
2832     @IntrinsicCandidate
2833     public final void putBooleanOpaque(Object o, long offset, boolean x) {
2834         putBooleanVolatile(o, offset, x);
2835     }
2836 
2837     /** Opaque version of {@link #putByteVolatile(Object, long, byte)} */
2838     @IntrinsicCandidate
2839     public final void putByteOpaque(Object o, long offset, byte x) {
2840         putByteVolatile(o, offset, x);
2841     }
2842 
2843     /** Opaque version of {@link #putShortVolatile(Object, long, short)} */
2844     @IntrinsicCandidate
2845     public final void putShortOpaque(Object o, long offset, short x) {
2846         putShortVolatile(o, offset, x);
2847     }
2848 
2849     /** Opaque version of {@link #putCharVolatile(Object, long, char)} */
2850     @IntrinsicCandidate
2851     public final void putCharOpaque(Object o, long offset, char x) {
2852         putCharVolatile(o, offset, x);
2853     }
2854 
2855     /** Opaque version of {@link #putIntVolatile(Object, long, int)} */
2856     @IntrinsicCandidate
2857     public final void putIntOpaque(Object o, long offset, int x) {
2858         putIntVolatile(o, offset, x);
2859     }
2860 
2861     /** Opaque version of {@link #putFloatVolatile(Object, long, float)} */
2862     @IntrinsicCandidate
2863     public final void putFloatOpaque(Object o, long offset, float x) {
2864         putFloatVolatile(o, offset, x);
2865     }
2866 
2867     /** Opaque version of {@link #putLongVolatile(Object, long, long)} */
2868     @IntrinsicCandidate
2869     public final void putLongOpaque(Object o, long offset, long x) {
2870         putLongVolatile(o, offset, x);
2871     }
2872 
2873     /** Opaque version of {@link #putDoubleVolatile(Object, long, double)} */
2874     @IntrinsicCandidate
2875     public final void putDoubleOpaque(Object o, long offset, double x) {
2876         putDoubleVolatile(o, offset, x);
2877     }
2878 
2879     @ForceInline
2880     private boolean compareAndSetFlatValueAsBytes(Object o, long offset, int layout, Class<?> valueType, Object expected, Object x) {
2881         // We turn the payload of an atomic value into a numeric value (of suitable type)
2882         // by storing the value into an array element (of matching layout) and by reading
2883         // back the array element as an integral value. After which we can implement the CAS
2884         // as a plain numeric CAS. Note: this only works if the payload contains no oops
2885         // (see VarHandles::isAtomicFlat).
2886         Object[] expectedArray = newSpecialArray(valueType, 1, layout);
2887         Object xArray = newSpecialArray(valueType, 1, layout);
2888         long base = arrayInstanceBaseOffset(expectedArray);
2889         int scale = arrayInstanceIndexScale(expectedArray);
2890         putFlatValue(expectedArray, base, layout, valueType, expected);
2891         putFlatValue(xArray, base, layout, valueType, x);
2892         switch (scale) {
2893             case 1: {
2894                 byte expectedByte = getByte(expectedArray, base);
2895                 byte xByte = getByte(xArray, base);
2896                 return compareAndSetByte(o, offset, expectedByte, xByte);
2897             }
2898             case 2: {
2899                 short expectedShort = getShort(expectedArray, base);
2900                 short xShort = getShort(xArray, base);
2901                 return compareAndSetShort(o, offset, expectedShort, xShort);
2902             }
2903             case 4: {
2904                 int expectedInt = getInt(expectedArray, base);
2905                 int xInt = getInt(xArray, base);
2906                 return compareAndSetInt(o, offset, expectedInt, xInt);
2907             }
2908             case 8: {
2909                 long expectedLong = getLong(expectedArray, base);
2910                 long xLong = getLong(xArray, base);
2911                 return compareAndSetLong(o, offset, expectedLong, xLong);
2912             }
2913             default: {
2914                 throw new UnsupportedOperationException();
2915             }
2916         }
2917     }
2918 
2919     /**
2920      * Unblocks the given thread blocked on {@code park}, or, if it is
2921      * not blocked, causes the subsequent call to {@code park} not to
2922      * block.  Note: this operation is "unsafe" solely because the
2923      * caller must somehow ensure that the thread has not been
2924      * destroyed. Nothing special is usually required to ensure this
2925      * when called from Java (in which there will ordinarily be a live
2926      * reference to the thread) but this is not nearly-automatically
2927      * so when calling from native code.
2928      *
2929      * @param thread the thread to unpark.
2930      */
2931     @IntrinsicCandidate
2932     public native void unpark(Object thread);
2933 
2934     /**
2935      * Blocks current thread, returning when a balancing
2936      * {@code unpark} occurs, or a balancing {@code unpark} has
2937      * already occurred, or the thread is interrupted, or, if not
2938      * absolute and time is not zero, the given time nanoseconds have
2939      * elapsed, or if absolute, the given deadline in milliseconds
2940      * since Epoch has passed, or spuriously (i.e., returning for no
2941      * "reason"). Note: This operation is in the Unsafe class only
2942      * because {@code unpark} is, so it would be strange to place it
2943      * elsewhere.
2944      */
2945     @IntrinsicCandidate
2946     public native void park(boolean isAbsolute, long time);
2947 
2948     /**
2949      * Gets the load average in the system run queue assigned
2950      * to the available processors averaged over various periods of time.
2951      * This method retrieves the given {@code nelem} samples and
2952      * assigns to the elements of the given {@code loadavg} array.
2953      * The system imposes a maximum of 3 samples, representing
2954      * averages over the last 1,  5,  and  15 minutes, respectively.
2955      *
2956      * @param loadavg an array of double of size nelems
2957      * @param nelems the number of samples to be retrieved and
2958      *        must be 1 to 3.
2959      *
2960      * @return the number of samples actually retrieved; or -1
2961      *         if the load average is unobtainable.
2962      */
2963     public int getLoadAverage(double[] loadavg, int nelems) {
2964         if (nelems < 0 || nelems > 3 || nelems > loadavg.length) {
2965             throw new ArrayIndexOutOfBoundsException();
2966         }
2967 
2968         return getLoadAverage0(loadavg, nelems);
2969     }
2970 
2971     // The following contain CAS-based Java implementations used on
2972     // platforms not supporting native instructions
2973 
2974     /**
2975      * Atomically adds the given value to the current value of a field
2976      * or array element within the given object {@code o}
2977      * at the given {@code offset}.
2978      *
2979      * @param o object/array to update the field/element in
2980      * @param offset field/element offset
2981      * @param delta the value to add
2982      * @return the previous value
2983      * @since 1.8
2984      */
2985     @IntrinsicCandidate
2986     public final int getAndAddInt(Object o, long offset, int delta) {
2987         int v;
2988         do {
2989             v = getIntVolatile(o, offset);
2990         } while (!weakCompareAndSetInt(o, offset, v, v + delta));
2991         return v;
2992     }
2993 
2994     @ForceInline
2995     public final int getAndAddIntRelease(Object o, long offset, int delta) {
2996         int v;
2997         do {
2998             v = getInt(o, offset);
2999         } while (!weakCompareAndSetIntRelease(o, offset, v, v + delta));
3000         return v;
3001     }
3002 
3003     @ForceInline
3004     public final int getAndAddIntAcquire(Object o, long offset, int delta) {
3005         int v;
3006         do {
3007             v = getIntAcquire(o, offset);
3008         } while (!weakCompareAndSetIntAcquire(o, offset, v, v + delta));
3009         return v;
3010     }
3011 
3012     /**
3013      * Atomically adds the given value to the current value of a field
3014      * or array element within the given object {@code o}
3015      * at the given {@code offset}.
3016      *
3017      * @param o object/array to update the field/element in
3018      * @param offset field/element offset
3019      * @param delta the value to add
3020      * @return the previous value
3021      * @since 1.8
3022      */
3023     @IntrinsicCandidate
3024     public final long getAndAddLong(Object o, long offset, long delta) {
3025         long v;
3026         do {
3027             v = getLongVolatile(o, offset);
3028         } while (!weakCompareAndSetLong(o, offset, v, v + delta));
3029         return v;
3030     }
3031 
3032     @ForceInline
3033     public final long getAndAddLongRelease(Object o, long offset, long delta) {
3034         long v;
3035         do {
3036             v = getLong(o, offset);
3037         } while (!weakCompareAndSetLongRelease(o, offset, v, v + delta));
3038         return v;
3039     }
3040 
3041     @ForceInline
3042     public final long getAndAddLongAcquire(Object o, long offset, long delta) {
3043         long v;
3044         do {
3045             v = getLongAcquire(o, offset);
3046         } while (!weakCompareAndSetLongAcquire(o, offset, v, v + delta));
3047         return v;
3048     }
3049 
3050     @IntrinsicCandidate
3051     public final byte getAndAddByte(Object o, long offset, byte delta) {
3052         byte v;
3053         do {
3054             v = getByteVolatile(o, offset);
3055         } while (!weakCompareAndSetByte(o, offset, v, (byte) (v + delta)));
3056         return v;
3057     }
3058 
3059     @ForceInline
3060     public final byte getAndAddByteRelease(Object o, long offset, byte delta) {
3061         byte v;
3062         do {
3063             v = getByte(o, offset);
3064         } while (!weakCompareAndSetByteRelease(o, offset, v, (byte) (v + delta)));
3065         return v;
3066     }
3067 
3068     @ForceInline
3069     public final byte getAndAddByteAcquire(Object o, long offset, byte delta) {
3070         byte v;
3071         do {
3072             v = getByteAcquire(o, offset);
3073         } while (!weakCompareAndSetByteAcquire(o, offset, v, (byte) (v + delta)));
3074         return v;
3075     }
3076 
3077     @IntrinsicCandidate
3078     public final short getAndAddShort(Object o, long offset, short delta) {
3079         short v;
3080         do {
3081             v = getShortVolatile(o, offset);
3082         } while (!weakCompareAndSetShort(o, offset, v, (short) (v + delta)));
3083         return v;
3084     }
3085 
3086     @ForceInline
3087     public final short getAndAddShortRelease(Object o, long offset, short delta) {
3088         short v;
3089         do {
3090             v = getShort(o, offset);
3091         } while (!weakCompareAndSetShortRelease(o, offset, v, (short) (v + delta)));
3092         return v;
3093     }
3094 
3095     @ForceInline
3096     public final short getAndAddShortAcquire(Object o, long offset, short delta) {
3097         short v;
3098         do {
3099             v = getShortAcquire(o, offset);
3100         } while (!weakCompareAndSetShortAcquire(o, offset, v, (short) (v + delta)));
3101         return v;
3102     }
3103 
3104     @ForceInline
3105     public final char getAndAddChar(Object o, long offset, char delta) {
3106         return (char) getAndAddShort(o, offset, (short) delta);
3107     }
3108 
3109     @ForceInline
3110     public final char getAndAddCharRelease(Object o, long offset, char delta) {
3111         return (char) getAndAddShortRelease(o, offset, (short) delta);
3112     }
3113 
3114     @ForceInline
3115     public final char getAndAddCharAcquire(Object o, long offset, char delta) {
3116         return (char) getAndAddShortAcquire(o, offset, (short) delta);
3117     }
3118 
3119     @ForceInline
3120     public final float getAndAddFloat(Object o, long offset, float delta) {
3121         int expectedBits;
3122         float v;
3123         do {
3124             // Load and CAS with the raw bits to avoid issues with NaNs and
3125             // possible bit conversion from signaling NaNs to quiet NaNs that
3126             // may result in the loop not terminating.
3127             expectedBits = getIntVolatile(o, offset);
3128             v = Float.intBitsToFloat(expectedBits);
3129         } while (!weakCompareAndSetInt(o, offset,
3130                                                 expectedBits, Float.floatToRawIntBits(v + delta)));
3131         return v;
3132     }
3133 
3134     @ForceInline
3135     public final float getAndAddFloatRelease(Object o, long offset, float delta) {
3136         int expectedBits;
3137         float v;
3138         do {
3139             // Load and CAS with the raw bits to avoid issues with NaNs and
3140             // possible bit conversion from signaling NaNs to quiet NaNs that
3141             // may result in the loop not terminating.
3142             expectedBits = getInt(o, offset);
3143             v = Float.intBitsToFloat(expectedBits);
3144         } while (!weakCompareAndSetIntRelease(o, offset,
3145                                                expectedBits, Float.floatToRawIntBits(v + delta)));
3146         return v;
3147     }
3148 
3149     @ForceInline
3150     public final float getAndAddFloatAcquire(Object o, long offset, float delta) {
3151         int expectedBits;
3152         float v;
3153         do {
3154             // Load and CAS with the raw bits to avoid issues with NaNs and
3155             // possible bit conversion from signaling NaNs to quiet NaNs that
3156             // may result in the loop not terminating.
3157             expectedBits = getIntAcquire(o, offset);
3158             v = Float.intBitsToFloat(expectedBits);
3159         } while (!weakCompareAndSetIntAcquire(o, offset,
3160                                                expectedBits, Float.floatToRawIntBits(v + delta)));
3161         return v;
3162     }
3163 
3164     @ForceInline
3165     public final double getAndAddDouble(Object o, long offset, double delta) {
3166         long expectedBits;
3167         double v;
3168         do {
3169             // Load and CAS with the raw bits to avoid issues with NaNs and
3170             // possible bit conversion from signaling NaNs to quiet NaNs that
3171             // may result in the loop not terminating.
3172             expectedBits = getLongVolatile(o, offset);
3173             v = Double.longBitsToDouble(expectedBits);
3174         } while (!weakCompareAndSetLong(o, offset,
3175                                                  expectedBits, Double.doubleToRawLongBits(v + delta)));
3176         return v;
3177     }
3178 
3179     @ForceInline
3180     public final double getAndAddDoubleRelease(Object o, long offset, double delta) {
3181         long expectedBits;
3182         double v;
3183         do {
3184             // Load and CAS with the raw bits to avoid issues with NaNs and
3185             // possible bit conversion from signaling NaNs to quiet NaNs that
3186             // may result in the loop not terminating.
3187             expectedBits = getLong(o, offset);
3188             v = Double.longBitsToDouble(expectedBits);
3189         } while (!weakCompareAndSetLongRelease(o, offset,
3190                                                 expectedBits, Double.doubleToRawLongBits(v + delta)));
3191         return v;
3192     }
3193 
3194     @ForceInline
3195     public final double getAndAddDoubleAcquire(Object o, long offset, double delta) {
3196         long expectedBits;
3197         double v;
3198         do {
3199             // Load and CAS with the raw bits to avoid issues with NaNs and
3200             // possible bit conversion from signaling NaNs to quiet NaNs that
3201             // may result in the loop not terminating.
3202             expectedBits = getLongAcquire(o, offset);
3203             v = Double.longBitsToDouble(expectedBits);
3204         } while (!weakCompareAndSetLongAcquire(o, offset,
3205                                                 expectedBits, Double.doubleToRawLongBits(v + delta)));
3206         return v;
3207     }
3208 
3209     /**
3210      * Atomically exchanges the given value with the current value of
3211      * a field or array element within the given object {@code o}
3212      * at the given {@code offset}.
3213      *
3214      * @param o object/array to update the field/element in
3215      * @param offset field/element offset
3216      * @param newValue new value
3217      * @return the previous value
3218      * @since 1.8
3219      */
3220     @IntrinsicCandidate
3221     public final int getAndSetInt(Object o, long offset, int newValue) {
3222         int v;
3223         do {
3224             v = getIntVolatile(o, offset);
3225         } while (!weakCompareAndSetInt(o, offset, v, newValue));
3226         return v;
3227     }
3228 
3229     @ForceInline
3230     public final int getAndSetIntRelease(Object o, long offset, int newValue) {
3231         int v;
3232         do {
3233             v = getInt(o, offset);
3234         } while (!weakCompareAndSetIntRelease(o, offset, v, newValue));
3235         return v;
3236     }
3237 
3238     @ForceInline
3239     public final int getAndSetIntAcquire(Object o, long offset, int newValue) {
3240         int v;
3241         do {
3242             v = getIntAcquire(o, offset);
3243         } while (!weakCompareAndSetIntAcquire(o, offset, v, newValue));
3244         return v;
3245     }
3246 
3247     /**
3248      * Atomically exchanges the given value with the current value of
3249      * a field or array element within the given object {@code o}
3250      * at the given {@code offset}.
3251      *
3252      * @param o object/array to update the field/element in
3253      * @param offset field/element offset
3254      * @param newValue new value
3255      * @return the previous value
3256      * @since 1.8
3257      */
3258     @IntrinsicCandidate
3259     public final long getAndSetLong(Object o, long offset, long newValue) {
3260         long v;
3261         do {
3262             v = getLongVolatile(o, offset);
3263         } while (!weakCompareAndSetLong(o, offset, v, newValue));
3264         return v;
3265     }
3266 
3267     @ForceInline
3268     public final long getAndSetLongRelease(Object o, long offset, long newValue) {
3269         long v;
3270         do {
3271             v = getLong(o, offset);
3272         } while (!weakCompareAndSetLongRelease(o, offset, v, newValue));
3273         return v;
3274     }
3275 
3276     @ForceInline
3277     public final long getAndSetLongAcquire(Object o, long offset, long newValue) {
3278         long v;
3279         do {
3280             v = getLongAcquire(o, offset);
3281         } while (!weakCompareAndSetLongAcquire(o, offset, v, newValue));
3282         return v;
3283     }
3284 
3285     /**
3286      * Atomically exchanges the given reference value with the current
3287      * reference value of a field or array element within the given
3288      * object {@code o} at the given {@code offset}.
3289      *
3290      * @param o object/array to update the field/element in
3291      * @param offset field/element offset
3292      * @param newValue new value
3293      * @return the previous value
3294      * @since 1.8
3295      */
3296     @IntrinsicCandidate
3297     public final Object getAndSetReference(Object o, long offset, Object newValue) {
3298         Object v;
3299         do {
3300             v = getReferenceVolatile(o, offset);
3301         } while (!weakCompareAndSetReference(o, offset, v, newValue));
3302         return v;
3303     }
3304 
3305     @ForceInline
3306     public final Object getAndSetReference(Object o, long offset, Class<?> valueType, Object newValue) {
3307         Object v;
3308         do {
3309             v = getReferenceVolatile(o, offset);
3310         } while (!compareAndSetReference(o, offset, valueType, v, newValue));
3311         return v;
3312     }
3313 
3314     @ForceInline
3315     public Object getAndSetFlatValue(Object o, long offset, int layoutKind, Class<?> valueType, Object newValue) {
3316         Object v;
3317         do {
3318             v = getFlatValueVolatile(o, offset, layoutKind, valueType);
3319         } while (!compareAndSetFlatValue(o, offset, layoutKind, valueType, v, newValue));
3320         return v;
3321     }
3322 
3323     @ForceInline
3324     public final Object getAndSetReferenceRelease(Object o, long offset, Object newValue) {
3325         Object v;
3326         do {
3327             v = getReference(o, offset);
3328         } while (!weakCompareAndSetReferenceRelease(o, offset, v, newValue));
3329         return v;
3330     }
3331 
3332     @ForceInline
3333     public final Object getAndSetReferenceRelease(Object o, long offset, Class<?> valueType, Object newValue) {
3334         return getAndSetReference(o, offset, valueType, newValue);
3335     }
3336 
3337     @ForceInline
3338     public Object getAndSetFlatValueRelease(Object o, long offset, int layoutKind, Class<?> valueType, Object x) {
3339         return getAndSetFlatValue(o, offset, layoutKind, valueType, x);
3340     }
3341 
3342     @ForceInline
3343     public final Object getAndSetReferenceAcquire(Object o, long offset, Object newValue) {
3344         Object v;
3345         do {
3346             v = getReferenceAcquire(o, offset);
3347         } while (!weakCompareAndSetReferenceAcquire(o, offset, v, newValue));
3348         return v;
3349     }
3350 
3351     @ForceInline
3352     public final Object getAndSetReferenceAcquire(Object o, long offset, Class<?> valueType, Object newValue) {
3353         return getAndSetReference(o, offset, valueType, newValue);
3354     }
3355 
3356     @ForceInline
3357     public Object getAndSetFlatValueAcquire(Object o, long offset, int layoutKind, Class<?> valueType, Object x) {
3358         return getAndSetFlatValue(o, offset, layoutKind, valueType, x);
3359     }
3360 
3361     @IntrinsicCandidate
3362     public final byte getAndSetByte(Object o, long offset, byte newValue) {
3363         byte v;
3364         do {
3365             v = getByteVolatile(o, offset);
3366         } while (!weakCompareAndSetByte(o, offset, v, newValue));
3367         return v;
3368     }
3369 
3370     @ForceInline
3371     public final byte getAndSetByteRelease(Object o, long offset, byte newValue) {
3372         byte v;
3373         do {
3374             v = getByte(o, offset);
3375         } while (!weakCompareAndSetByteRelease(o, offset, v, newValue));
3376         return v;
3377     }
3378 
3379     @ForceInline
3380     public final byte getAndSetByteAcquire(Object o, long offset, byte newValue) {
3381         byte v;
3382         do {
3383             v = getByteAcquire(o, offset);
3384         } while (!weakCompareAndSetByteAcquire(o, offset, v, newValue));
3385         return v;
3386     }
3387 
3388     @ForceInline
3389     public final boolean getAndSetBoolean(Object o, long offset, boolean newValue) {
3390         return byte2bool(getAndSetByte(o, offset, bool2byte(newValue)));
3391     }
3392 
3393     @ForceInline
3394     public final boolean getAndSetBooleanRelease(Object o, long offset, boolean newValue) {
3395         return byte2bool(getAndSetByteRelease(o, offset, bool2byte(newValue)));
3396     }
3397 
3398     @ForceInline
3399     public final boolean getAndSetBooleanAcquire(Object o, long offset, boolean newValue) {
3400         return byte2bool(getAndSetByteAcquire(o, offset, bool2byte(newValue)));
3401     }
3402 
3403     @IntrinsicCandidate
3404     public final short getAndSetShort(Object o, long offset, short newValue) {
3405         short v;
3406         do {
3407             v = getShortVolatile(o, offset);
3408         } while (!weakCompareAndSetShort(o, offset, v, newValue));
3409         return v;
3410     }
3411 
3412     @ForceInline
3413     public final short getAndSetShortRelease(Object o, long offset, short newValue) {
3414         short v;
3415         do {
3416             v = getShort(o, offset);
3417         } while (!weakCompareAndSetShortRelease(o, offset, v, newValue));
3418         return v;
3419     }
3420 
3421     @ForceInline
3422     public final short getAndSetShortAcquire(Object o, long offset, short newValue) {
3423         short v;
3424         do {
3425             v = getShortAcquire(o, offset);
3426         } while (!weakCompareAndSetShortAcquire(o, offset, v, newValue));
3427         return v;
3428     }
3429 
3430     @ForceInline
3431     public final char getAndSetChar(Object o, long offset, char newValue) {
3432         return s2c(getAndSetShort(o, offset, c2s(newValue)));
3433     }
3434 
3435     @ForceInline
3436     public final char getAndSetCharRelease(Object o, long offset, char newValue) {
3437         return s2c(getAndSetShortRelease(o, offset, c2s(newValue)));
3438     }
3439 
3440     @ForceInline
3441     public final char getAndSetCharAcquire(Object o, long offset, char newValue) {
3442         return s2c(getAndSetShortAcquire(o, offset, c2s(newValue)));
3443     }
3444 
3445     @ForceInline
3446     public final float getAndSetFloat(Object o, long offset, float newValue) {
3447         int v = getAndSetInt(o, offset, Float.floatToRawIntBits(newValue));
3448         return Float.intBitsToFloat(v);
3449     }
3450 
3451     @ForceInline
3452     public final float getAndSetFloatRelease(Object o, long offset, float newValue) {
3453         int v = getAndSetIntRelease(o, offset, Float.floatToRawIntBits(newValue));
3454         return Float.intBitsToFloat(v);
3455     }
3456 
3457     @ForceInline
3458     public final float getAndSetFloatAcquire(Object o, long offset, float newValue) {
3459         int v = getAndSetIntAcquire(o, offset, Float.floatToRawIntBits(newValue));
3460         return Float.intBitsToFloat(v);
3461     }
3462 
3463     @ForceInline
3464     public final double getAndSetDouble(Object o, long offset, double newValue) {
3465         long v = getAndSetLong(o, offset, Double.doubleToRawLongBits(newValue));
3466         return Double.longBitsToDouble(v);
3467     }
3468 
3469     @ForceInline
3470     public final double getAndSetDoubleRelease(Object o, long offset, double newValue) {
3471         long v = getAndSetLongRelease(o, offset, Double.doubleToRawLongBits(newValue));
3472         return Double.longBitsToDouble(v);
3473     }
3474 
3475     @ForceInline
3476     public final double getAndSetDoubleAcquire(Object o, long offset, double newValue) {
3477         long v = getAndSetLongAcquire(o, offset, Double.doubleToRawLongBits(newValue));
3478         return Double.longBitsToDouble(v);
3479     }
3480 
3481 
3482     // The following contain CAS-based Java implementations used on
3483     // platforms not supporting native instructions
3484 
3485     @ForceInline
3486     public final boolean getAndBitwiseOrBoolean(Object o, long offset, boolean mask) {
3487         return byte2bool(getAndBitwiseOrByte(o, offset, bool2byte(mask)));
3488     }
3489 
3490     @ForceInline
3491     public final boolean getAndBitwiseOrBooleanRelease(Object o, long offset, boolean mask) {
3492         return byte2bool(getAndBitwiseOrByteRelease(o, offset, bool2byte(mask)));
3493     }
3494 
3495     @ForceInline
3496     public final boolean getAndBitwiseOrBooleanAcquire(Object o, long offset, boolean mask) {
3497         return byte2bool(getAndBitwiseOrByteAcquire(o, offset, bool2byte(mask)));
3498     }
3499 
3500     @ForceInline
3501     public final boolean getAndBitwiseAndBoolean(Object o, long offset, boolean mask) {
3502         return byte2bool(getAndBitwiseAndByte(o, offset, bool2byte(mask)));
3503     }
3504 
3505     @ForceInline
3506     public final boolean getAndBitwiseAndBooleanRelease(Object o, long offset, boolean mask) {
3507         return byte2bool(getAndBitwiseAndByteRelease(o, offset, bool2byte(mask)));
3508     }
3509 
3510     @ForceInline
3511     public final boolean getAndBitwiseAndBooleanAcquire(Object o, long offset, boolean mask) {
3512         return byte2bool(getAndBitwiseAndByteAcquire(o, offset, bool2byte(mask)));
3513     }
3514 
3515     @ForceInline
3516     public final boolean getAndBitwiseXorBoolean(Object o, long offset, boolean mask) {
3517         return byte2bool(getAndBitwiseXorByte(o, offset, bool2byte(mask)));
3518     }
3519 
3520     @ForceInline
3521     public final boolean getAndBitwiseXorBooleanRelease(Object o, long offset, boolean mask) {
3522         return byte2bool(getAndBitwiseXorByteRelease(o, offset, bool2byte(mask)));
3523     }
3524 
3525     @ForceInline
3526     public final boolean getAndBitwiseXorBooleanAcquire(Object o, long offset, boolean mask) {
3527         return byte2bool(getAndBitwiseXorByteAcquire(o, offset, bool2byte(mask)));
3528     }
3529 
3530 
3531     @ForceInline
3532     public final byte getAndBitwiseOrByte(Object o, long offset, byte mask) {
3533         byte current;
3534         do {
3535             current = getByteVolatile(o, offset);
3536         } while (!weakCompareAndSetByte(o, offset,
3537                                                   current, (byte) (current | mask)));
3538         return current;
3539     }
3540 
3541     @ForceInline
3542     public final byte getAndBitwiseOrByteRelease(Object o, long offset, byte mask) {
3543         byte current;
3544         do {
3545             current = getByte(o, offset);
3546         } while (!weakCompareAndSetByteRelease(o, offset,
3547                                                  current, (byte) (current | mask)));
3548         return current;
3549     }
3550 
3551     @ForceInline
3552     public final byte getAndBitwiseOrByteAcquire(Object o, long offset, byte mask) {
3553         byte current;
3554         do {
3555             // Plain read, the value is a hint, the acquire CAS does the work
3556             current = getByte(o, offset);
3557         } while (!weakCompareAndSetByteAcquire(o, offset,
3558                                                  current, (byte) (current | mask)));
3559         return current;
3560     }
3561 
3562     @ForceInline
3563     public final byte getAndBitwiseAndByte(Object o, long offset, byte mask) {
3564         byte current;
3565         do {
3566             current = getByteVolatile(o, offset);
3567         } while (!weakCompareAndSetByte(o, offset,
3568                                                   current, (byte) (current & mask)));
3569         return current;
3570     }
3571 
3572     @ForceInline
3573     public final byte getAndBitwiseAndByteRelease(Object o, long offset, byte mask) {
3574         byte current;
3575         do {
3576             current = getByte(o, offset);
3577         } while (!weakCompareAndSetByteRelease(o, offset,
3578                                                  current, (byte) (current & mask)));
3579         return current;
3580     }
3581 
3582     @ForceInline
3583     public final byte getAndBitwiseAndByteAcquire(Object o, long offset, byte mask) {
3584         byte current;
3585         do {
3586             // Plain read, the value is a hint, the acquire CAS does the work
3587             current = getByte(o, offset);
3588         } while (!weakCompareAndSetByteAcquire(o, offset,
3589                                                  current, (byte) (current & mask)));
3590         return current;
3591     }
3592 
3593     @ForceInline
3594     public final byte getAndBitwiseXorByte(Object o, long offset, byte mask) {
3595         byte current;
3596         do {
3597             current = getByteVolatile(o, offset);
3598         } while (!weakCompareAndSetByte(o, offset,
3599                                                   current, (byte) (current ^ mask)));
3600         return current;
3601     }
3602 
3603     @ForceInline
3604     public final byte getAndBitwiseXorByteRelease(Object o, long offset, byte mask) {
3605         byte current;
3606         do {
3607             current = getByte(o, offset);
3608         } while (!weakCompareAndSetByteRelease(o, offset,
3609                                                  current, (byte) (current ^ mask)));
3610         return current;
3611     }
3612 
3613     @ForceInline
3614     public final byte getAndBitwiseXorByteAcquire(Object o, long offset, byte mask) {
3615         byte current;
3616         do {
3617             // Plain read, the value is a hint, the acquire CAS does the work
3618             current = getByte(o, offset);
3619         } while (!weakCompareAndSetByteAcquire(o, offset,
3620                                                  current, (byte) (current ^ mask)));
3621         return current;
3622     }
3623 
3624 
3625     @ForceInline
3626     public final char getAndBitwiseOrChar(Object o, long offset, char mask) {
3627         return s2c(getAndBitwiseOrShort(o, offset, c2s(mask)));
3628     }
3629 
3630     @ForceInline
3631     public final char getAndBitwiseOrCharRelease(Object o, long offset, char mask) {
3632         return s2c(getAndBitwiseOrShortRelease(o, offset, c2s(mask)));
3633     }
3634 
3635     @ForceInline
3636     public final char getAndBitwiseOrCharAcquire(Object o, long offset, char mask) {
3637         return s2c(getAndBitwiseOrShortAcquire(o, offset, c2s(mask)));
3638     }
3639 
3640     @ForceInline
3641     public final char getAndBitwiseAndChar(Object o, long offset, char mask) {
3642         return s2c(getAndBitwiseAndShort(o, offset, c2s(mask)));
3643     }
3644 
3645     @ForceInline
3646     public final char getAndBitwiseAndCharRelease(Object o, long offset, char mask) {
3647         return s2c(getAndBitwiseAndShortRelease(o, offset, c2s(mask)));
3648     }
3649 
3650     @ForceInline
3651     public final char getAndBitwiseAndCharAcquire(Object o, long offset, char mask) {
3652         return s2c(getAndBitwiseAndShortAcquire(o, offset, c2s(mask)));
3653     }
3654 
3655     @ForceInline
3656     public final char getAndBitwiseXorChar(Object o, long offset, char mask) {
3657         return s2c(getAndBitwiseXorShort(o, offset, c2s(mask)));
3658     }
3659 
3660     @ForceInline
3661     public final char getAndBitwiseXorCharRelease(Object o, long offset, char mask) {
3662         return s2c(getAndBitwiseXorShortRelease(o, offset, c2s(mask)));
3663     }
3664 
3665     @ForceInline
3666     public final char getAndBitwiseXorCharAcquire(Object o, long offset, char mask) {
3667         return s2c(getAndBitwiseXorShortAcquire(o, offset, c2s(mask)));
3668     }
3669 
3670 
3671     @ForceInline
3672     public final short getAndBitwiseOrShort(Object o, long offset, short mask) {
3673         short current;
3674         do {
3675             current = getShortVolatile(o, offset);
3676         } while (!weakCompareAndSetShort(o, offset,
3677                                                 current, (short) (current | mask)));
3678         return current;
3679     }
3680 
3681     @ForceInline
3682     public final short getAndBitwiseOrShortRelease(Object o, long offset, short mask) {
3683         short current;
3684         do {
3685             current = getShort(o, offset);
3686         } while (!weakCompareAndSetShortRelease(o, offset,
3687                                                current, (short) (current | mask)));
3688         return current;
3689     }
3690 
3691     @ForceInline
3692     public final short getAndBitwiseOrShortAcquire(Object o, long offset, short mask) {
3693         short current;
3694         do {
3695             // Plain read, the value is a hint, the acquire CAS does the work
3696             current = getShort(o, offset);
3697         } while (!weakCompareAndSetShortAcquire(o, offset,
3698                                                current, (short) (current | mask)));
3699         return current;
3700     }
3701 
3702     @ForceInline
3703     public final short getAndBitwiseAndShort(Object o, long offset, short mask) {
3704         short current;
3705         do {
3706             current = getShortVolatile(o, offset);
3707         } while (!weakCompareAndSetShort(o, offset,
3708                                                 current, (short) (current & mask)));
3709         return current;
3710     }
3711 
3712     @ForceInline
3713     public final short getAndBitwiseAndShortRelease(Object o, long offset, short mask) {
3714         short current;
3715         do {
3716             current = getShort(o, offset);
3717         } while (!weakCompareAndSetShortRelease(o, offset,
3718                                                current, (short) (current & mask)));
3719         return current;
3720     }
3721 
3722     @ForceInline
3723     public final short getAndBitwiseAndShortAcquire(Object o, long offset, short mask) {
3724         short current;
3725         do {
3726             // Plain read, the value is a hint, the acquire CAS does the work
3727             current = getShort(o, offset);
3728         } while (!weakCompareAndSetShortAcquire(o, offset,
3729                                                current, (short) (current & mask)));
3730         return current;
3731     }
3732 
3733     @ForceInline
3734     public final short getAndBitwiseXorShort(Object o, long offset, short mask) {
3735         short current;
3736         do {
3737             current = getShortVolatile(o, offset);
3738         } while (!weakCompareAndSetShort(o, offset,
3739                                                 current, (short) (current ^ mask)));
3740         return current;
3741     }
3742 
3743     @ForceInline
3744     public final short getAndBitwiseXorShortRelease(Object o, long offset, short mask) {
3745         short current;
3746         do {
3747             current = getShort(o, offset);
3748         } while (!weakCompareAndSetShortRelease(o, offset,
3749                                                current, (short) (current ^ mask)));
3750         return current;
3751     }
3752 
3753     @ForceInline
3754     public final short getAndBitwiseXorShortAcquire(Object o, long offset, short mask) {
3755         short current;
3756         do {
3757             // Plain read, the value is a hint, the acquire CAS does the work
3758             current = getShort(o, offset);
3759         } while (!weakCompareAndSetShortAcquire(o, offset,
3760                                                current, (short) (current ^ mask)));
3761         return current;
3762     }
3763 
3764 
3765     @ForceInline
3766     public final int getAndBitwiseOrInt(Object o, long offset, int mask) {
3767         int current;
3768         do {
3769             current = getIntVolatile(o, offset);
3770         } while (!weakCompareAndSetInt(o, offset,
3771                                                 current, current | mask));
3772         return current;
3773     }
3774 
3775     @ForceInline
3776     public final int getAndBitwiseOrIntRelease(Object o, long offset, int mask) {
3777         int current;
3778         do {
3779             current = getInt(o, offset);
3780         } while (!weakCompareAndSetIntRelease(o, offset,
3781                                                current, current | mask));
3782         return current;
3783     }
3784 
3785     @ForceInline
3786     public final int getAndBitwiseOrIntAcquire(Object o, long offset, int mask) {
3787         int current;
3788         do {
3789             // Plain read, the value is a hint, the acquire CAS does the work
3790             current = getInt(o, offset);
3791         } while (!weakCompareAndSetIntAcquire(o, offset,
3792                                                current, current | mask));
3793         return current;
3794     }
3795 
3796     /**
3797      * Atomically replaces the current value of a field or array element within
3798      * the given object with the result of bitwise AND between the current value
3799      * and mask.
3800      *
3801      * @param o object/array to update the field/element in
3802      * @param offset field/element offset
3803      * @param mask the mask value
3804      * @return the previous value
3805      * @since 9
3806      */
3807     @ForceInline
3808     public final int getAndBitwiseAndInt(Object o, long offset, int mask) {
3809         int current;
3810         do {
3811             current = getIntVolatile(o, offset);
3812         } while (!weakCompareAndSetInt(o, offset,
3813                                                 current, current & mask));
3814         return current;
3815     }
3816 
3817     @ForceInline
3818     public final int getAndBitwiseAndIntRelease(Object o, long offset, int mask) {
3819         int current;
3820         do {
3821             current = getInt(o, offset);
3822         } while (!weakCompareAndSetIntRelease(o, offset,
3823                                                current, current & mask));
3824         return current;
3825     }
3826 
3827     @ForceInline
3828     public final int getAndBitwiseAndIntAcquire(Object o, long offset, int mask) {
3829         int current;
3830         do {
3831             // Plain read, the value is a hint, the acquire CAS does the work
3832             current = getInt(o, offset);
3833         } while (!weakCompareAndSetIntAcquire(o, offset,
3834                                                current, current & mask));
3835         return current;
3836     }
3837 
3838     @ForceInline
3839     public final int getAndBitwiseXorInt(Object o, long offset, int mask) {
3840         int current;
3841         do {
3842             current = getIntVolatile(o, offset);
3843         } while (!weakCompareAndSetInt(o, offset,
3844                                                 current, current ^ mask));
3845         return current;
3846     }
3847 
3848     @ForceInline
3849     public final int getAndBitwiseXorIntRelease(Object o, long offset, int mask) {
3850         int current;
3851         do {
3852             current = getInt(o, offset);
3853         } while (!weakCompareAndSetIntRelease(o, offset,
3854                                                current, current ^ mask));
3855         return current;
3856     }
3857 
3858     @ForceInline
3859     public final int getAndBitwiseXorIntAcquire(Object o, long offset, int mask) {
3860         int current;
3861         do {
3862             // Plain read, the value is a hint, the acquire CAS does the work
3863             current = getInt(o, offset);
3864         } while (!weakCompareAndSetIntAcquire(o, offset,
3865                                                current, current ^ mask));
3866         return current;
3867     }
3868 
3869 
3870     @ForceInline
3871     public final long getAndBitwiseOrLong(Object o, long offset, long mask) {
3872         long current;
3873         do {
3874             current = getLongVolatile(o, offset);
3875         } while (!weakCompareAndSetLong(o, offset,
3876                                                 current, current | mask));
3877         return current;
3878     }
3879 
3880     @ForceInline
3881     public final long getAndBitwiseOrLongRelease(Object o, long offset, long mask) {
3882         long current;
3883         do {
3884             current = getLong(o, offset);
3885         } while (!weakCompareAndSetLongRelease(o, offset,
3886                                                current, current | mask));
3887         return current;
3888     }
3889 
3890     @ForceInline
3891     public final long getAndBitwiseOrLongAcquire(Object o, long offset, long mask) {
3892         long current;
3893         do {
3894             // Plain read, the value is a hint, the acquire CAS does the work
3895             current = getLong(o, offset);
3896         } while (!weakCompareAndSetLongAcquire(o, offset,
3897                                                current, current | mask));
3898         return current;
3899     }
3900 
3901     @ForceInline
3902     public final long getAndBitwiseAndLong(Object o, long offset, long mask) {
3903         long current;
3904         do {
3905             current = getLongVolatile(o, offset);
3906         } while (!weakCompareAndSetLong(o, offset,
3907                                                 current, current & mask));
3908         return current;
3909     }
3910 
3911     @ForceInline
3912     public final long getAndBitwiseAndLongRelease(Object o, long offset, long mask) {
3913         long current;
3914         do {
3915             current = getLong(o, offset);
3916         } while (!weakCompareAndSetLongRelease(o, offset,
3917                                                current, current & mask));
3918         return current;
3919     }
3920 
3921     @ForceInline
3922     public final long getAndBitwiseAndLongAcquire(Object o, long offset, long mask) {
3923         long current;
3924         do {
3925             // Plain read, the value is a hint, the acquire CAS does the work
3926             current = getLong(o, offset);
3927         } while (!weakCompareAndSetLongAcquire(o, offset,
3928                                                current, current & mask));
3929         return current;
3930     }
3931 
3932     @ForceInline
3933     public final long getAndBitwiseXorLong(Object o, long offset, long mask) {
3934         long current;
3935         do {
3936             current = getLongVolatile(o, offset);
3937         } while (!weakCompareAndSetLong(o, offset,
3938                                                 current, current ^ mask));
3939         return current;
3940     }
3941 
3942     @ForceInline
3943     public final long getAndBitwiseXorLongRelease(Object o, long offset, long mask) {
3944         long current;
3945         do {
3946             current = getLong(o, offset);
3947         } while (!weakCompareAndSetLongRelease(o, offset,
3948                                                current, current ^ mask));
3949         return current;
3950     }
3951 
3952     @ForceInline
3953     public final long getAndBitwiseXorLongAcquire(Object o, long offset, long mask) {
3954         long current;
3955         do {
3956             // Plain read, the value is a hint, the acquire CAS does the work
3957             current = getLong(o, offset);
3958         } while (!weakCompareAndSetLongAcquire(o, offset,
3959                                                current, current ^ mask));
3960         return current;
3961     }
3962 
3963 
3964 
3965     /**
3966      * Ensures that loads before the fence will not be reordered with loads and
3967      * stores after the fence; a "LoadLoad plus LoadStore barrier".
3968      *
3969      * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
3970      * (an "acquire fence").
3971      *
3972      * Provides a LoadLoad barrier followed by a LoadStore barrier.
3973      *
3974      * @since 1.8
3975      */
3976     @IntrinsicCandidate
3977     public final void loadFence() {
3978         // If loadFence intrinsic is not available, fall back to full fence.
3979         fullFence();
3980     }
3981 
3982     /**
3983      * Ensures that loads and stores before the fence will not be reordered with
3984      * stores after the fence; a "StoreStore plus LoadStore barrier".
3985      *
3986      * Corresponds to C11 atomic_thread_fence(memory_order_release)
3987      * (a "release fence").
3988      *
3989      * Provides a StoreStore barrier followed by a LoadStore barrier.
3990      *
3991      * @since 1.8
3992      */
3993     @IntrinsicCandidate
3994     public final void storeFence() {
3995         // If storeFence intrinsic is not available, fall back to full fence.
3996         fullFence();
3997     }
3998 
3999     /**
4000      * Ensures that loads and stores before the fence will not be reordered
4001      * with loads and stores after the fence.  Implies the effects of both
4002      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
4003      * barrier.
4004      *
4005      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
4006      * @since 1.8
4007      */
4008     @IntrinsicCandidate
4009     public native void fullFence();
4010 
4011     /**
4012      * Ensures that loads before the fence will not be reordered with
4013      * loads after the fence.
4014      *
4015      * @implNote
4016      * This method is operationally equivalent to {@link #loadFence()}.
4017      *
4018      * @since 9
4019      */
4020     public final void loadLoadFence() {
4021         loadFence();
4022     }
4023 
4024     /**
4025      * Ensures that stores before the fence will not be reordered with
4026      * stores after the fence.
4027      *
4028      * @since 9
4029      */
4030     @IntrinsicCandidate
4031     public final void storeStoreFence() {
4032         // If storeStoreFence intrinsic is not available, fall back to storeFence.
4033         storeFence();
4034     }
4035 
4036     /**
4037      * Throws IllegalAccessError; for use by the VM for access control
4038      * error support.
4039      * @since 1.8
4040      */
4041     private static void throwIllegalAccessError() {
4042         throw new IllegalAccessError();
4043     }
4044 
4045     /**
4046      * Throws NoSuchMethodError; for use by the VM for redefinition support.
4047      * @since 13
4048      */
4049     private static void throwNoSuchMethodError() {
4050         throw new NoSuchMethodError();
4051     }
4052 
4053     /**
4054      * @return Returns true if the native byte ordering of this
4055      * platform is big-endian, false if it is little-endian.
4056      */
4057     public final boolean isBigEndian() { return BIG_ENDIAN; }
4058 
4059     /**
4060      * @return Returns true if this platform is capable of performing
4061      * accesses at addresses which are not aligned for the type of the
4062      * primitive type being accessed, false otherwise.
4063      */
4064     public final boolean unalignedAccess() { return UNALIGNED_ACCESS; }
4065 
4066     /**
4067      * Fetches a value at some byte offset into a given Java object.
4068      * More specifically, fetches a value within the given object
4069      * <code>o</code> at the given offset, or (if <code>o</code> is
4070      * null) from the memory address whose numerical value is the
4071      * given offset.  <p>
4072      *
4073      * The specification of this method is the same as {@link
4074      * #getLong(Object, long)} except that the offset does not need to
4075      * have been obtained from {@link #objectFieldOffset} on the
4076      * {@link java.lang.reflect.Field} of some Java field.  The value
4077      * in memory is raw data, and need not correspond to any Java
4078      * variable.  Unless <code>o</code> is null, the value accessed
4079      * must be entirely within the allocated object.  The endianness
4080      * of the value in memory is the endianness of the native platform.
4081      *
4082      * <p> The read will be atomic with respect to the largest power
4083      * of two that divides the GCD of the offset and the storage size.
4084      * For example, getLongUnaligned will make atomic reads of 2-, 4-,
4085      * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
4086      * respectively.  There are no other guarantees of atomicity.
4087      * <p>
4088      * 8-byte atomicity is only guaranteed on platforms on which
4089      * support atomic accesses to longs.
4090      *
4091      * @param o Java heap object in which the value resides, if any, else
4092      *        null
4093      * @param offset The offset in bytes from the start of the object
4094      * @return the value fetched from the indicated object
4095      * @throws RuntimeException No defined exceptions are thrown, not even
4096      *         {@link NullPointerException}
4097      * @since 9
4098      */
4099     @IntrinsicCandidate
4100     public final long getLongUnaligned(Object o, long offset) {
4101         if ((offset & 7) == 0) {
4102             return getLong(o, offset);
4103         } else if ((offset & 3) == 0) {
4104             return makeLong(getInt(o, offset),
4105                             getInt(o, offset + 4));
4106         } else if ((offset & 1) == 0) {
4107             return makeLong(getShort(o, offset),
4108                             getShort(o, offset + 2),
4109                             getShort(o, offset + 4),
4110                             getShort(o, offset + 6));
4111         } else {
4112             return makeLong(getByte(o, offset),
4113                             getByte(o, offset + 1),
4114                             getByte(o, offset + 2),
4115                             getByte(o, offset + 3),
4116                             getByte(o, offset + 4),
4117                             getByte(o, offset + 5),
4118                             getByte(o, offset + 6),
4119                             getByte(o, offset + 7));
4120         }
4121     }
4122     /**
4123      * As {@link #getLongUnaligned(Object, long)} but with an
4124      * additional argument which specifies the endianness of the value
4125      * as stored in memory.
4126      *
4127      * @param o Java heap object in which the variable resides
4128      * @param offset The offset in bytes from the start of the object
4129      * @param bigEndian The endianness of the value
4130      * @return the value fetched from the indicated object
4131      * @since 9
4132      */
4133     public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
4134         return convEndian(bigEndian, getLongUnaligned(o, offset));
4135     }
4136 
4137     /** @see #getLongUnaligned(Object, long) */
4138     @IntrinsicCandidate
4139     public final int getIntUnaligned(Object o, long offset) {
4140         if ((offset & 3) == 0) {
4141             return getInt(o, offset);
4142         } else if ((offset & 1) == 0) {
4143             return makeInt(getShort(o, offset),
4144                            getShort(o, offset + 2));
4145         } else {
4146             return makeInt(getByte(o, offset),
4147                            getByte(o, offset + 1),
4148                            getByte(o, offset + 2),
4149                            getByte(o, offset + 3));
4150         }
4151     }
4152     /** @see #getLongUnaligned(Object, long, boolean) */
4153     public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
4154         return convEndian(bigEndian, getIntUnaligned(o, offset));
4155     }
4156 
4157     /** @see #getLongUnaligned(Object, long) */
4158     @IntrinsicCandidate
4159     public final short getShortUnaligned(Object o, long offset) {
4160         if ((offset & 1) == 0) {
4161             return getShort(o, offset);
4162         } else {
4163             return makeShort(getByte(o, offset),
4164                              getByte(o, offset + 1));
4165         }
4166     }
4167     /** @see #getLongUnaligned(Object, long, boolean) */
4168     public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
4169         return convEndian(bigEndian, getShortUnaligned(o, offset));
4170     }
4171 
4172     /** @see #getLongUnaligned(Object, long) */
4173     @IntrinsicCandidate
4174     public final char getCharUnaligned(Object o, long offset) {
4175         if ((offset & 1) == 0) {
4176             return getChar(o, offset);
4177         } else {
4178             return (char)makeShort(getByte(o, offset),
4179                                    getByte(o, offset + 1));
4180         }
4181     }
4182 
4183     /** @see #getLongUnaligned(Object, long, boolean) */
4184     public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
4185         return convEndian(bigEndian, getCharUnaligned(o, offset));
4186     }
4187 
4188     /**
4189      * Stores a value at some byte offset into a given Java object.
4190      * <p>
4191      * The specification of this method is the same as {@link
4192      * #getLong(Object, long)} except that the offset does not need to
4193      * have been obtained from {@link #objectFieldOffset} on the
4194      * {@link java.lang.reflect.Field} of some Java field.  The value
4195      * in memory is raw data, and need not correspond to any Java
4196      * variable.  The endianness of the value in memory is the
4197      * endianness of the native platform.
4198      * <p>
4199      * The write will be atomic with respect to the largest power of
4200      * two that divides the GCD of the offset and the storage size.
4201      * For example, putLongUnaligned will make atomic writes of 2-, 4-,
4202      * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
4203      * respectively.  There are no other guarantees of atomicity.
4204      * <p>
4205      * 8-byte atomicity is only guaranteed on platforms on which
4206      * support atomic accesses to longs.
4207      *
4208      * @param o Java heap object in which the value resides, if any, else
4209      *        null
4210      * @param offset The offset in bytes from the start of the object
4211      * @param x the value to store
4212      * @throws RuntimeException No defined exceptions are thrown, not even
4213      *         {@link NullPointerException}
4214      * @since 9
4215      */
4216     @IntrinsicCandidate
4217     public final void putLongUnaligned(Object o, long offset, long x) {
4218         if ((offset & 7) == 0) {
4219             putLong(o, offset, x);
4220         } else if ((offset & 3) == 0) {
4221             putLongParts(o, offset,
4222                          (int)(x >> 0),
4223                          (int)(x >>> 32));
4224         } else if ((offset & 1) == 0) {
4225             putLongParts(o, offset,
4226                          (short)(x >>> 0),
4227                          (short)(x >>> 16),
4228                          (short)(x >>> 32),
4229                          (short)(x >>> 48));
4230         } else {
4231             putLongParts(o, offset,
4232                          (byte)(x >>> 0),
4233                          (byte)(x >>> 8),
4234                          (byte)(x >>> 16),
4235                          (byte)(x >>> 24),
4236                          (byte)(x >>> 32),
4237                          (byte)(x >>> 40),
4238                          (byte)(x >>> 48),
4239                          (byte)(x >>> 56));
4240         }
4241     }
4242 
4243     /**
4244      * As {@link #putLongUnaligned(Object, long, long)} but with an additional
4245      * argument which specifies the endianness of the value as stored in memory.
4246      * @param o Java heap object in which the value resides
4247      * @param offset The offset in bytes from the start of the object
4248      * @param x the value to store
4249      * @param bigEndian The endianness of the value
4250      * @throws RuntimeException No defined exceptions are thrown, not even
4251      *         {@link NullPointerException}
4252      * @since 9
4253      */
4254     public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
4255         putLongUnaligned(o, offset, convEndian(bigEndian, x));
4256     }
4257 
4258     /** @see #putLongUnaligned(Object, long, long) */
4259     @IntrinsicCandidate
4260     public final void putIntUnaligned(Object o, long offset, int x) {
4261         if ((offset & 3) == 0) {
4262             putInt(o, offset, x);
4263         } else if ((offset & 1) == 0) {
4264             putIntParts(o, offset,
4265                         (short)(x >> 0),
4266                         (short)(x >>> 16));
4267         } else {
4268             putIntParts(o, offset,
4269                         (byte)(x >>> 0),
4270                         (byte)(x >>> 8),
4271                         (byte)(x >>> 16),
4272                         (byte)(x >>> 24));
4273         }
4274     }
4275     /** @see #putLongUnaligned(Object, long, long, boolean) */
4276     public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
4277         putIntUnaligned(o, offset, convEndian(bigEndian, x));
4278     }
4279 
4280     /** @see #putLongUnaligned(Object, long, long) */
4281     @IntrinsicCandidate
4282     public final void putShortUnaligned(Object o, long offset, short x) {
4283         if ((offset & 1) == 0) {
4284             putShort(o, offset, x);
4285         } else {
4286             putShortParts(o, offset,
4287                           (byte)(x >>> 0),
4288                           (byte)(x >>> 8));
4289         }
4290     }
4291     /** @see #putLongUnaligned(Object, long, long, boolean) */
4292     public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
4293         putShortUnaligned(o, offset, convEndian(bigEndian, x));
4294     }
4295 
4296     /** @see #putLongUnaligned(Object, long, long) */
4297     @IntrinsicCandidate
4298     public final void putCharUnaligned(Object o, long offset, char x) {
4299         putShortUnaligned(o, offset, (short)x);
4300     }
4301     /** @see #putLongUnaligned(Object, long, long, boolean) */
4302     public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
4303         putCharUnaligned(o, offset, convEndian(bigEndian, x));
4304     }
4305 
4306     private static int pickPos(int top, int pos) { return BIG_ENDIAN ? top - pos : pos; }
4307 
4308     // These methods construct integers from bytes.  The byte ordering
4309     // is the native endianness of this platform.
4310     private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
4311         return ((toUnsignedLong(i0) << pickPos(56, 0))
4312               | (toUnsignedLong(i1) << pickPos(56, 8))
4313               | (toUnsignedLong(i2) << pickPos(56, 16))
4314               | (toUnsignedLong(i3) << pickPos(56, 24))
4315               | (toUnsignedLong(i4) << pickPos(56, 32))
4316               | (toUnsignedLong(i5) << pickPos(56, 40))
4317               | (toUnsignedLong(i6) << pickPos(56, 48))
4318               | (toUnsignedLong(i7) << pickPos(56, 56)));
4319     }
4320     private static long makeLong(short i0, short i1, short i2, short i3) {
4321         return ((toUnsignedLong(i0) << pickPos(48, 0))
4322               | (toUnsignedLong(i1) << pickPos(48, 16))
4323               | (toUnsignedLong(i2) << pickPos(48, 32))
4324               | (toUnsignedLong(i3) << pickPos(48, 48)));
4325     }
4326     private static long makeLong(int i0, int i1) {
4327         return (toUnsignedLong(i0) << pickPos(32, 0))
4328              | (toUnsignedLong(i1) << pickPos(32, 32));
4329     }
4330     private static int makeInt(short i0, short i1) {
4331         return (toUnsignedInt(i0) << pickPos(16, 0))
4332              | (toUnsignedInt(i1) << pickPos(16, 16));
4333     }
4334     private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
4335         return ((toUnsignedInt(i0) << pickPos(24, 0))
4336               | (toUnsignedInt(i1) << pickPos(24, 8))
4337               | (toUnsignedInt(i2) << pickPos(24, 16))
4338               | (toUnsignedInt(i3) << pickPos(24, 24)));
4339     }
4340     private static short makeShort(byte i0, byte i1) {
4341         return (short)((toUnsignedInt(i0) << pickPos(8, 0))
4342                      | (toUnsignedInt(i1) << pickPos(8, 8)));
4343     }
4344 
4345     private static byte  pick(byte  le, byte  be) { return BIG_ENDIAN ? be : le; }
4346     private static short pick(short le, short be) { return BIG_ENDIAN ? be : le; }
4347     private static int   pick(int   le, int   be) { return BIG_ENDIAN ? be : le; }
4348 
4349     // These methods write integers to memory from smaller parts
4350     // provided by their caller.  The ordering in which these parts
4351     // are written is the native endianness of this platform.
4352     private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
4353         putByte(o, offset + 0, pick(i0, i7));
4354         putByte(o, offset + 1, pick(i1, i6));
4355         putByte(o, offset + 2, pick(i2, i5));
4356         putByte(o, offset + 3, pick(i3, i4));
4357         putByte(o, offset + 4, pick(i4, i3));
4358         putByte(o, offset + 5, pick(i5, i2));
4359         putByte(o, offset + 6, pick(i6, i1));
4360         putByte(o, offset + 7, pick(i7, i0));
4361     }
4362     private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
4363         putShort(o, offset + 0, pick(i0, i3));
4364         putShort(o, offset + 2, pick(i1, i2));
4365         putShort(o, offset + 4, pick(i2, i1));
4366         putShort(o, offset + 6, pick(i3, i0));
4367     }
4368     private void putLongParts(Object o, long offset, int i0, int i1) {
4369         putInt(o, offset + 0, pick(i0, i1));
4370         putInt(o, offset + 4, pick(i1, i0));
4371     }
4372     private void putIntParts(Object o, long offset, short i0, short i1) {
4373         putShort(o, offset + 0, pick(i0, i1));
4374         putShort(o, offset + 2, pick(i1, i0));
4375     }
4376     private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
4377         putByte(o, offset + 0, pick(i0, i3));
4378         putByte(o, offset + 1, pick(i1, i2));
4379         putByte(o, offset + 2, pick(i2, i1));
4380         putByte(o, offset + 3, pick(i3, i0));
4381     }
4382     private void putShortParts(Object o, long offset, byte i0, byte i1) {
4383         putByte(o, offset + 0, pick(i0, i1));
4384         putByte(o, offset + 1, pick(i1, i0));
4385     }
4386 
4387     // Zero-extend an integer
4388     private static int toUnsignedInt(byte n)    { return n & 0xff; }
4389     private static int toUnsignedInt(short n)   { return n & 0xffff; }
4390     private static long toUnsignedLong(byte n)  { return n & 0xffl; }
4391     private static long toUnsignedLong(short n) { return n & 0xffffl; }
4392     private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
4393 
4394     // Maybe byte-reverse an integer
4395     private static char convEndian(boolean big, char n)   { return big == BIG_ENDIAN ? n : Character.reverseBytes(n); }
4396     private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n)    ; }
4397     private static int convEndian(boolean big, int n)     { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n)  ; }
4398     private static long convEndian(boolean big, long n)   { return big == BIG_ENDIAN ? n : Long.reverseBytes(n)     ; }
4399 
4400 
4401 
4402     private native long allocateMemory0(long bytes);
4403     private native long reallocateMemory0(long address, long bytes);
4404     private native void freeMemory0(long address);
4405     @IntrinsicCandidate
4406     private native void setMemory0(Object o, long offset, long bytes, byte value);
4407     @IntrinsicCandidate
4408     private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
4409     private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
4410     private native long objectFieldOffset0(Field f); // throws IAE
4411     private native long knownObjectFieldOffset0(Class<?> c, String name); // error code: -1 not found, -2 static
4412     private native long staticFieldOffset0(Field f); // throws IAE
4413     private native Object staticFieldBase0(Field f); // throws IAE
4414     private native boolean shouldBeInitialized0(Class<?> c);
4415     private native void ensureClassInitialized0(Class<?> c);
4416     private native void notifyStrictStaticAccess0(Class<?> c, long staticFieldOffset, boolean writing);
4417     private native int arrayBaseOffset0(Class<?> arrayClass); // public version returns long to promote correct arithmetic
4418     @IntrinsicCandidate
4419     private native int arrayInstanceBaseOffset0(Object[] array);
4420     private native int arrayIndexScale0(Class<?> arrayClass);
4421     @IntrinsicCandidate
4422     private native int arrayInstanceIndexScale0(Object[] array);
4423     private native long getObjectSize0(Object o);
4424     private native int getLoadAverage0(double[] loadavg, int nelems);
4425     @IntrinsicCandidate
4426     private native int[] getFieldMap0(Class <?> c);
4427 
4428 
4429     /**
4430      * Invokes the given direct byte buffer's cleaner, if any.
4431      *
4432      * @param directBuffer a direct byte buffer
4433      * @throws NullPointerException     if {@code directBuffer} is null
4434      * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
4435      *                                  or is a {@link java.nio.Buffer#slice slice}, or is a
4436      *                                  {@link java.nio.Buffer#duplicate duplicate}
4437      */
4438     public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
4439         if (!directBuffer.isDirect())
4440             throw new IllegalArgumentException("buffer is non-direct");
4441 
4442         DirectBuffer db = (DirectBuffer) directBuffer;
4443         if (db.attachment() != null)
4444             throw new IllegalArgumentException("duplicate or slice");
4445 
4446         Cleaner cleaner = db.cleaner();
4447         if (cleaner != null) {
4448             cleaner.clean();
4449         }
4450     }
4451 }