< prev index next >

src/java.base/share/classes/jdk/internal/misc/Unsafe.java

Print this page




  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.HotSpotIntrinsicCandidate;
  29 import jdk.internal.ref.Cleaner;
  30 import jdk.internal.vm.annotation.ForceInline;
  31 import sun.nio.ch.DirectBuffer;
  32 
  33 import java.lang.reflect.Field;
  34 import java.security.ProtectionDomain;
  35 
  36 import static jdk.internal.misc.UnsafeConstants.*;
  37 
  38 /**
  39  * A collection of methods for performing low-level, unsafe operations.
  40  * Although the class and all methods are public, use of this class is
  41  * limited because only trusted code can obtain instances of it.
  42  *
  43  * <em>Note:</em> It is the resposibility of the caller to make sure
  44  * arguments are checked before methods of this class are
  45  * called. While some rudimentary checks are performed on the input,
  46  * the checks are best effort and when performance is an overriding
  47  * priority, as when methods of this class are optimized by the
  48  * runtime compiler, some or all checks (if any) may be elided. Hence,
  49  * the caller must not rely on the checks and corresponding
  50  * exceptions!
  51  *
  52  * @author John R. Rose
  53  * @see #getUnsafe
  54  */
  55 
  56 public final class Unsafe {


1150 
1151     /** The value of {@code arrayIndexScale(double[].class)} */
1152     public static final int ARRAY_DOUBLE_INDEX_SCALE
1153             = theUnsafe.arrayIndexScale(double[].class);
1154 
1155     /** The value of {@code arrayIndexScale(Object[].class)} */
1156     public static final int ARRAY_OBJECT_INDEX_SCALE
1157             = theUnsafe.arrayIndexScale(Object[].class);
1158 
1159     /**
1160      * Reports the size in bytes of a native pointer, as stored via {@link
1161      * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
1162      * other primitive types (as stored in native memory blocks) is determined
1163      * fully by their information content.
1164      */
1165     public int addressSize() {
1166         return ADDRESS_SIZE;
1167     }
1168 
1169     /** The value of {@code addressSize()} */
1170     public static final int ADDRESS_SIZE = ADDRESS_SIZE0;
1171 
1172     /**
1173      * Reports the size in bytes of a native memory page (whatever that is).
1174      * This value will always be a power of two.
1175      */
1176     public int pageSize() { return PAGE_SIZE; }

1177 
1178     /// random trusted operations from JNI:
1179 
1180     /**
1181      * Tells the VM to define a class, without security checks.  By default, the
1182      * class loader and protection domain come from the caller's class.
1183      */
1184     public Class<?> defineClass(String name, byte[] b, int off, int len,
1185                                 ClassLoader loader,
1186                                 ProtectionDomain protectionDomain) {
1187         if (b == null) {
1188             throw new NullPointerException();
1189         }
1190         if (len < 0) {
1191             throw new ArrayIndexOutOfBoundsException();
1192         }
1193 
1194         return defineClass0(name, b, off, len, loader, protectionDomain);
1195     }
1196 


1400     @HotSpotIntrinsicCandidate
1401     public final boolean weakCompareAndSetIntRelease(Object o, long offset,
1402                                                      int expected,
1403                                                      int x) {
1404         return compareAndSetInt(o, offset, expected, x);
1405     }
1406 
1407     @HotSpotIntrinsicCandidate
1408     public final boolean weakCompareAndSetInt(Object o, long offset,
1409                                               int expected,
1410                                               int x) {
1411         return compareAndSetInt(o, offset, expected, x);
1412     }
1413 
1414     @HotSpotIntrinsicCandidate
1415     public final byte compareAndExchangeByte(Object o, long offset,
1416                                              byte expected,
1417                                              byte x) {
1418         long wordOffset = offset & ~3;
1419         int shift = (int) (offset & 3) << 3;
1420         if (BIG_ENDIAN) {
1421             shift = 24 - shift;
1422         }
1423         int mask           = 0xFF << shift;
1424         int maskedExpected = (expected & 0xFF) << shift;
1425         int maskedX        = (x & 0xFF) << shift;
1426         int fullWord;
1427         do {
1428             fullWord = getIntVolatile(o, wordOffset);
1429             if ((fullWord & mask) != maskedExpected)
1430                 return (byte) ((fullWord & mask) >> shift);
1431         } while (!weakCompareAndSetInt(o, wordOffset,
1432                                                 fullWord, (fullWord & ~mask) | maskedX));
1433         return expected;
1434     }
1435 
1436     @HotSpotIntrinsicCandidate
1437     public final boolean compareAndSetByte(Object o, long offset,
1438                                            byte expected,
1439                                            byte x) {
1440         return compareAndExchangeByte(o, offset, expected, x) == expected;


1474                                                     byte x) {
1475         return compareAndExchangeByte(o, offset, expected, x);
1476     }
1477 
1478     @HotSpotIntrinsicCandidate
1479     public final byte compareAndExchangeByteRelease(Object o, long offset,
1480                                                     byte expected,
1481                                                     byte x) {
1482         return compareAndExchangeByte(o, offset, expected, x);
1483     }
1484 
1485     @HotSpotIntrinsicCandidate
1486     public final short compareAndExchangeShort(Object o, long offset,
1487                                                short expected,
1488                                                short x) {
1489         if ((offset & 3) == 3) {
1490             throw new IllegalArgumentException("Update spans the word, not supported");
1491         }
1492         long wordOffset = offset & ~3;
1493         int shift = (int) (offset & 3) << 3;
1494         if (BIG_ENDIAN) {
1495             shift = 16 - shift;
1496         }
1497         int mask           = 0xFFFF << shift;
1498         int maskedExpected = (expected & 0xFFFF) << shift;
1499         int maskedX        = (x & 0xFFFF) << shift;
1500         int fullWord;
1501         do {
1502             fullWord = getIntVolatile(o, wordOffset);
1503             if ((fullWord & mask) != maskedExpected) {
1504                 return (short) ((fullWord & mask) >> shift);
1505             }
1506         } while (!weakCompareAndSetInt(o, wordOffset,
1507                                                 fullWord, (fullWord & ~mask) | maskedX));
1508         return expected;
1509     }
1510 
1511     @HotSpotIntrinsicCandidate
1512     public final boolean compareAndSetShort(Object o, long offset,
1513                                             short expected,
1514                                             short x) {


3337      * Throws IllegalAccessError; for use by the VM for access control
3338      * error support.
3339      * @since 1.8
3340      */
3341     private static void throwIllegalAccessError() {
3342         throw new IllegalAccessError();
3343     }
3344 
3345     /**
3346      * Throws NoSuchMethodError; for use by the VM for redefinition support.
3347      * @since 13
3348      */
3349     private static void throwNoSuchMethodError() {
3350         throw new NoSuchMethodError();
3351     }
3352 
3353     /**
3354      * @return Returns true if the native byte ordering of this
3355      * platform is big-endian, false if it is little-endian.
3356      */
3357     public final boolean isBigEndian() { return BIG_ENDIAN; }
3358 
3359     /**
3360      * @return Returns true if this platform is capable of performing
3361      * accesses at addresses which are not aligned for the type of the
3362      * primitive type being accessed, false otherwise.
3363      */
3364     public final boolean unalignedAccess() { return UNALIGNED_ACCESS; }
3365 
3366     /**
3367      * Fetches a value at some byte offset into a given Java object.
3368      * More specifically, fetches a value within the given object
3369      * <code>o</code> at the given offset, or (if <code>o</code> is
3370      * null) from the memory address whose numerical value is the
3371      * given offset.  <p>
3372      *
3373      * The specification of this method is the same as {@link
3374      * #getLong(Object, long)} except that the offset does not need to
3375      * have been obtained from {@link #objectFieldOffset} on the
3376      * {@link java.lang.reflect.Field} of some Java field.  The value
3377      * in memory is raw data, and need not correspond to any Java
3378      * variable.  Unless <code>o</code> is null, the value accessed
3379      * must be entirely within the allocated object.  The endianness
3380      * of the value in memory is the endianness of the native platform.
3381      *
3382      * <p> The read will be atomic with respect to the largest power
3383      * of two that divides the GCD of the offset and the storage size.
3384      * For example, getLongUnaligned will make atomic reads of 2-, 4-,


3586             putShortParts(o, offset,
3587                           (byte)(x >>> 0),
3588                           (byte)(x >>> 8));
3589         }
3590     }
3591     /** @see #putLongUnaligned(Object, long, long, boolean) */
3592     public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
3593         putShortUnaligned(o, offset, convEndian(bigEndian, x));
3594     }
3595 
3596     /** @see #putLongUnaligned(Object, long, long) */
3597     @HotSpotIntrinsicCandidate
3598     public final void putCharUnaligned(Object o, long offset, char x) {
3599         putShortUnaligned(o, offset, (short)x);
3600     }
3601     /** @see #putLongUnaligned(Object, long, long, boolean) */
3602     public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
3603         putCharUnaligned(o, offset, convEndian(bigEndian, x));
3604     }
3605 
3606     private static int pickPos(int top, int pos) { return BIG_ENDIAN ? top - pos : pos; }







3607 
3608     // These methods construct integers from bytes.  The byte ordering
3609     // is the native endianness of this platform.
3610     private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
3611         return ((toUnsignedLong(i0) << pickPos(56, 0))
3612               | (toUnsignedLong(i1) << pickPos(56, 8))
3613               | (toUnsignedLong(i2) << pickPos(56, 16))
3614               | (toUnsignedLong(i3) << pickPos(56, 24))
3615               | (toUnsignedLong(i4) << pickPos(56, 32))
3616               | (toUnsignedLong(i5) << pickPos(56, 40))
3617               | (toUnsignedLong(i6) << pickPos(56, 48))
3618               | (toUnsignedLong(i7) << pickPos(56, 56)));
3619     }
3620     private static long makeLong(short i0, short i1, short i2, short i3) {
3621         return ((toUnsignedLong(i0) << pickPos(48, 0))
3622               | (toUnsignedLong(i1) << pickPos(48, 16))
3623               | (toUnsignedLong(i2) << pickPos(48, 32))
3624               | (toUnsignedLong(i3) << pickPos(48, 48)));
3625     }
3626     private static long makeLong(int i0, int i1) {
3627         return (toUnsignedLong(i0) << pickPos(32, 0))
3628              | (toUnsignedLong(i1) << pickPos(32, 32));
3629     }
3630     private static int makeInt(short i0, short i1) {
3631         return (toUnsignedInt(i0) << pickPos(16, 0))
3632              | (toUnsignedInt(i1) << pickPos(16, 16));
3633     }
3634     private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
3635         return ((toUnsignedInt(i0) << pickPos(24, 0))
3636               | (toUnsignedInt(i1) << pickPos(24, 8))
3637               | (toUnsignedInt(i2) << pickPos(24, 16))
3638               | (toUnsignedInt(i3) << pickPos(24, 24)));
3639     }
3640     private static short makeShort(byte i0, byte i1) {
3641         return (short)((toUnsignedInt(i0) << pickPos(8, 0))
3642                      | (toUnsignedInt(i1) << pickPos(8, 8)));
3643     }
3644 
3645     private static byte  pick(byte  le, byte  be) { return BIG_ENDIAN ? be : le; }
3646     private static short pick(short le, short be) { return BIG_ENDIAN ? be : le; }
3647     private static int   pick(int   le, int   be) { return BIG_ENDIAN ? be : le; }
3648 
3649     // These methods write integers to memory from smaller parts
3650     // provided by their caller.  The ordering in which these parts
3651     // are written is the native endianness of this platform.
3652     private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
3653         putByte(o, offset + 0, pick(i0, i7));
3654         putByte(o, offset + 1, pick(i1, i6));
3655         putByte(o, offset + 2, pick(i2, i5));
3656         putByte(o, offset + 3, pick(i3, i4));
3657         putByte(o, offset + 4, pick(i4, i3));
3658         putByte(o, offset + 5, pick(i5, i2));
3659         putByte(o, offset + 6, pick(i6, i1));
3660         putByte(o, offset + 7, pick(i7, i0));
3661     }
3662     private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
3663         putShort(o, offset + 0, pick(i0, i3));
3664         putShort(o, offset + 2, pick(i1, i2));
3665         putShort(o, offset + 4, pick(i2, i1));
3666         putShort(o, offset + 6, pick(i3, i0));
3667     }


3675     }
3676     private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
3677         putByte(o, offset + 0, pick(i0, i3));
3678         putByte(o, offset + 1, pick(i1, i2));
3679         putByte(o, offset + 2, pick(i2, i1));
3680         putByte(o, offset + 3, pick(i3, i0));
3681     }
3682     private void putShortParts(Object o, long offset, byte i0, byte i1) {
3683         putByte(o, offset + 0, pick(i0, i1));
3684         putByte(o, offset + 1, pick(i1, i0));
3685     }
3686 
3687     // Zero-extend an integer
3688     private static int toUnsignedInt(byte n)    { return n & 0xff; }
3689     private static int toUnsignedInt(short n)   { return n & 0xffff; }
3690     private static long toUnsignedLong(byte n)  { return n & 0xffl; }
3691     private static long toUnsignedLong(short n) { return n & 0xffffl; }
3692     private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
3693 
3694     // Maybe byte-reverse an integer
3695     private static char convEndian(boolean big, char n)   { return big == BIG_ENDIAN ? n : Character.reverseBytes(n); }
3696     private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n)    ; }
3697     private static int convEndian(boolean big, int n)     { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n)  ; }
3698     private static long convEndian(boolean big, long n)   { return big == BIG_ENDIAN ? n : Long.reverseBytes(n)     ; }
3699 
3700 
3701 
3702     private native long allocateMemory0(long bytes);
3703     private native long reallocateMemory0(long address, long bytes);
3704     private native void freeMemory0(long address);
3705     private native void setMemory0(Object o, long offset, long bytes, byte value);
3706     @HotSpotIntrinsicCandidate
3707     private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
3708     private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
3709     private native long objectFieldOffset0(Field f);
3710     private native long objectFieldOffset1(Class<?> c, String name);
3711     private native long staticFieldOffset0(Field f);
3712     private native Object staticFieldBase0(Field f);
3713     private native boolean shouldBeInitialized0(Class<?> c);
3714     private native void ensureClassInitialized0(Class<?> c);
3715     private native int arrayBaseOffset0(Class<?> arrayClass);
3716     private native int arrayIndexScale0(Class<?> arrayClass);

3717     private native Class<?> defineAnonymousClass0(Class<?> hostClass, byte[] data, Object[] cpPatches);
3718     private native int getLoadAverage0(double[] loadavg, int nelems);


3719 
3720 
3721     /**
3722      * Invokes the given direct byte buffer's cleaner, if any.
3723      *
3724      * @param directBuffer a direct byte buffer
3725      * @throws NullPointerException     if {@code directBuffer} is null
3726      * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
3727      *                                  or is a {@link java.nio.Buffer#slice slice}, or is a
3728      *                                  {@link java.nio.Buffer#duplicate duplicate}
3729      */
3730     public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
3731         if (!directBuffer.isDirect())
3732             throw new IllegalArgumentException("buffer is non-direct");
3733 
3734         DirectBuffer db = (DirectBuffer) directBuffer;
3735         if (db.attachment() != null)
3736             throw new IllegalArgumentException("duplicate or slice");
3737 
3738         Cleaner cleaner = db.cleaner();




  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.HotSpotIntrinsicCandidate;
  29 import jdk.internal.ref.Cleaner;
  30 import jdk.internal.vm.annotation.ForceInline;
  31 import sun.nio.ch.DirectBuffer;
  32 
  33 import java.lang.reflect.Field;
  34 import java.security.ProtectionDomain;
  35 

  36 
  37 /**
  38  * A collection of methods for performing low-level, unsafe operations.
  39  * Although the class and all methods are public, use of this class is
  40  * limited because only trusted code can obtain instances of it.
  41  *
  42  * <em>Note:</em> It is the resposibility of the caller to make sure
  43  * arguments are checked before methods of this class are
  44  * called. While some rudimentary checks are performed on the input,
  45  * the checks are best effort and when performance is an overriding
  46  * priority, as when methods of this class are optimized by the
  47  * runtime compiler, some or all checks (if any) may be elided. Hence,
  48  * the caller must not rely on the checks and corresponding
  49  * exceptions!
  50  *
  51  * @author John R. Rose
  52  * @see #getUnsafe
  53  */
  54 
  55 public final class Unsafe {


1149 
1150     /** The value of {@code arrayIndexScale(double[].class)} */
1151     public static final int ARRAY_DOUBLE_INDEX_SCALE
1152             = theUnsafe.arrayIndexScale(double[].class);
1153 
1154     /** The value of {@code arrayIndexScale(Object[].class)} */
1155     public static final int ARRAY_OBJECT_INDEX_SCALE
1156             = theUnsafe.arrayIndexScale(Object[].class);
1157 
1158     /**
1159      * Reports the size in bytes of a native pointer, as stored via {@link
1160      * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
1161      * other primitive types (as stored in native memory blocks) is determined
1162      * fully by their information content.
1163      */
1164     public int addressSize() {
1165         return ADDRESS_SIZE;
1166     }
1167 
1168     /** The value of {@code addressSize()} */
1169     public static final int ADDRESS_SIZE = theUnsafe.addressSize0();
1170 
1171     /**
1172      * Reports the size in bytes of a native memory page (whatever that is).
1173      * This value will always be a power of two.
1174      */
1175     public native int pageSize();
1176 
1177 
1178     /// random trusted operations from JNI:
1179 
1180     /**
1181      * Tells the VM to define a class, without security checks.  By default, the
1182      * class loader and protection domain come from the caller's class.
1183      */
1184     public Class<?> defineClass(String name, byte[] b, int off, int len,
1185                                 ClassLoader loader,
1186                                 ProtectionDomain protectionDomain) {
1187         if (b == null) {
1188             throw new NullPointerException();
1189         }
1190         if (len < 0) {
1191             throw new ArrayIndexOutOfBoundsException();
1192         }
1193 
1194         return defineClass0(name, b, off, len, loader, protectionDomain);
1195     }
1196 


1400     @HotSpotIntrinsicCandidate
1401     public final boolean weakCompareAndSetIntRelease(Object o, long offset,
1402                                                      int expected,
1403                                                      int x) {
1404         return compareAndSetInt(o, offset, expected, x);
1405     }
1406 
1407     @HotSpotIntrinsicCandidate
1408     public final boolean weakCompareAndSetInt(Object o, long offset,
1409                                               int expected,
1410                                               int x) {
1411         return compareAndSetInt(o, offset, expected, x);
1412     }
1413 
1414     @HotSpotIntrinsicCandidate
1415     public final byte compareAndExchangeByte(Object o, long offset,
1416                                              byte expected,
1417                                              byte x) {
1418         long wordOffset = offset & ~3;
1419         int shift = (int) (offset & 3) << 3;
1420         if (BE) {
1421             shift = 24 - shift;
1422         }
1423         int mask           = 0xFF << shift;
1424         int maskedExpected = (expected & 0xFF) << shift;
1425         int maskedX        = (x & 0xFF) << shift;
1426         int fullWord;
1427         do {
1428             fullWord = getIntVolatile(o, wordOffset);
1429             if ((fullWord & mask) != maskedExpected)
1430                 return (byte) ((fullWord & mask) >> shift);
1431         } while (!weakCompareAndSetInt(o, wordOffset,
1432                                                 fullWord, (fullWord & ~mask) | maskedX));
1433         return expected;
1434     }
1435 
1436     @HotSpotIntrinsicCandidate
1437     public final boolean compareAndSetByte(Object o, long offset,
1438                                            byte expected,
1439                                            byte x) {
1440         return compareAndExchangeByte(o, offset, expected, x) == expected;


1474                                                     byte x) {
1475         return compareAndExchangeByte(o, offset, expected, x);
1476     }
1477 
1478     @HotSpotIntrinsicCandidate
1479     public final byte compareAndExchangeByteRelease(Object o, long offset,
1480                                                     byte expected,
1481                                                     byte x) {
1482         return compareAndExchangeByte(o, offset, expected, x);
1483     }
1484 
1485     @HotSpotIntrinsicCandidate
1486     public final short compareAndExchangeShort(Object o, long offset,
1487                                                short expected,
1488                                                short x) {
1489         if ((offset & 3) == 3) {
1490             throw new IllegalArgumentException("Update spans the word, not supported");
1491         }
1492         long wordOffset = offset & ~3;
1493         int shift = (int) (offset & 3) << 3;
1494         if (BE) {
1495             shift = 16 - shift;
1496         }
1497         int mask           = 0xFFFF << shift;
1498         int maskedExpected = (expected & 0xFFFF) << shift;
1499         int maskedX        = (x & 0xFFFF) << shift;
1500         int fullWord;
1501         do {
1502             fullWord = getIntVolatile(o, wordOffset);
1503             if ((fullWord & mask) != maskedExpected) {
1504                 return (short) ((fullWord & mask) >> shift);
1505             }
1506         } while (!weakCompareAndSetInt(o, wordOffset,
1507                                                 fullWord, (fullWord & ~mask) | maskedX));
1508         return expected;
1509     }
1510 
1511     @HotSpotIntrinsicCandidate
1512     public final boolean compareAndSetShort(Object o, long offset,
1513                                             short expected,
1514                                             short x) {


3337      * Throws IllegalAccessError; for use by the VM for access control
3338      * error support.
3339      * @since 1.8
3340      */
3341     private static void throwIllegalAccessError() {
3342         throw new IllegalAccessError();
3343     }
3344 
3345     /**
3346      * Throws NoSuchMethodError; for use by the VM for redefinition support.
3347      * @since 13
3348      */
3349     private static void throwNoSuchMethodError() {
3350         throw new NoSuchMethodError();
3351     }
3352 
3353     /**
3354      * @return Returns true if the native byte ordering of this
3355      * platform is big-endian, false if it is little-endian.
3356      */
3357     public final boolean isBigEndian() { return BE; }
3358 
3359     /**
3360      * @return Returns true if this platform is capable of performing
3361      * accesses at addresses which are not aligned for the type of the
3362      * primitive type being accessed, false otherwise.
3363      */
3364     public final boolean unalignedAccess() { return unalignedAccess; }
3365 
3366     /**
3367      * Fetches a value at some byte offset into a given Java object.
3368      * More specifically, fetches a value within the given object
3369      * <code>o</code> at the given offset, or (if <code>o</code> is
3370      * null) from the memory address whose numerical value is the
3371      * given offset.  <p>
3372      *
3373      * The specification of this method is the same as {@link
3374      * #getLong(Object, long)} except that the offset does not need to
3375      * have been obtained from {@link #objectFieldOffset} on the
3376      * {@link java.lang.reflect.Field} of some Java field.  The value
3377      * in memory is raw data, and need not correspond to any Java
3378      * variable.  Unless <code>o</code> is null, the value accessed
3379      * must be entirely within the allocated object.  The endianness
3380      * of the value in memory is the endianness of the native platform.
3381      *
3382      * <p> The read will be atomic with respect to the largest power
3383      * of two that divides the GCD of the offset and the storage size.
3384      * For example, getLongUnaligned will make atomic reads of 2-, 4-,


3586             putShortParts(o, offset,
3587                           (byte)(x >>> 0),
3588                           (byte)(x >>> 8));
3589         }
3590     }
3591     /** @see #putLongUnaligned(Object, long, long, boolean) */
3592     public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
3593         putShortUnaligned(o, offset, convEndian(bigEndian, x));
3594     }
3595 
3596     /** @see #putLongUnaligned(Object, long, long) */
3597     @HotSpotIntrinsicCandidate
3598     public final void putCharUnaligned(Object o, long offset, char x) {
3599         putShortUnaligned(o, offset, (short)x);
3600     }
3601     /** @see #putLongUnaligned(Object, long, long, boolean) */
3602     public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
3603         putCharUnaligned(o, offset, convEndian(bigEndian, x));
3604     }
3605 
3606     // JVM interface methods
3607     // BE is true iff the native endianness of this platform is big.
3608     private static final boolean BE = theUnsafe.isBigEndian0();
3609 
3610     // unalignedAccess is true iff this platform can perform unaligned accesses.
3611     private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
3612 
3613     private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
3614 
3615     // These methods construct integers from bytes.  The byte ordering
3616     // is the native endianness of this platform.
3617     private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
3618         return ((toUnsignedLong(i0) << pickPos(56, 0))
3619               | (toUnsignedLong(i1) << pickPos(56, 8))
3620               | (toUnsignedLong(i2) << pickPos(56, 16))
3621               | (toUnsignedLong(i3) << pickPos(56, 24))
3622               | (toUnsignedLong(i4) << pickPos(56, 32))
3623               | (toUnsignedLong(i5) << pickPos(56, 40))
3624               | (toUnsignedLong(i6) << pickPos(56, 48))
3625               | (toUnsignedLong(i7) << pickPos(56, 56)));
3626     }
3627     private static long makeLong(short i0, short i1, short i2, short i3) {
3628         return ((toUnsignedLong(i0) << pickPos(48, 0))
3629               | (toUnsignedLong(i1) << pickPos(48, 16))
3630               | (toUnsignedLong(i2) << pickPos(48, 32))
3631               | (toUnsignedLong(i3) << pickPos(48, 48)));
3632     }
3633     private static long makeLong(int i0, int i1) {
3634         return (toUnsignedLong(i0) << pickPos(32, 0))
3635              | (toUnsignedLong(i1) << pickPos(32, 32));
3636     }
3637     private static int makeInt(short i0, short i1) {
3638         return (toUnsignedInt(i0) << pickPos(16, 0))
3639              | (toUnsignedInt(i1) << pickPos(16, 16));
3640     }
3641     private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
3642         return ((toUnsignedInt(i0) << pickPos(24, 0))
3643               | (toUnsignedInt(i1) << pickPos(24, 8))
3644               | (toUnsignedInt(i2) << pickPos(24, 16))
3645               | (toUnsignedInt(i3) << pickPos(24, 24)));
3646     }
3647     private static short makeShort(byte i0, byte i1) {
3648         return (short)((toUnsignedInt(i0) << pickPos(8, 0))
3649                      | (toUnsignedInt(i1) << pickPos(8, 8)));
3650     }
3651 
3652     private static byte  pick(byte  le, byte  be) { return BE ? be : le; }
3653     private static short pick(short le, short be) { return BE ? be : le; }
3654     private static int   pick(int   le, int   be) { return BE ? be : le; }
3655 
3656     // These methods write integers to memory from smaller parts
3657     // provided by their caller.  The ordering in which these parts
3658     // are written is the native endianness of this platform.
3659     private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
3660         putByte(o, offset + 0, pick(i0, i7));
3661         putByte(o, offset + 1, pick(i1, i6));
3662         putByte(o, offset + 2, pick(i2, i5));
3663         putByte(o, offset + 3, pick(i3, i4));
3664         putByte(o, offset + 4, pick(i4, i3));
3665         putByte(o, offset + 5, pick(i5, i2));
3666         putByte(o, offset + 6, pick(i6, i1));
3667         putByte(o, offset + 7, pick(i7, i0));
3668     }
3669     private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
3670         putShort(o, offset + 0, pick(i0, i3));
3671         putShort(o, offset + 2, pick(i1, i2));
3672         putShort(o, offset + 4, pick(i2, i1));
3673         putShort(o, offset + 6, pick(i3, i0));
3674     }


3682     }
3683     private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
3684         putByte(o, offset + 0, pick(i0, i3));
3685         putByte(o, offset + 1, pick(i1, i2));
3686         putByte(o, offset + 2, pick(i2, i1));
3687         putByte(o, offset + 3, pick(i3, i0));
3688     }
3689     private void putShortParts(Object o, long offset, byte i0, byte i1) {
3690         putByte(o, offset + 0, pick(i0, i1));
3691         putByte(o, offset + 1, pick(i1, i0));
3692     }
3693 
3694     // Zero-extend an integer
3695     private static int toUnsignedInt(byte n)    { return n & 0xff; }
3696     private static int toUnsignedInt(short n)   { return n & 0xffff; }
3697     private static long toUnsignedLong(byte n)  { return n & 0xffl; }
3698     private static long toUnsignedLong(short n) { return n & 0xffffl; }
3699     private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
3700 
3701     // Maybe byte-reverse an integer
3702     private static char convEndian(boolean big, char n)   { return big == BE ? n : Character.reverseBytes(n); }
3703     private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n)    ; }
3704     private static int convEndian(boolean big, int n)     { return big == BE ? n : Integer.reverseBytes(n)  ; }
3705     private static long convEndian(boolean big, long n)   { return big == BE ? n : Long.reverseBytes(n)     ; }
3706 
3707 
3708 
3709     private native long allocateMemory0(long bytes);
3710     private native long reallocateMemory0(long address, long bytes);
3711     private native void freeMemory0(long address);
3712     private native void setMemory0(Object o, long offset, long bytes, byte value);
3713     @HotSpotIntrinsicCandidate
3714     private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
3715     private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
3716     private native long objectFieldOffset0(Field f);
3717     private native long objectFieldOffset1(Class<?> c, String name);
3718     private native long staticFieldOffset0(Field f);
3719     private native Object staticFieldBase0(Field f);
3720     private native boolean shouldBeInitialized0(Class<?> c);
3721     private native void ensureClassInitialized0(Class<?> c);
3722     private native int arrayBaseOffset0(Class<?> arrayClass);
3723     private native int arrayIndexScale0(Class<?> arrayClass);
3724     private native int addressSize0();
3725     private native Class<?> defineAnonymousClass0(Class<?> hostClass, byte[] data, Object[] cpPatches);
3726     private native int getLoadAverage0(double[] loadavg, int nelems);
3727     private native boolean unalignedAccess0();
3728     private native boolean isBigEndian0();
3729 
3730 
3731     /**
3732      * Invokes the given direct byte buffer's cleaner, if any.
3733      *
3734      * @param directBuffer a direct byte buffer
3735      * @throws NullPointerException     if {@code directBuffer} is null
3736      * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
3737      *                                  or is a {@link java.nio.Buffer#slice slice}, or is a
3738      *                                  {@link java.nio.Buffer#duplicate duplicate}
3739      */
3740     public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
3741         if (!directBuffer.isDirect())
3742             throw new IllegalArgumentException("buffer is non-direct");
3743 
3744         DirectBuffer db = (DirectBuffer) directBuffer;
3745         if (db.attachment() != null)
3746             throw new IllegalArgumentException("duplicate or slice");
3747 
3748         Cleaner cleaner = db.cleaner();


< prev index next >