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