src/java.base/share/classes/jdk/internal/misc/Unsafe.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Cdiff src/java.base/share/classes/jdk/internal/misc/Unsafe.java

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

Print this page
rev 13795 : [mq]: unsafejavachecks1

*** 38,47 **** --- 38,56 ---- /** * A collection of methods for performing low-level, unsafe operations. * Although the class and all methods are public, use of this class is * limited because only trusted code can obtain instances of it. * + * <em>Note:</em> It is the resposibility of the caller to make sure + * arguments are checked before methods of this class are + * called. While some rudimentary checks are performed on the input, + * the checks are best effort and when performance is an overriding + * priority, as when methods of this class are optimized by the + * runtime compiler, some or all checks (if any) may be elided. Hence, + * the caller must not rely on the checks and corresponding + * exceptions! + * * @author John R. Rose * @see #getUnsafe */ public final class Unsafe {
*** 356,383 **** * @see #getAddress(long) */ @HotSpotIntrinsicCandidate public native void putAddress(long address, long x); /// wrappers for malloc, realloc, free: /** * Allocates a new block of native memory, of the given size in bytes. The * contents of the memory are uninitialized; they will generally be * garbage. The resulting native pointer will never be zero, and will be * aligned for all value types. Dispose of this memory by calling {@link * #freeMemory}, or resize it with {@link #reallocateMemory}. * ! * @throws IllegalArgumentException if the size is negative or too large * for the native size_t type * * @throws OutOfMemoryError if the allocation is refused by the system * * @see #getByte(long) * @see #putByte(long, byte) */ ! public native long allocateMemory(long bytes); /** * Resizes a new block of native memory, to the given size in bytes. The * contents of the new block past the size of the old block are * uninitialized; they will generally be garbage. The resulting native --- 365,589 ---- * @see #getAddress(long) */ @HotSpotIntrinsicCandidate public native void putAddress(long address, long x); + + + /// helper methods for validating various types of objects/values + + /** + * Create an exception reflecting that some of the input was invalid + * + * <em>Note:</em> It is the resposibility of the caller to make + * sure arguments are checked before the methods are called. While + * some rudimentary checks are performed on the input, the checks + * are best effort and when performance is an overriding priority, + * as when methods of this class are optimized by the runtime + * compiler, some or all checks (if any) may be elided. Hence, the + * caller must not rely on the checks and corresponding + * exceptions! + * + * @return an exception object + */ + private RuntimeException invalidInput() { + return new IllegalArgumentException(); + } + + /** + * Check if a value is 32-bit clean (32 MSB are all zero) + * + * @param value the 64-bit value to check + * + * @return true if the value is 32-bit clean + */ + private boolean is32BitClean(long value) { + return value >>> 32 == 0; + } + + /** + * Check the validity of a size (the equivalent of a size_t) + * + * @throws RuntimeException if the size is invalid + * (<em>Note:</em> after optimization, invalid inputs may + * go undetected, which will lead to unpredictable + * behavior) + */ + private void checkSize(long size) { + if (ADDRESS_SIZE == 4) { + // Note: this will also check for negative sizes + if (!is32BitClean(size)) { + throw invalidInput(); + } + } else if (size < 0) { + throw invalidInput(); + } + } + + /** + * Check the validity of a native address (the equivalent of void*) + * + * @throws RuntimeException if the address is invalid + * (<em>Note:</em> after optimization, invalid inputs may + * go undetected, which will lead to unpredictable + * behavior) + */ + private void checkNativeAddress(long address) { + if (ADDRESS_SIZE == 4) { + // Accept both zero and sign extended pointers. A valid + // pointer will, after the +1 below, either have produced + // the value 0x0 or 0x1. Masking off the low bit allows + // for testing against 0. + if ((((address >> 32) + 1) & ~1) != 0) { + throw invalidInput(); + } + } + } + + /** + * Check the validity of an offset, relative to a base object + * + * @param o the base object + * @param offset the offset to check + * + * @throws RuntimeException if the size is invalid + * (<em>Note:</em> after optimization, invalid inputs may + * go undetected, which will lead to unpredictable + * behavior) + */ + private void checkOffset(Object o, long offset) { + if (ADDRESS_SIZE == 4) { + // Note: this will also check for negative offsets + if (!is32BitClean(offset)) { + throw invalidInput(); + } + } else if (offset < 0) { + throw invalidInput(); + } + } + + /** + * Check the validity of a double-register pointer + * + * Note: This code deliberately does *not* check for NPE for (at + * least) three reasons: + * + * 1) NPE is not just NULL/0 - there is a range of values all + * resulting in an NPE, which is not trivial to check for + * + * 2) It is the responsibility of the callers of Unsafe methods + * to verify the input, so throwing an exception here is not really + * useful - passing in a NULL pointer is a critical error and the + * must not expect an exception to be thrown anyway. + * + * 3) the actual operations will detect NULL pointers anyway by + * means of traps and signals (like SIGSEGV). + * + * @param o Java heap object, or null + * @param offset indication of where the variable resides in a Java heap + * object, if any, else a memory address locating the variable + * statically + * + * @throws RuntimeException if the pointer is invalid + * (<em>Note:</em> after optimization, invalid inputs may + * go undetected, which will lead to unpredictable + * behavior) + */ + private void checkPointer(Object o, long offset) { + if (o == null) { + checkNativeAddress(offset); + } else { + checkOffset(o, offset); + } + } + + /** + * Check if a type is a primitive array type + * + * @param c the type to check + * + * @return true if the type is a primitive array type + */ + private void checkPrimitiveArray(Class<?> c) { + Class<?> componentType = c.getComponentType(); + if (componentType == null || !componentType.isPrimitive()) { + throw invalidInput(); + } + } + + /** + * Check that a pointer is a valid primitive array type pointer + * + * Note: pointers off-heap are considered to be primitive arrays + * + * @throws RuntimeException if the pointer is invalid + * (<em>Note:</em> after optimization, invalid inputs may + * go undetected, which will lead to unpredictable + * behavior) + */ + private void checkPrimitivePointer(Object o, long offset) { + checkPointer(o, offset); + + if (o != null) { + // If on heap, it it must be a primitive array + checkPrimitiveArray(o.getClass()); + } + } + + /// wrappers for malloc, realloc, free: /** * Allocates a new block of native memory, of the given size in bytes. The * contents of the memory are uninitialized; they will generally be * garbage. The resulting native pointer will never be zero, and will be * aligned for all value types. Dispose of this memory by calling {@link * #freeMemory}, or resize it with {@link #reallocateMemory}. * ! * <em>Note:</em> It is the resposibility of the caller to make ! * sure arguments are checked before the methods are called. While ! * some rudimentary checks are performed on the input, the checks ! * are best effort and when performance is an overriding priority, ! * as when methods of this class are optimized by the runtime ! * compiler, some or all checks (if any) may be elided. Hence, the ! * caller must not rely on the checks and corresponding ! * exceptions! ! * ! * @throws RuntimeException if the size is negative or too large * for the native size_t type * * @throws OutOfMemoryError if the allocation is refused by the system * * @see #getByte(long) * @see #putByte(long, byte) */ ! public long allocateMemory(long bytes) { ! allocateMemoryChecks(bytes); ! ! if (bytes == 0) { ! return 0; ! } ! ! long p = allocateMemory0(bytes); ! if (p == 0) { ! throw new OutOfMemoryError(); ! } ! ! return p; ! } ! ! /** ! * Validate the arguments to allocateMemory ! * ! * @throws RuntimeException if the arguments are invalid ! * (<em>Note:</em> after optimization, invalid inputs may ! * go undetected, which will lead to unpredictable ! * behavior) ! */ ! private void allocateMemoryChecks(long bytes) { ! checkSize(bytes); ! } /** * Resizes a new block of native memory, to the given size in bytes. The * contents of the new block past the size of the old block are * uninitialized; they will generally be garbage. The resulting native
*** 385,402 **** * resulting native pointer will be aligned for all value types. Dispose * of this memory by calling {@link #freeMemory}, or resize it with {@link * #reallocateMemory}. The address passed to this method may be null, in * which case an allocation will be performed. * ! * @throws IllegalArgumentException if the size is negative or too large * for the native size_t type * * @throws OutOfMemoryError if the allocation is refused by the system * * @see #allocateMemory */ ! public native long reallocateMemory(long address, long bytes); /** * Sets all bytes in a given block of memory to a fixed value * (usually zero). * --- 591,644 ---- * resulting native pointer will be aligned for all value types. Dispose * of this memory by calling {@link #freeMemory}, or resize it with {@link * #reallocateMemory}. The address passed to this method may be null, in * which case an allocation will be performed. * ! * <em>Note:</em> It is the resposibility of the caller to make ! * sure arguments are checked before the methods are called. While ! * some rudimentary checks are performed on the input, the checks ! * are best effort and when performance is an overriding priority, ! * as when methods of this class are optimized by the runtime ! * compiler, some or all checks (if any) may be elided. Hence, the ! * caller must not rely on the checks and corresponding ! * exceptions! ! * ! * @throws RuntimeException if the size is negative or too large * for the native size_t type * * @throws OutOfMemoryError if the allocation is refused by the system * * @see #allocateMemory */ ! public long reallocateMemory(long address, long bytes) { ! reallocateMemoryChecks(address, bytes); ! ! if (bytes == 0) { ! freeMemory(address); ! return 0; ! } ! ! long p = (address == 0) ? allocateMemory0(bytes) : reallocateMemory0(address, bytes); ! if (p == 0) { ! throw new OutOfMemoryError(); ! } ! ! return p; ! } ! ! /** ! * Validate the arguments to reallocateMemory ! * ! * @throws RuntimeException if the arguments are invalid ! * (<em>Note:</em> after optimization, invalid inputs may ! * go undetected, which will lead to unpredictable ! * behavior) ! */ ! private void reallocateMemoryChecks(long address, long bytes) { ! checkPointer(null, address); ! checkSize(bytes); ! } /** * Sets all bytes in a given block of memory to a fixed value * (usually zero). *
*** 409,421 **** * by the address and length parameters. If the effective address and * length are all even modulo 8, the stores take place in 'long' units. * If the effective address and length are (resp.) even modulo 4 or 2, * the stores take place in units of 'int' or 'short'. * * @since 1.7 */ ! public native void setMemory(Object o, long offset, long bytes, byte value); /** * Sets all bytes in a given block of memory to a fixed value * (usually zero). This provides a <em>single-register</em> addressing mode, * as discussed in {@link #getInt(Object,long)}. --- 651,682 ---- * by the address and length parameters. If the effective address and * length are all even modulo 8, the stores take place in 'long' units. * If the effective address and length are (resp.) even modulo 4 or 2, * the stores take place in units of 'int' or 'short'. * + * <em>Note:</em> It is the resposibility of the caller to make + * sure arguments are checked before the methods are called. While + * some rudimentary checks are performed on the input, the checks + * are best effort and when performance is an overriding priority, + * as when methods of this class are optimized by the runtime + * compiler, some or all checks (if any) may be elided. Hence, the + * caller must not rely on the checks and corresponding + * exceptions! + * + * @throws RuntimeException if any of the arguments is invalid + * * @since 1.7 */ ! public void setMemory(Object o, long offset, long bytes, byte value) { ! setMemoryChecks(o, offset, bytes, value); ! ! if (bytes == 0) { ! return; ! } ! ! setMemory0(o, offset, bytes, value); ! } /** * Sets all bytes in a given block of memory to a fixed value * (usually zero). This provides a <em>single-register</em> addressing mode, * as discussed in {@link #getInt(Object,long)}.
*** 425,434 **** --- 686,708 ---- public void setMemory(long address, long bytes, byte value) { setMemory(null, address, bytes, value); } /** + * Validate the arguments to setMemory + * + * @throws RuntimeException if the arguments are invalid + * (<em>Note:</em> after optimization, invalid inputs may + * go undetected, which will lead to unpredictable + * behavior) + */ + private void setMemoryChecks(Object o, long offset, long bytes, byte value) { + checkPrimitivePointer(o, offset); + checkSize(bytes); + } + + /** * Sets all bytes in a given block of memory to a copy of another * block. * * <p>This method determines each block's base address by means of two parameters, * and so it provides (in effect) a <em>double-register</em> addressing mode,
*** 439,454 **** * by the address and length parameters. If the effective addresses and * length are all even modulo 8, the transfer takes place in 'long' units. * If the effective addresses and length are (resp.) even modulo 4 or 2, * the transfer takes place in units of 'int' or 'short'. * * @since 1.7 */ ! @HotSpotIntrinsicCandidate ! public native void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, ! long bytes); /** * Sets all bytes in a given block of memory to a copy of another * block. This provides a <em>single-register</em> addressing mode, * as discussed in {@link #getInt(Object,long)}. * --- 713,747 ---- * by the address and length parameters. If the effective addresses and * length are all even modulo 8, the transfer takes place in 'long' units. * If the effective addresses and length are (resp.) even modulo 4 or 2, * the transfer takes place in units of 'int' or 'short'. * + * <em>Note:</em> It is the resposibility of the caller to make + * sure arguments are checked before the methods are called. While + * some rudimentary checks are performed on the input, the checks + * are best effort and when performance is an overriding priority, + * as when methods of this class are optimized by the runtime + * compiler, some or all checks (if any) may be elided. Hence, the + * caller must not rely on the checks and corresponding + * exceptions! + * + * @throws RuntimeException if any of the arguments is invalid + * * @since 1.7 */ ! public void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, ! long bytes) { ! copyMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes); ! ! if (bytes == 0) { ! return; ! } ! ! copyMemory0(srcBase, srcOffset, destBase, destOffset, bytes); ! } ! /** * Sets all bytes in a given block of memory to a copy of another * block. This provides a <em>single-register</em> addressing mode, * as discussed in {@link #getInt(Object,long)}. *
*** 456,522 **** */ public void copyMemory(long srcAddress, long destAddress, long bytes) { copyMemory(null, srcAddress, null, destAddress, bytes); } ! private boolean isPrimitiveArray(Class<?> c) { ! Class<?> componentType = c.getComponentType(); ! return componentType != null && componentType.isPrimitive(); ! } ! ! private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, ! long bytes, long elemSize); /** * Copies all elements from one block of memory to another block, * *unconditionally* byte swapping the elements on the fly. * * <p>This method determines each block's base address by means of two parameters, * and so it provides (in effect) a <em>double-register</em> addressing mode, * as discussed in {@link #getInt(Object,long)}. When the object reference is null, * the offset supplies an absolute base address. * * @since 9 */ public void copySwapMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize) { ! if (bytes < 0) { ! throw new IllegalArgumentException(); ! } ! if (elemSize != 2 && elemSize != 4 && elemSize != 8) { ! throw new IllegalArgumentException(); ! } ! if (bytes % elemSize != 0) { ! throw new IllegalArgumentException(); ! } ! if ((srcBase == null && srcOffset == 0) || ! (destBase == null && destOffset == 0)) { ! throw new NullPointerException(); ! } ! // Must be off-heap, or primitive heap arrays ! if (srcBase != null && (srcOffset < 0 || !isPrimitiveArray(srcBase.getClass()))) { ! throw new IllegalArgumentException(); ! } ! if (destBase != null && (destOffset < 0 || !isPrimitiveArray(destBase.getClass()))) { ! throw new IllegalArgumentException(); } ! // Sanity check size and offsets on 32-bit platforms. Most ! // significant 32 bits must be zero. ! if (ADDRESS_SIZE == 4 && ! (bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) { ! throw new IllegalArgumentException(); } ! if (bytes == 0) { ! return; } ! copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize); } /** * Copies all elements from one block of memory to another block, byte swapping the * elements on the fly. --- 749,822 ---- */ public void copyMemory(long srcAddress, long destAddress, long bytes) { copyMemory(null, srcAddress, null, destAddress, bytes); } ! /** ! * Validate the arguments to copyMemory ! * ! * @throws RuntimeException if any of the arguments is invalid ! * (<em>Note:</em> after optimization, invalid inputs may ! * go undetected, which will lead to unpredictable ! * behavior) ! */ ! private void copyMemoryChecks(Object srcBase, long srcOffset, Object destBase, long destOffset, ! long bytes) { ! checkSize(bytes); ! checkPrimitivePointer(srcBase, srcOffset); ! checkPrimitivePointer(destBase, destOffset); ! } /** * Copies all elements from one block of memory to another block, * *unconditionally* byte swapping the elements on the fly. * * <p>This method determines each block's base address by means of two parameters, * and so it provides (in effect) a <em>double-register</em> addressing mode, * as discussed in {@link #getInt(Object,long)}. When the object reference is null, * the offset supplies an absolute base address. * + * <em>Note:</em> It is the resposibility of the caller to make + * sure arguments are checked before the methods are called. While + * some rudimentary checks are performed on the input, the checks + * are best effort and when performance is an overriding priority, + * as when methods of this class are optimized by the runtime + * compiler, some or all checks (if any) may be elided. Hence, the + * caller must not rely on the checks and corresponding + * exceptions! + * + * @throws RuntimeException if any of the arguments is invalid + * * @since 9 */ public void copySwapMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize) { ! copySwapMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes, elemSize); ! if (bytes == 0) { ! return; } ! copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize); } ! private void copySwapMemoryChecks(Object srcBase, long srcOffset, ! Object destBase, long destOffset, ! long bytes, long elemSize) { ! checkSize(bytes); ! ! if (elemSize != 2 && elemSize != 4 && elemSize != 8) { ! throw invalidInput(); ! } ! if (bytes % elemSize != 0) { ! throw invalidInput(); } ! checkPrimitivePointer(srcBase, srcOffset); ! checkPrimitivePointer(destBase, destOffset); } /** * Copies all elements from one block of memory to another block, byte swapping the * elements on the fly.
*** 533,545 **** /** * Disposes of a block of native memory, as obtained from {@link * #allocateMemory} or {@link #reallocateMemory}. The address passed to * this method may be null, in which case no action is taken. * * @see #allocateMemory */ ! public native void freeMemory(long address); /// random queries /** * This constant differs from all results that will ever be returned from --- 833,876 ---- /** * Disposes of a block of native memory, as obtained from {@link * #allocateMemory} or {@link #reallocateMemory}. The address passed to * this method may be null, in which case no action is taken. * + * <em>Note:</em> It is the resposibility of the caller to make + * sure arguments are checked before the methods are called. While + * some rudimentary checks are performed on the input, the checks + * are best effort and when performance is an overriding priority, + * as when methods of this class are optimized by the runtime + * compiler, some or all checks (if any) may be elided. Hence, the + * caller must not rely on the checks and corresponding + * exceptions! + * + * @throws RuntimeException if any of the arguments is invalid + * * @see #allocateMemory */ ! public void freeMemory(long address) { ! freeMemoryChecks(address); ! ! if (address == 0) { ! return; ! } ! ! freeMemory0(address); ! } ! ! /** ! * Validate the arguments to freeMemory ! * ! * @throws RuntimeException if the arguments are invalid ! * (<em>Note:</em> after optimization, invalid inputs may ! * go undetected, which will lead to unpredictable ! * behavior) ! */ ! private void freeMemoryChecks(long address) { ! checkPointer(null, address); ! } /// random queries /** * This constant differs from all results that will ever be returned from
*** 564,574 **** * the field locations in a form usable by {@link #getInt(Object,long)}. * Therefore, code which will be ported to such JVMs on 64-bit platforms * must preserve all bits of static field offsets. * @see #getInt(Object, long) */ ! public native long objectFieldOffset(Field f); /** * Reports the location of a given static field, in conjunction with {@link * #staticFieldBase}. * <p>Do not expect to perform any sort of arithmetic on this offset; --- 895,911 ---- * the field locations in a form usable by {@link #getInt(Object,long)}. * Therefore, code which will be ported to such JVMs on 64-bit platforms * must preserve all bits of static field offsets. * @see #getInt(Object, long) */ ! public long objectFieldOffset(Field f) { ! if (f == null) { ! throw new NullPointerException(); ! } ! ! return objectFieldOffset0(f); ! } /** * Reports the location of a given static field, in conjunction with {@link * #staticFieldBase}. * <p>Do not expect to perform any sort of arithmetic on this offset;
*** 583,593 **** * a few bits to encode an offset within a non-array object, * However, for consistency with other methods in this class, * this method reports its result as a long value. * @see #getInt(Object, long) */ ! public native long staticFieldOffset(Field f); /** * Reports the location of a given static field, in conjunction with {@link * #staticFieldOffset}. * <p>Fetch the base "Object", if any, with which static fields of the --- 920,936 ---- * a few bits to encode an offset within a non-array object, * However, for consistency with other methods in this class, * this method reports its result as a long value. * @see #getInt(Object, long) */ ! public long staticFieldOffset(Field f) { ! if (f == null) { ! throw new NullPointerException(); ! } ! ! return staticFieldOffset0(f); ! } /** * Reports the location of a given static field, in conjunction with {@link * #staticFieldOffset}. * <p>Fetch the base "Object", if any, with which static fields of the
*** 595,620 **** * long)}. This value may be null. This value may refer to an object * which is a "cookie", not guaranteed to be a real Object, and it should * not be used in any way except as argument to the get and put routines in * this class. */ ! public native Object staticFieldBase(Field f); /** * Detects if the given class may need to be initialized. This is often * needed in conjunction with obtaining the static field base of a * class. * @return false only if a call to {@code ensureClassInitialized} would have no effect */ ! public native boolean shouldBeInitialized(Class<?> c); /** * Ensures the given class has been initialized. This is often * needed in conjunction with obtaining the static field base of a * class. */ ! public native void ensureClassInitialized(Class<?> c); /** * Reports the offset of the first element in the storage allocation of a * given array class. If {@link #arrayIndexScale} returns a non-zero value * for the same class, you may use that scale factor, together with this --- 938,981 ---- * long)}. This value may be null. This value may refer to an object * which is a "cookie", not guaranteed to be a real Object, and it should * not be used in any way except as argument to the get and put routines in * this class. */ ! public Object staticFieldBase(Field f) { ! if (f == null) { ! throw new NullPointerException(); ! } ! ! return staticFieldBase0(f); ! } /** * Detects if the given class may need to be initialized. This is often * needed in conjunction with obtaining the static field base of a * class. * @return false only if a call to {@code ensureClassInitialized} would have no effect */ ! public boolean shouldBeInitialized(Class<?> c) { ! if (c == null) { ! throw new NullPointerException(); ! } ! ! return shouldBeInitialized0(c); ! } /** * Ensures the given class has been initialized. This is often * needed in conjunction with obtaining the static field base of a * class. */ ! public void ensureClassInitialized(Class<?> c) { ! if (c == null) { ! throw new NullPointerException(); ! } ! ! ensureClassInitialized0(c); ! } /** * Reports the offset of the first element in the storage allocation of a * given array class. If {@link #arrayIndexScale} returns a non-zero value * for the same class, you may use that scale factor, together with this
*** 622,632 **** * given class. * * @see #getInt(Object, long) * @see #putInt(Object, long, int) */ ! public native int arrayBaseOffset(Class<?> arrayClass); /** The value of {@code arrayBaseOffset(boolean[].class)} */ public static final int ARRAY_BOOLEAN_BASE_OFFSET = theUnsafe.arrayBaseOffset(boolean[].class); --- 983,1000 ---- * given class. * * @see #getInt(Object, long) * @see #putInt(Object, long, int) */ ! public int arrayBaseOffset(Class<?> arrayClass) { ! if (arrayClass == null) { ! throw new NullPointerException(); ! } ! ! return arrayBaseOffset0(arrayClass); ! } ! /** The value of {@code arrayBaseOffset(boolean[].class)} */ public static final int ARRAY_BOOLEAN_BASE_OFFSET = theUnsafe.arrayBaseOffset(boolean[].class);
*** 671,681 **** * * @see #arrayBaseOffset * @see #getInt(Object, long) * @see #putInt(Object, long, int) */ ! public native int arrayIndexScale(Class<?> arrayClass); /** The value of {@code arrayIndexScale(boolean[].class)} */ public static final int ARRAY_BOOLEAN_INDEX_SCALE = theUnsafe.arrayIndexScale(boolean[].class); --- 1039,1056 ---- * * @see #arrayBaseOffset * @see #getInt(Object, long) * @see #putInt(Object, long, int) */ ! public int arrayIndexScale(Class<?> arrayClass) { ! if (arrayClass == null) { ! throw new NullPointerException(); ! } ! ! return arrayIndexScale0(arrayClass); ! } ! /** The value of {@code arrayIndexScale(boolean[].class)} */ public static final int ARRAY_BOOLEAN_INDEX_SCALE = theUnsafe.arrayIndexScale(boolean[].class);
*** 715,728 **** * Reports the size in bytes of a native pointer, as stored via {@link * #putAddress}. This value will be either 4 or 8. Note that the sizes of * other primitive types (as stored in native memory blocks) is determined * fully by their information content. */ ! public native int addressSize(); /** The value of {@code addressSize()} */ ! public static final int ADDRESS_SIZE = theUnsafe.addressSize(); /** * Reports the size in bytes of a native memory page (whatever that is). * This value will always be a power of two. */ --- 1090,1105 ---- * Reports the size in bytes of a native pointer, as stored via {@link * #putAddress}. This value will be either 4 or 8. Note that the sizes of * other primitive types (as stored in native memory blocks) is determined * fully by their information content. */ ! public int addressSize() { ! return ADDRESS_SIZE; ! } /** The value of {@code addressSize()} */ ! public static final int ADDRESS_SIZE = theUnsafe.addressSize0(); /** * Reports the size in bytes of a native memory page (whatever that is). * This value will always be a power of two. */
*** 733,743 **** /** * Tells the VM to define a class, without security checks. By default, the * class loader and protection domain come from the caller's class. */ ! public native Class<?> defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain); /** * Defines a class but does not make it known to the class loader or system dictionary. --- 1110,1133 ---- /** * Tells the VM to define a class, without security checks. By default, the * class loader and protection domain come from the caller's class. */ ! public Class<?> defineClass(String name, byte[] b, int off, int len, ! ClassLoader loader, ! ProtectionDomain protectionDomain) { ! if (b == null) { ! throw new NullPointerException(); ! } ! if (len < 0) { ! throw new ArrayIndexOutOfBoundsException(); ! } ! ! return defineClass0(name, b, off, len, loader, protectionDomain); ! } ! ! public native Class<?> defineClass0(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain); /** * Defines a class but does not make it known to the class loader or system dictionary.
*** 753,763 **** * </ul> * @param hostClass context for linkage, access control, protection domain, and class loader * @param data bytes of a class file * @param cpPatches where non-null entries exist, they replace corresponding CP entries in data */ ! public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches); /** * Allocates an instance but does not run any constructor. * Initializes the class if it has not yet been. */ --- 1143,1159 ---- * </ul> * @param hostClass context for linkage, access control, protection domain, and class loader * @param data bytes of a class file * @param cpPatches where non-null entries exist, they replace corresponding CP entries in data */ ! public Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches) { ! if (hostClass == null || data == null) { ! throw new NullPointerException(); ! } ! ! return defineAnonymousClass0(hostClass, data, cpPatches); ! } /** * Allocates an instance but does not run any constructor. * Initializes the class if it has not yet been. */
*** 1288,1298 **** * must be 1 to 3. * * @return the number of samples actually retrieved; or -1 * if the load average is unobtainable. */ ! public native int getLoadAverage(double[] loadavg, int nelems); // The following contain CAS-based Java implementations used on // platforms not supporting native instructions /** --- 1684,1700 ---- * must be 1 to 3. * * @return the number of samples actually retrieved; or -1 * if the load average is unobtainable. */ ! public int getLoadAverage(double[] loadavg, int nelems) { ! if (nelems < 0 || nelems > 3 || nelems > loadavg.length) { ! throw new ArrayIndexOutOfBoundsException(); ! } ! ! return getLoadAverage0(loadavg, nelems); ! } // The following contain CAS-based Java implementations used on // platforms not supporting native instructions /**
*** 1716,1728 **** public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) { putCharUnaligned(o, offset, convEndian(bigEndian, x)); } // JVM interface methods - private native boolean unalignedAccess0(); - private native boolean isBigEndian0(); - // BE is true iff the native endianness of this platform is big. private static final boolean BE = theUnsafe.isBigEndian0(); // unalignedAccess is true iff this platform can perform unaligned accesses. private static final boolean unalignedAccess = theUnsafe.unalignedAccess0(); --- 2118,2127 ----
*** 1818,1823 **** --- 2217,2244 ---- // Maybe byte-reverse an integer private static char convEndian(boolean big, char n) { return big == BE ? n : Character.reverseBytes(n); } private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; } private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; } private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; } + + + + private native long allocateMemory0(long bytes); + private native long reallocateMemory0(long address, long bytes); + private native void freeMemory0(long address); + private native void setMemory0(Object o, long offset, long bytes, byte value); + @HotSpotIntrinsicCandidate + private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes); + private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize); + private native long objectFieldOffset0(Field f); + private native long staticFieldOffset0(Field f); + private native Object staticFieldBase0(Field f); + private native boolean shouldBeInitialized0(Class<?> c); + private native void ensureClassInitialized0(Class<?> c); + private native int arrayBaseOffset0(Class<?> arrayClass); + private native int arrayIndexScale0(Class<?> arrayClass); + private native int addressSize0(); + private native Class<?> defineAnonymousClass0(Class<?> hostClass, byte[] data, Object[] cpPatches); + private native int getLoadAverage0(double[] loadavg, int nelems); + private native boolean unalignedAccess0(); + private native boolean isBigEndian0(); }
src/java.base/share/classes/jdk/internal/misc/Unsafe.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File