< prev index next >

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

Print this page
@@ -24,10 +24,11 @@
   */
  
  package jdk.internal.misc;
  
  import jdk.internal.ref.Cleaner;
+ import jdk.internal.value.ValueClass;
  import jdk.internal.vm.annotation.ForceInline;
  import jdk.internal.vm.annotation.IntrinsicCandidate;
  import sun.nio.ch.DirectBuffer;
  
  import java.lang.reflect.Field;

@@ -180,19 +181,110 @@
       *         {@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);
+ 
+     public static final int NON_FLAT_LAYOUT = 0;
+ 
+     /* Reports the kind of layout used for an element in the storage
+      * allocation of the given array. Do not expect to perform any logic
+      * or layout control with this value, it is just an opaque token
+      * used for performance reasons.
+      *
+      * A layout of 0 indicates this array is not flat.
+      */
+     public int arrayLayout(Class<?> arrayClass) {
+         if (arrayClass == null) {
+             throw new NullPointerException();
+         }
+         return arrayLayout0(arrayClass);
+     }
+ 
+     private native int arrayLayout0(Object o);
+ 
+ 
+     /* Reports the kind of layout used for a given field in the storage
+      * allocation of its class.  Do not expect to perform any logic
+      * or layout control with this value, it is just an opaque token
+      * used for performance reasons.
+      *
+      * A layout of 0 indicates this field is not flat.
+      */
+     public int fieldLayout(Field f) {
+         if (f == null) {
+             throw new NullPointerException();
+         }
+         return fieldLayout0(f);
+     }
+ 
+     private native int fieldLayout0(Object o);
+ 
+     public native Object[] newSpecialArray(Class<?> componentType,
+                                                   int length, int layoutKind);
+ 
+     /**
+      * 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)

@@ -200,10 +292,123 @@
       * @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);
+ 
+     /**
+      * 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 layoutKind opaque value used by the VM to know the layout
+      *        the field or array element. This value must be retrieved with
+      *        {@link #fieldLayout} or {@link #arrayLayout}.
+      * @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}
+      */
+     public native <V> V getFlatValue(Object o, long offset, int layoutKind, 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);
+ 
+     /**
+      * 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 layoutKind opaque value used by the VM to know the layout
+      *        the field or array element. This value must be retrieved with
+      *        {@link #fieldLayout} or {@link #arrayLayout}.
+      * @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}
+      */
+     public native <V> void putFlatValue(Object o, long offset, int layoutKind, Class<?> valueType, V v);
+ 
+     /**
+      * 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) */

@@ -1248,10 +1453,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);
  

@@ -1426,57 +1642,251 @@
      @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.
+      */
+     @ForceInline
+     public final <V> boolean compareAndSetReference(Object o, long offset,
+                                                     Class<?> type,
+                                                     V expected,
+                                                     V x) {
+         if (type.isValue() || isValueObject(expected)) {
+             while (true) {
+                 Object witness = getReferenceVolatile(o, offset);
+                 if (witness != expected) {
+                     return false;
+                 }
+                 if (compareAndSetReference(o, offset, witness, x)) {
+                     return true;
+                 }
+             }
+         } else {
+             return compareAndSetReference(o, offset, expected, x);
+         }
+     }
+ 
+     @ForceInline
+     public final <V> boolean compareAndSetFlatValue(Object o, long offset,
+                                                 int layout,
+                                                 Class<?> valueType,
+                                                 V expected,
+                                                 V x) {
+         while (true) {
+             Object witness = getFlatValueVolatile(o, offset, layout, valueType);
+             if (witness != expected) {
+                 return false;
+             }
+             if (compareAndSetFlatValueAsBytes(o, offset, layout, valueType, witness, x)) {
+                 return true;
+             }
+         }
+     }
+ 
      @IntrinsicCandidate
      public final native Object compareAndExchangeReference(Object o, long offset,
                                                             Object expected,
                                                             Object x);
  
+     @ForceInline
+     public final <V> Object compareAndExchangeReference(Object o, long offset,
+                                                         Class<?> valueType,
+                                                         V expected,
+                                                         V x) {
+         if (valueType.isValue() || isValueObject(expected)) {
+             while (true) {
+                 Object witness = getReferenceVolatile(o, offset);
+                 if (witness != expected) {
+                     return witness;
+                 }
+                 if (compareAndSetReference(o, offset, witness, x)) {
+                     return witness;
+                 }
+             }
+         } else {
+             return compareAndExchangeReference(o, offset, expected, x);
+         }
+     }
+ 
+     @ForceInline
+     public final <V> Object compareAndExchangeFlatValue(Object o, long offset,
+                                                     int layout,
+                                                     Class<?> valueType,
+                                                     V expected,
+                                                     V x) {
+         while (true) {
+             Object witness = getFlatValueVolatile(o, offset, layout, valueType);
+             if (witness != expected) {
+                 return witness;
+             }
+             if (compareAndSetFlatValueAsBytes(o, offset, layout, valueType, witness, 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 compareAndExchangeFlatValueAcquire(Object o, long offset,
+                                                            int layout,
+                                                            Class<?> valueType,
+                                                            V expected,
+                                                            V x) {
+         return compareAndExchangeFlatValue(o, offset, layout, 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 compareAndExchangeFlatValueRelease(Object o, long offset,
+                                                            int layout,
+                                                            Class<?> valueType,
+                                                            V expected,
+                                                            V x) {
+         return compareAndExchangeFlatValue(o, offset, layout, 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 weakCompareAndSetFlatValuePlain(Object o, long offset,
+                                                          int layout,
+                                                          Class<?> valueType,
+                                                          V expected,
+                                                          V x) {
+         return compareAndSetFlatValue(o, offset, layout, 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 weakCompareAndSetFlatValueAcquire(Object o, long offset,
+                                                            int layout,
+                                                            Class<?> valueType,
+                                                            V expected,
+                                                            V x) {
+         return compareAndSetFlatValue(o, offset, layout, 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 weakCompareAndSetFlatValueRelease(Object o, long offset,
+                                                            int layout,
+                                                            Class<?> valueType,
+                                                            V expected,
+                                                            V x) {
+         return compareAndSetFlatValue(o, offset, layout, 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 weakCompareAndSetFlatValue(Object o, long offset,
+                                                     int layout,
+                                                     Class<?> valueType,
+                                                     V expected,
+                                                     V x) {
+         return compareAndSetFlatValue(o, offset, layout, 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

@@ -2088,17 +2498,32 @@
       * load semantics. Otherwise identical to {@link #getReference(Object, long)}
       */
      @IntrinsicCandidate
      public native Object getReferenceVolatile(Object o, long offset);
  
+     @ForceInline
+     public final <V> Object getFlatValueVolatile(Object o, long offset, int layout, Class<?> valueType) {
+         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
+         Object res = getFlatValue(o, offset, layout, valueType);
+         fullFence();
+         return res;
+     }
+ 
      /**
       * 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);
  
+     @ForceInline
+     public final <V> void putFlatValueVolatile(Object o, long offset, int layout, Class<?> valueType, V x) {
+         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
+         putFlatValueRelease(o, offset, layout, valueType, x);
+         fullFence();
+     }
+ 
      /** Volatile version of {@link #getInt(Object, long)}  */
      @IntrinsicCandidate
      public native int     getIntVolatile(Object o, long offset);
  
      /** Volatile version of {@link #putInt(Object, long, int)}  */

@@ -2167,10 +2592,18 @@
      @IntrinsicCandidate
      public final Object getReferenceAcquire(Object o, long offset) {
          return getReferenceVolatile(o, offset);
      }
  
+     @ForceInline
+     public final <V> Object getFlatValueAcquire(Object o, long offset, int layout, Class<?> valueType) {
+         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
+         Object res = getFlatValue(o, offset, layout, valueType);
+         loadFence();
+         return res;
+     }
+ 
      /** Acquire version of {@link #getBooleanVolatile(Object, long)} */
      @IntrinsicCandidate
      public final boolean getBooleanAcquire(Object o, long offset) {
          return getBooleanVolatile(o, offset);
      }

@@ -2231,10 +2664,17 @@
      @IntrinsicCandidate
      public final void putReferenceRelease(Object o, long offset, Object x) {
          putReferenceVolatile(o, offset, x);
      }
  
+     @ForceInline
+     public final <V> void putFlatValueRelease(Object o, long offset, int layout, Class<?> valueType, V x) {
+         // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
+         storeFence();
+         putFlatValue(o, offset, layout, 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);
      }

@@ -2287,10 +2727,16 @@
      @IntrinsicCandidate
      public final Object getReferenceOpaque(Object o, long offset) {
          return getReferenceVolatile(o, offset);
      }
  
+     @ForceInline
+     public final <V> Object getFlatValueOpaque(Object o, long offset, int layout, Class<?> valueType) {
+         // this is stronger than opaque semantics
+         return getFlatValueAcquire(o, offset, layout, valueType);
+     }
+ 
      /** Opaque version of {@link #getBooleanVolatile(Object, long)} */
      @IntrinsicCandidate
      public final boolean getBooleanOpaque(Object o, long offset) {
          return getBooleanVolatile(o, offset);
      }

@@ -2341,10 +2787,16 @@
      @IntrinsicCandidate
      public final void putReferenceOpaque(Object o, long offset, Object x) {
          putReferenceVolatile(o, offset, x);
      }
  
+     @ForceInline
+     public final <V> void putFlatValueOpaque(Object o, long offset, int layout, Class<?> valueType, V x) {
+         // this is stronger than opaque semantics
+         putFlatValueRelease(o, offset, layout, 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);
      }

@@ -2389,10 +2841,50 @@
      @IntrinsicCandidate
      public final void putDoubleOpaque(Object o, long offset, double x) {
          putDoubleVolatile(o, offset, x);
      }
  
+     @ForceInline
+     private boolean compareAndSetFlatValueAsBytes(Object o, long offset, int layout, Class<?> valueType, Object expected, Object x) {
+         // We turn the payload of an atomic value into a numeric value (of suitable type)
+         // by storing the value into an array element (of matching layout) and by reading
+         // back the array element as an integral value. After which we can implement the CAS
+         // as a plain numeric CAS. Note: this only works if the payload contains no oops
+         // (see VarHandles::isAtomicFlat).
+         Object expectedArray = newSpecialArray(valueType, 1, layout);
+         Object xArray = newSpecialArray(valueType, 1, layout);
+         long base = arrayBaseOffset(expectedArray.getClass());
+         int scale = arrayIndexScale(expectedArray.getClass());
+         putFlatValue(expectedArray, base, layout, valueType, expected);
+         putFlatValue(xArray, base, layout, valueType, x);
+         switch (scale) {
+             case 1: {
+                 byte expectedByte = getByte(expectedArray, base);
+                 byte xByte = getByte(xArray, base);
+                 return compareAndSetByte(o, offset, expectedByte, xByte);
+             }
+             case 2: {
+                 short expectedShort = getShort(expectedArray, base);
+                 short xShort = getShort(xArray, base);
+                 return compareAndSetShort(o, offset, expectedShort, xShort);
+             }
+             case 4: {
+                 int expectedInt = getInt(expectedArray, base);
+                 int xInt = getInt(xArray, base);
+                 return compareAndSetInt(o, offset, expectedInt, xInt);
+             }
+             case 8: {
+                 long expectedLong = getLong(expectedArray, base);
+                 long xLong = getLong(xArray, base);
+                 return compareAndSetLong(o, offset, expectedLong, xLong);
+             }
+             default: {
+                 throw new UnsupportedOperationException();
+             }
+         }
+     }
+ 
      /**
       * Unblocks the given thread blocked on {@code park}, or, if it is
       * not blocked, causes the subsequent call to {@code park} not to
       * block.  Note: this operation is "unsafe" solely because the
       * caller must somehow ensure that the thread has not been

@@ -2775,28 +3267,66 @@
              v = getReferenceVolatile(o, offset);
          } while (!weakCompareAndSetReference(o, offset, v, newValue));
          return v;
      }
  
+     @ForceInline
+     public final Object getAndSetReference(Object o, long offset, Class<?> valueType, Object newValue) {
+         Object v;
+         do {
+             v = getReferenceVolatile(o, offset);
+         } while (!compareAndSetReference(o, offset, valueType, v, newValue));
+         return v;
+     }
+ 
+     @ForceInline
+     public Object getAndSetFlatValue(Object o, long offset, int layoutKind, Class<?> valueType, Object newValue) {
+         Object v;
+         do {
+             v = getFlatValueVolatile(o, offset, layoutKind, valueType);
+         } while (!compareAndSetFlatValue(o, offset, layoutKind, valueType, v, newValue));
+         return v;
+     }
+ 
      @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 Object getAndSetReferenceRelease(Object o, long offset, Class<?> valueType, Object newValue) {
+         return getAndSetReference(o, offset, valueType, newValue);
+     }
+ 
+     @ForceInline
+     public Object getAndSetFlatValueRelease(Object o, long offset, int layoutKind, Class<?> valueType, Object x) {
+         return getAndSetFlatValue(o, offset, layoutKind, valueType, x);
+     }
+ 
      @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 Object getAndSetReferenceAcquire(Object o, long offset, Class<?> valueType, Object newValue) {
+         return getAndSetReference(o, offset, valueType, newValue);
+     }
+ 
+     @ForceInline
+     public Object getAndSetFlatValueAcquire(Object o, long offset, int layoutKind, Class<?> valueType, Object x) {
+         return getAndSetFlatValue(o, offset, layoutKind, valueType, x);
+     }
+ 
      @IntrinsicCandidate
      public final byte getAndSetByte(Object o, long offset, byte newValue) {
          byte v;
          do {
              v = getByteVolatile(o, offset);

@@ -3850,10 +4380,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); // public version returns long to promote correct arithmetic
      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 >