< prev index next > src/java.base/share/classes/jdk/internal/misc/Unsafe.java
Print this page
* {@link NullPointerException}
*/
@IntrinsicCandidate
public native void putInt(Object o, long offset, int x);
+
+ /**
+ * Returns true if the given field is flattened.
+ */
+ public boolean isFlatField(Field f) {
+ if (f == null) {
+ throw new NullPointerException();
+ }
+ return isFlatField0(f);
+ }
+
+ private native boolean isFlatField0(Object o);
+
+ /* Returns true if the given field has a null marker
+ * <p>
+ * Nullable flat fields are stored in a flattened representation
+ * and have an associated null marker to indicate if the the field value is
+ * null or the one stored with the flat representation
+ */
+
+ public boolean hasNullMarker(Field f) {
+ if (f == null) {
+ throw new NullPointerException();
+ }
+ return hasNullMarker0(f);
+ }
+
+ private native boolean hasNullMarker0(Object o);
+
+ /* Returns the offset of the null marker of the field,
+ * or -1 if the field doesn't have a null marker
+ */
+
+ public int nullMarkerOffset(Field f) {
+ if (f == null) {
+ throw new NullPointerException();
+ }
+ return nullMarkerOffset0(f);
+ }
+
+ private native int nullMarkerOffset0(Object o);
+
+ /**
+ * Returns true if the given class is a flattened array.
+ */
+ @IntrinsicCandidate
+ public native boolean isFlatArray(Class<?> arrayClass);
+
/**
* Fetches a reference value from a given Java variable.
+ * This method can return a reference to either an object or value
+ * or a null reference.
+ *
* @see #getInt(Object, long)
*/
@IntrinsicCandidate
public native Object getReference(Object o, long offset);
/**
* Stores a reference value into a given Java variable.
+ * This method can store a reference to either an object or value
+ * or a null reference.
* <p>
* Unless the reference {@code x} being stored is either null
* or matches the field type, the results are undefined.
* If the reference {@code o} is non-null, card marks or
* other store barriers for that object (if the VM requires them)
* @see #putInt(Object, long, int)
*/
@IntrinsicCandidate
public native void putReference(Object o, long offset, Object x);
+ /**
+ * Fetches a value of type {@code <V>} from a given Java variable.
+ * More specifically, fetches a field or array element within the given
+ * {@code o} object at the given offset, or (if {@code o} is null)
+ * from the memory address whose numerical value is the given offset.
+ *
+ * @param o Java heap object in which the variable resides, if any, else
+ * null
+ * @param offset indication of where the variable resides in a Java heap
+ * object, if any, else a memory address locating the variable
+ * statically
+ * @param valueType value type
+ * @param <V> the type of a value
+ * @return the value fetched from the indicated Java variable
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ */
+ @IntrinsicCandidate
+ public native <V> V getValue(Object o, long offset, Class<?> valueType);
+
+ /**
+ * Stores the given value into a given Java variable.
+ *
+ * Unless the reference {@code o} being stored is either null
+ * or matches the field type, the results are undefined.
+ *
+ * @param o Java heap object in which the variable resides, if any, else
+ * null
+ * @param offset indication of where the variable resides in a Java heap
+ * object, if any, else a memory address locating the variable
+ * statically
+ * @param valueType value type
+ * @param v the value to store into the indicated Java variable
+ * @param <V> the type of a value
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ */
+ @IntrinsicCandidate
+ public native <V> void putValue(Object o, long offset, Class<?> valueType, V v);
+
+ /**
+ * Returns an uninitialized default instance of the given value class.
+ */
+ public native <V> V uninitializedDefaultValue(Class<?> type);
+
+ /**
+ * Returns an object instance with a private buffered value whose layout
+ * and contents is exactly the given value instance. The return object
+ * is in the larval state that can be updated using the unsafe put operation.
+ *
+ * @param value a value instance
+ * @param <V> the type of the given value instance
+ */
+ @IntrinsicCandidate
+ public native <V> V makePrivateBuffer(V value);
+
+ /**
+ * Exits the larval state and returns a value instance.
+ *
+ * @param value a value instance
+ * @param <V> the type of the given value instance
+ */
+ @IntrinsicCandidate
+ public native <V> V finishPrivateBuffer(V value);
+
+ /**
+ * Returns the header size of the given value type.
+ *
+ * @param valueType value type
+ * @return the header size of the value type
+ */
+ public native <V> long valueHeaderSize(Class<V> valueType);
+
/** @see #getInt(Object, long) */
@IntrinsicCandidate
public native boolean getBoolean(Object o, long offset);
/** @see #putInt(Object, long, int) */
}
return arrayIndexScale0(arrayClass);
}
+ /**
+ * Return the size of the object in the heap.
+ * @param o an object
+ * @return the objects's size
+ * @since Valhalla
+ */
+ public long getObjectSize(Object o) {
+ if (o == null)
+ throw new NullPointerException();
+ return getObjectSize0(o);
+ }
/** The value of {@code arrayIndexScale(boolean[].class)} */
public static final int ARRAY_BOOLEAN_INDEX_SCALE
= theUnsafe.arrayIndexScale(boolean[].class);
@IntrinsicCandidate
public final native boolean compareAndSetReference(Object o, long offset,
Object expected,
Object x);
+ private final boolean isValueObject(Object o) {
+ return o != null && o.getClass().isValue();
+ }
+
+ /*
+ * For value type, CAS should do substitutability test as opposed
+ * to two pointers comparison.
+ *
+ * TODO: replace global lock workaround with the proper support for
+ * atomic access to value objects and loosely consistent values.
+ */
+ public final <V> boolean compareAndSetReference(Object o, long offset,
+ Class<?> type,
+ V expected,
+ V x) {
+ if (type.isValue() || isValueObject(expected)) {
+ synchronized (valueLock) {
+ Object witness = getReference(o, offset);
+ if (witness == expected) {
+ putReference(o, offset, x);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return compareAndSetReference(o, offset, expected, x);
+ }
+ }
+
+ @ForceInline
+ public final <V> boolean compareAndSetValue(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ synchronized (valueLock) {
+ Object witness = getValue(o, offset, valueType);
+ if (witness == expected) {
+ putValue(o, offset, valueType, x);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+
@IntrinsicCandidate
public final native Object compareAndExchangeReference(Object o, long offset,
Object expected,
Object x);
+ public final <V> Object compareAndExchangeReference(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ if (valueType.isValue() || isValueObject(expected)) {
+ synchronized (valueLock) {
+ Object witness = getReference(o, offset);
+ if (witness == expected) {
+ putReference(o, offset, x);
+ }
+ return witness;
+ }
+ } else {
+ return compareAndExchangeReference(o, offset, expected, x);
+ }
+ }
+
+ @ForceInline
+ public final <V> Object compareAndExchangeValue(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ synchronized (valueLock) {
+ Object witness = getValue(o, offset, valueType);
+ if (witness == expected) {
+ putValue(o, offset, valueType, x);
+ }
+ return witness;
+ }
+ }
+
@IntrinsicCandidate
public final Object compareAndExchangeReferenceAcquire(Object o, long offset,
Object expected,
Object x) {
return compareAndExchangeReference(o, offset, expected, x);
}
+ public final <V> Object compareAndExchangeReferenceAcquire(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndExchangeReference(o, offset, valueType, expected, x);
+ }
+
+ @ForceInline
+ public final <V> Object compareAndExchangeValueAcquire(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndExchangeValue(o, offset, valueType, expected, x);
+ }
+
@IntrinsicCandidate
public final Object compareAndExchangeReferenceRelease(Object o, long offset,
Object expected,
Object x) {
return compareAndExchangeReference(o, offset, expected, x);
}
+ public final <V> Object compareAndExchangeReferenceRelease(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndExchangeReference(o, offset, valueType, expected, x);
+ }
+
+ @ForceInline
+ public final <V> Object compareAndExchangeValueRelease(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndExchangeValue(o, offset, valueType, expected, x);
+ }
+
@IntrinsicCandidate
public final boolean weakCompareAndSetReferencePlain(Object o, long offset,
Object expected,
Object x) {
return compareAndSetReference(o, offset, expected, x);
}
+ public final <V> boolean weakCompareAndSetReferencePlain(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ if (valueType.isValue() || isValueObject(expected)) {
+ return compareAndSetReference(o, offset, valueType, expected, x);
+ } else {
+ return weakCompareAndSetReferencePlain(o, offset, expected, x);
+ }
+ }
+
+ @ForceInline
+ public final <V> boolean weakCompareAndSetValuePlain(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndSetValue(o, offset, valueType, expected, x);
+ }
+
@IntrinsicCandidate
public final boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
Object expected,
Object x) {
return compareAndSetReference(o, offset, expected, x);
}
+ public final <V> boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ if (valueType.isValue() || isValueObject(expected)) {
+ return compareAndSetReference(o, offset, valueType, expected, x);
+ } else {
+ return weakCompareAndSetReferencePlain(o, offset, expected, x);
+ }
+ }
+
+ @ForceInline
+ public final <V> boolean weakCompareAndSetValueAcquire(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndSetValue(o, offset, valueType, expected, x);
+ }
+
@IntrinsicCandidate
public final boolean weakCompareAndSetReferenceRelease(Object o, long offset,
Object expected,
Object x) {
return compareAndSetReference(o, offset, expected, x);
}
+ public final <V> boolean weakCompareAndSetReferenceRelease(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ if (valueType.isValue() || isValueObject(expected)) {
+ return compareAndSetReference(o, offset, valueType, expected, x);
+ } else {
+ return weakCompareAndSetReferencePlain(o, offset, expected, x);
+ }
+ }
+
+ @ForceInline
+ public final <V> boolean weakCompareAndSetValueRelease(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndSetValue(o, offset, valueType, expected, x);
+ }
+
@IntrinsicCandidate
public final boolean weakCompareAndSetReference(Object o, long offset,
Object expected,
Object x) {
return compareAndSetReference(o, offset, expected, x);
}
+ public final <V> boolean weakCompareAndSetReference(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ if (valueType.isValue() || isValueObject(expected)) {
+ return compareAndSetReference(o, offset, valueType, expected, x);
+ } else {
+ return weakCompareAndSetReferencePlain(o, offset, expected, x);
+ }
+ }
+
+ @ForceInline
+ public final <V> boolean weakCompareAndSetValue(Object o, long offset,
+ Class<?> valueType,
+ V expected,
+ V x) {
+ return compareAndSetValue(o, offset, valueType, expected, x);
+ }
+
/**
* Atomically updates Java variable to {@code x} if it is currently
* holding {@code expected}.
*
* <p>This operation has memory semantics of a {@code volatile} read
* load semantics. Otherwise identical to {@link #getReference(Object, long)}
*/
@IntrinsicCandidate
public native Object getReferenceVolatile(Object o, long offset);
+ /**
+ * Global lock for atomic and volatile strength access to any value of
+ * a value type. This is a temporary workaround until better localized
+ * atomic access mechanisms are supported for value class and primitive class.
+ */
+ private static final Object valueLock = new Object();
+
+ public final <V> Object getValueVolatile(Object base, long offset, Class<?> valueType) {
+ synchronized (valueLock) {
+ return getValue(base, offset, valueType);
+ }
+ }
+
/**
* Stores a reference value into a given Java variable, with
* volatile store semantics. Otherwise identical to {@link #putReference(Object, long, Object)}
*/
@IntrinsicCandidate
public native void putReferenceVolatile(Object o, long offset, Object x);
+ public final <V> void putValueVolatile(Object o, long offset, Class<?> valueType, V x) {
+ synchronized (valueLock) {
+ putValue(o, offset, valueType, x);
+ }
+ }
+
/** Volatile version of {@link #getInt(Object, long)} */
@IntrinsicCandidate
public native int getIntVolatile(Object o, long offset);
/** Volatile version of {@link #putInt(Object, long, int)} */
@IntrinsicCandidate
public final Object getReferenceAcquire(Object o, long offset) {
return getReferenceVolatile(o, offset);
}
+ public final <V> Object getValueAcquire(Object base, long offset, Class<?> valueType) {
+ return getValueVolatile(base, offset, valueType);
+ }
+
/** Acquire version of {@link #getBooleanVolatile(Object, long)} */
@IntrinsicCandidate
public final boolean getBooleanAcquire(Object o, long offset) {
return getBooleanVolatile(o, offset);
}
@IntrinsicCandidate
public final void putReferenceRelease(Object o, long offset, Object x) {
putReferenceVolatile(o, offset, x);
}
+ public final <V> void putValueRelease(Object o, long offset, Class<?> valueType, V x) {
+ putValueVolatile(o, offset, valueType, x);
+ }
+
/** Release version of {@link #putBooleanVolatile(Object, long, boolean)} */
@IntrinsicCandidate
public final void putBooleanRelease(Object o, long offset, boolean x) {
putBooleanVolatile(o, offset, x);
}
@IntrinsicCandidate
public final Object getReferenceOpaque(Object o, long offset) {
return getReferenceVolatile(o, offset);
}
+ public final <V> Object getValueOpaque(Object base, long offset, Class<?> valueType) {
+ return getValueVolatile(base, offset, valueType);
+ }
+
/** Opaque version of {@link #getBooleanVolatile(Object, long)} */
@IntrinsicCandidate
public final boolean getBooleanOpaque(Object o, long offset) {
return getBooleanVolatile(o, offset);
}
@IntrinsicCandidate
public final void putReferenceOpaque(Object o, long offset, Object x) {
putReferenceVolatile(o, offset, x);
}
+ public final <V> void putValueOpaque(Object o, long offset, Class<?> valueType, V x) {
+ putValueVolatile(o, offset, valueType, x);
+ }
+
/** Opaque version of {@link #putBooleanVolatile(Object, long, boolean)} */
@IntrinsicCandidate
public final void putBooleanOpaque(Object o, long offset, boolean x) {
putBooleanVolatile(o, offset, x);
}
v = getReferenceVolatile(o, offset);
} while (!weakCompareAndSetReference(o, offset, v, newValue));
return v;
}
+ @SuppressWarnings("unchecked")
+ public final <V> Object getAndSetValue(Object o, long offset, Class<?> valueType, V newValue) {
+ synchronized (valueLock) {
+ Object oldValue = getValue(o, offset, valueType);
+ putValue(o, offset, valueType, newValue);
+ return oldValue;
+ }
+ }
+
@ForceInline
public final Object getAndSetReferenceRelease(Object o, long offset, Object newValue) {
Object v;
do {
v = getReference(o, offset);
} while (!weakCompareAndSetReferenceRelease(o, offset, v, newValue));
return v;
}
+ @ForceInline
+ public final <V> Object getAndSetValueRelease(Object o, long offset, Class<?> valueType, V newValue) {
+ return getAndSetValue(o, offset, valueType, newValue);
+ }
+
@ForceInline
public final Object getAndSetReferenceAcquire(Object o, long offset, Object newValue) {
Object v;
do {
v = getReferenceAcquire(o, offset);
} while (!weakCompareAndSetReferenceAcquire(o, offset, v, newValue));
return v;
}
+ @ForceInline
+ public final <V> Object getAndSetValueAcquire(Object o, long offset, Class<?> valueType, V newValue) {
+ return getAndSetValue(o, offset, valueType, newValue);
+ }
+
@IntrinsicCandidate
public final byte getAndSetByte(Object o, long offset, byte newValue) {
byte v;
do {
v = getByteVolatile(o, offset);
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 long getObjectSize0(Object o);
private native int getLoadAverage0(double[] loadavg, int nelems);
/**
* Invokes the given direct byte buffer's cleaner, if any.
< prev index next >