diff a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
@@ -175,19 +175,72 @@
      *         {@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)
@@ -195,10 +248,83 @@
      * @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) */
@@ -1233,10 +1359,21 @@
         }
 
         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);
 
@@ -1411,57 +1548,241 @@
     @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
@@ -2073,17 +2394,36 @@
      * 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)}  */
@@ -2152,10 +2492,14 @@
     @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);
     }
@@ -2216,10 +2560,14 @@
     @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);
     }
@@ -2272,10 +2620,14 @@
     @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);
     }
@@ -2326,10 +2678,14 @@
     @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);
     }
@@ -2760,28 +3116,47 @@
             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);
@@ -3834,10 +4209,11 @@
     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.
