< prev index next >

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

Print this page
rev 54327 : 8221477: Inject os/cpu-specific constants into Unsafe from JVM
Summary: Initialize Unsafe os/cpu-specific constants using injection instead of native callouts
Reviewed-by: stuefe


   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.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


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 


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)));


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();




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


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 = UnsafeConstants.ADDRESS_SIZE;






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


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


3584             putShortParts(o, offset,
3585                           (byte)(x >>> 0),
3586                           (byte)(x >>> 8));
3587         }
3588     }
3589     /** @see #putLongUnaligned(Object, long, long, boolean) */
3590     public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
3591         putShortUnaligned(o, offset, convEndian(bigEndian, x));
3592     }
3593 
3594     /** @see #putLongUnaligned(Object, long, long) */
3595     @HotSpotIntrinsicCandidate
3596     public final void putCharUnaligned(Object o, long offset, char x) {
3597         putShortUnaligned(o, offset, (short)x);
3598     }
3599     /** @see #putLongUnaligned(Object, long, long, boolean) */
3600     public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
3601         putCharUnaligned(o, offset, convEndian(bigEndian, x));
3602     }
3603 

3604     // BE is true iff the native endianness of this platform is big.
3605     private static final boolean BE = UnsafeConstants.BIG_ENDIAN;



3606 
3607     private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
3608 
3609     // These methods construct integers from bytes.  The byte ordering
3610     // is the native endianness of this platform.
3611     private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
3612         return ((toUnsignedLong(i0) << pickPos(56, 0))
3613               | (toUnsignedLong(i1) << pickPos(56, 8))
3614               | (toUnsignedLong(i2) << pickPos(56, 16))
3615               | (toUnsignedLong(i3) << pickPos(56, 24))
3616               | (toUnsignedLong(i4) << pickPos(56, 32))
3617               | (toUnsignedLong(i5) << pickPos(56, 40))
3618               | (toUnsignedLong(i6) << pickPos(56, 48))
3619               | (toUnsignedLong(i7) << pickPos(56, 56)));
3620     }
3621     private static long makeLong(short i0, short i1, short i2, short i3) {
3622         return ((toUnsignedLong(i0) << pickPos(48, 0))
3623               | (toUnsignedLong(i1) << pickPos(48, 16))
3624               | (toUnsignedLong(i2) << pickPos(48, 32))
3625               | (toUnsignedLong(i3) << pickPos(48, 48)));


3698     private static int convEndian(boolean big, int n)     { return big == BE ? n : Integer.reverseBytes(n)  ; }
3699     private static long convEndian(boolean big, long n)   { return big == BE ? n : Long.reverseBytes(n)     ; }
3700 
3701 
3702 
3703     private native long allocateMemory0(long bytes);
3704     private native long reallocateMemory0(long address, long bytes);
3705     private native void freeMemory0(long address);
3706     private native void setMemory0(Object o, long offset, long bytes, byte value);
3707     @HotSpotIntrinsicCandidate
3708     private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
3709     private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
3710     private native long objectFieldOffset0(Field f);
3711     private native long objectFieldOffset1(Class<?> c, String name);
3712     private native long staticFieldOffset0(Field f);
3713     private native Object staticFieldBase0(Field f);
3714     private native boolean shouldBeInitialized0(Class<?> c);
3715     private native void ensureClassInitialized0(Class<?> c);
3716     private native int arrayBaseOffset0(Class<?> arrayClass);
3717     private native int arrayIndexScale0(Class<?> arrayClass);

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


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


< prev index next >