diff a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template
@@ -22,10 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 package java.lang.invoke;
 
+#if[Object]
+import jdk.internal.value.CheckedType;
+import jdk.internal.value.NullRestrictedCheckedType;
+import jdk.internal.value.ValueClass;
+#end[Object]
 import jdk.internal.util.Preconditions;
 import jdk.internal.vm.annotation.ForceInline;
 
 import java.lang.invoke.VarHandle.VarHandleDesc;
 import java.util.Objects;
@@ -40,38 +45,40 @@
     static sealed class FieldInstanceReadOnly extends VarHandle {
         final long fieldOffset;
         final Class<?> receiverType;
 #if[Object]
         final Class<?> fieldType;
+        final CheckedType checkedFieldType;
 #end[Object]
 
-        FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.FORM, false);
+        FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType}) {
+            this(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, FieldInstanceReadOnly.FORM, false);
         }
 
-        protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
+        protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType},
                                         VarForm form, boolean exact) {
             super(form, exact);
             this.fieldOffset = fieldOffset;
             this.receiverType = receiverType;
 #if[Object]
             this.fieldType = fieldType;
+            this.checkedFieldType = checkedFieldType;
 #end[Object]
         }
 
         @Override
         public FieldInstanceReadOnly withInvokeExactBehavior() {
             return hasInvokeExactBehavior()
                 ? this
-                : new FieldInstanceReadOnly(receiverType, fieldOffset{#if[Object]?, fieldType}, vform, true);
+                : new FieldInstanceReadOnly(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, vform, true);
         }
 
         @Override
         public FieldInstanceReadOnly withInvokeBehavior() {
             return !hasInvokeExactBehavior()
                 ? this
-                : new FieldInstanceReadOnly(receiverType, fieldOffset{#if[Object]?, fieldType}, vform, false);
+                : new FieldInstanceReadOnly(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, vform, false);
         }
 
         @Override
         final MethodType accessModeTypeUncached(AccessType at) {
             return at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class});
@@ -91,190 +98,220 @@
         }
 
         @ForceInline
         static $type$ get(VarHandle ob, Object holder) {
             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
-            return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         @ForceInline
         static $type$ getVolatile(VarHandle ob, Object holder) {
             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
-            return UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         @ForceInline
         static $type$ getOpaque(VarHandle ob, Object holder) {
             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
-            return UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         @ForceInline
         static $type$ getAcquire(VarHandle ob, Object holder) {
             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
-            return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, $type$.class);
     }
 
     static final class FieldInstanceReadWrite extends FieldInstanceReadOnly {
-
-        FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(receiverType, fieldOffset{#if[Object]?, fieldType}, false);
+        FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType}) {
+            this(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, false);
         }
 
-        private FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
+        private FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType},
                                        boolean exact) {
-            super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.FORM, exact);
+            super(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, FieldInstanceReadWrite.FORM, exact);
         }
 
         @Override
         public FieldInstanceReadWrite withInvokeExactBehavior() {
             return hasInvokeExactBehavior()
                 ? this
-                : new FieldInstanceReadWrite(receiverType, fieldOffset{#if[Object]?, fieldType}, true);
+                : new FieldInstanceReadWrite(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, true);
         }
 
         @Override
         public FieldInstanceReadWrite withInvokeBehavior() {
             return !hasInvokeExactBehavior()
                 ? this
-                : new FieldInstanceReadWrite(receiverType, fieldOffset{#if[Object]?, fieldType}, false);
+                : new FieldInstanceReadWrite(receiverType, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, false);
+        }
+
+#if[Object]
+        @ForceInline
+        static Object checkCast(FieldInstanceReadWrite handle, $type$ value) {
+            return handle.checkedFieldType.cast(value);
         }
+#end[Object]
 
         @ForceInline
         static void set(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             UNSAFE.put$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                             handle.fieldOffset,
-                             {#if[Object]?handle.fieldType.cast(value):value});
+                             handle.fieldOffset{#if[Value]?, handle.fieldType},
+                             {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static void setVolatile(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             UNSAFE.put$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                     handle.fieldOffset,
-                                     {#if[Object]?handle.fieldType.cast(value):value});
+                                     handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                     {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static void setOpaque(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             UNSAFE.put$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                   handle.fieldOffset,
-                                   {#if[Object]?handle.fieldType.cast(value):value});
+                                   handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                   {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static void setRelease(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             UNSAFE.put$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                    handle.fieldOffset,
-                                    {#if[Object]?handle.fieldType.cast(value):value});
+                                    handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                    {#if[Object]?checkCast(handle, value):value});
         }
 #if[CAS]
 
         @ForceInline
         static boolean compareAndSet(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.compareAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ compareAndExchange(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.compareAndExchange$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ compareAndExchangeAcquire(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ compareAndExchangeRelease(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSetPlain(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.weakCompareAndSet$Type$Plain(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSet(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.weakCompareAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSetAcquire(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.weakCompareAndSet$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSetRelease(VarHandle ob, Object holder, $type$ expected, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.weakCompareAndSet$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ getAndSet(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.getAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                          handle.fieldOffset,
-                                          {#if[Object]?handle.fieldType.cast(value):value});
+                                          handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                          {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ getAndSetAcquire(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.getAndSet$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                          handle.fieldOffset,
-                                          {#if[Object]?handle.fieldType.cast(value):value});
+                                          handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                          {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ getAndSetRelease(VarHandle ob, Object holder, $type$ value) {
             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
             return UNSAFE.getAndSet$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
-                                          handle.fieldOffset,
-                                          {#if[Object]?handle.fieldType.cast(value):value});
+                                          handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                          {#if[Object]?checkCast(handle, value):value});
         }
 #end[CAS]
 #if[AtomicAdd]
 
         @ForceInline
@@ -385,39 +422,41 @@
         final Class<?> declaringClass;
         final Object base;
         final long fieldOffset;
 #if[Object]
         final Class<?> fieldType;
+        final CheckedType checkedFieldType;
 #end[Object]
 
-        FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false);
+        FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType}) {
+            this(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, FieldStaticReadOnly.FORM, false);
         }
 
-        protected FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
+        protected FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType},
                                       VarForm form, boolean exact) {
             super(form, exact);
             this.declaringClass = declaringClass;
             this.base = base;
             this.fieldOffset = fieldOffset;
 #if[Object]
             this.fieldType = fieldType;
+            this.checkedFieldType = checkedFieldType;
 #end[Object]
         }
 
         @Override
         public FieldStaticReadOnly withInvokeExactBehavior() {
             return hasInvokeExactBehavior()
                 ? this
-                : new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, vform, true);
+                : new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, vform, true);
         }
 
         @Override
         public FieldStaticReadOnly withInvokeBehavior() {
             return !hasInvokeExactBehavior()
                 ? this
-                : new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, vform, false);
+                : new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, vform, false);
         }
 
         @Override
         public Optional<VarHandleDesc> describeConstable() {
             var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
@@ -439,191 +478,222 @@
         }
 
         @ForceInline
         static $type$ get(VarHandle ob) {
             FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
-            return UNSAFE.get$Type$(handle.base,
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$(handle.base,
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         @ForceInline
         static $type$ getVolatile(VarHandle ob) {
             FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
-            return UNSAFE.get$Type$Volatile(handle.base,
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$Volatile(handle.base,
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         @ForceInline
         static $type$ getOpaque(VarHandle ob) {
             FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
-            return UNSAFE.get$Type$Opaque(handle.base,
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$Opaque(handle.base,
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         @ForceInline
         static $type$ getAcquire(VarHandle ob) {
             FieldStaticReadOnly handle = (FieldStaticReadOnly) ob.target();
-            return UNSAFE.get$Type$Acquire(handle.base,
-                                 handle.fieldOffset);
+            $type$ value = UNSAFE.get$Type$Acquire(handle.base,
+                                 handle.fieldOffset{#if[Value]?, handle.fieldType});
+#if[Object]
+            if (value == null && handle.checkedFieldType instanceof NullRestrictedCheckedType) {
+                return ValueClass.zeroInstance(handle.fieldType);
+            }
+#end[Object]
+            return value;
         }
 
         static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, $type$.class);
     }
 
     static final class FieldStaticReadWrite extends FieldStaticReadOnly {
 
-        FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, false);
+        FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType}) {
+            this(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, false);
         }
 
-        private FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
+        private FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType, CheckedType checkedFieldType},
                                      boolean exact) {
-            super(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact);
+            super(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, FieldStaticReadWrite.FORM, exact);
         }
 
         @Override
         public FieldStaticReadWrite withInvokeExactBehavior() {
             return hasInvokeExactBehavior()
                 ? this
-                : new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, true);
+                : new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, true);
         }
 
         @Override
         public FieldStaticReadWrite withInvokeBehavior() {
             return !hasInvokeExactBehavior()
                 ? this
-                : new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, false);
+                : new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType, checkedFieldType}, false);
+        }
+
+#if[Object]
+        @ForceInline
+        static Object checkCast(FieldStaticReadWrite handle, $type$ value) {
+            return handle.checkedFieldType.cast(value);
         }
+#end[Object]
 
         @ForceInline
         static void set(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             UNSAFE.put$Type$(handle.base,
-                             handle.fieldOffset,
-                             {#if[Object]?handle.fieldType.cast(value):value});
+                             handle.fieldOffset{#if[Value]?, handle.fieldType},
+                             {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static void setVolatile(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             UNSAFE.put$Type$Volatile(handle.base,
-                                     handle.fieldOffset,
-                                     {#if[Object]?handle.fieldType.cast(value):value});
+                                     handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                     {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static void setOpaque(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             UNSAFE.put$Type$Opaque(handle.base,
-                                   handle.fieldOffset,
-                                   {#if[Object]?handle.fieldType.cast(value):value});
+                                   handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                   {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static void setRelease(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             UNSAFE.put$Type$Release(handle.base,
-                                    handle.fieldOffset,
-                                    {#if[Object]?handle.fieldType.cast(value):value});
+                                    handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                    {#if[Object]?checkCast(handle, value):value});
         }
 #if[CAS]
 
         @ForceInline
         static boolean compareAndSet(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.compareAndSet$Type$(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
 
         @ForceInline
         static $type$ compareAndExchange(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.compareAndExchange$Type$(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ compareAndExchangeAcquire(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ compareAndExchangeRelease(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.compareAndExchange$Type$Release(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSetPlain(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.weakCompareAndSet$Type$Plain(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSet(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.weakCompareAndSet$Type$(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSetAcquire(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.weakCompareAndSet$Type$Acquire(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static boolean weakCompareAndSetRelease(VarHandle ob, $type$ expected, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.weakCompareAndSet$Type$Release(handle.base,
-                                               handle.fieldOffset,
-                                               {#if[Object]?handle.fieldType.cast(expected):expected},
-                                               {#if[Object]?handle.fieldType.cast(value):value});
+                                               handle.fieldOffset{#if[Object]?, handle.fieldType},
+                                               {#if[Object]?checkCast(handle, expected):expected},
+                                               {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ getAndSet(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.getAndSet$Type$(handle.base,
-                                          handle.fieldOffset,
-                                          {#if[Object]?handle.fieldType.cast(value):value});
+                                          handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                          {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ getAndSetAcquire(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.getAndSet$Type$Acquire(handle.base,
-                                          handle.fieldOffset,
-                                          {#if[Object]?handle.fieldType.cast(value):value});
+                                          handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                          {#if[Object]?checkCast(handle, value):value});
         }
 
         @ForceInline
         static $type$ getAndSetRelease(VarHandle ob, $type$ value) {
             FieldStaticReadWrite handle = (FieldStaticReadWrite) ob.target();
             return UNSAFE.getAndSet$Type$Release(handle.base,
-                                          handle.fieldOffset,
-                                          {#if[Object]?handle.fieldType.cast(value):value});
+                                          handle.fieldOffset{#if[Value]?, handle.fieldType},
+                                          {#if[Object]?checkCast(handle, value):value});
         }
 #end[CAS]
 #if[AtomicAdd]
 
         @ForceInline
@@ -726,11 +796,10 @@
 #end[Bitwise]
 
         static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, $type$.class);
     }
 
-
     static final class Array extends VarHandle {
         final int abase;
         final int ashift;
 #if[Object]
         final Class<{#if[Object]??:$type$[]}> arrayType;
@@ -774,29 +843,29 @@
             return Optional.of(VarHandleDesc.ofArray(arrayTypeRef.get()));
         }
 
         @Override
         final MethodType accessModeTypeUncached(AccessType at) {
-            return at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+            return at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?componentType:$type$.class}, int.class);
         }
 
 #if[Object]
         @ForceInline
         static Object runtimeTypeCheck(Array handle, Object[] oarray, Object value) {
             if (handle.arrayType == oarray.getClass()) {
                 // Fast path: static array type same as argument array type
-                return handle.componentType.cast(value);
+                return {#if[Value]?ValueClass.componentCheckedType(oarray):handle.componentType}.cast(value);
             } else {
-                // Slow path: check value against argument array component type
+                // Slow path: check value against argument array component checked type
                 return reflectiveTypeCheck(oarray, value);
             }
         }
 
         @ForceInline
         static Object reflectiveTypeCheck(Object[] oarray, Object value) {
             try {
-                return oarray.getClass().getComponentType().cast(value);
+                return ValueClass.componentCheckedType(oarray).cast(value);
             } catch (ClassCastException e) {
                 throw new ArrayStoreException();
             }
         }
 #end[Object]
@@ -818,35 +887,61 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
-            array[index] = {#if[Object]?handle.componentType.cast(value):value};
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                vh.set(oarray, index, value);
+                return;
+            }
+#end[Reference]
+            array[index] = {#if[Object]?runtimeTypeCheck(handle, array, value):value};
         }
 
         @ForceInline
         static $type$ getVolatile(VarHandle ob, Object oarray, int index) {
             Array handle = (Array)ob;
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.getVolatile(oarray, index);
+            }
+#end[Reference]
             return UNSAFE.get$Type$Volatile(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase);
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType});
         }
 
         @ForceInline
         static void setVolatile(VarHandle ob, Object oarray, int index, $type$ value) {
             Array handle = (Array)ob;
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                vh.setVolatile(oarray, index, value);
+                return;
+            }
+#end[Reference]
             UNSAFE.put$Type$Volatile(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
         static $type$ getOpaque(VarHandle ob, Object oarray, int index) {
@@ -854,24 +949,41 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.getOpaque(oarray, index);
+            }
+#end[Reference]
             return UNSAFE.get$Type$Opaque(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase);
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType});
         }
 
         @ForceInline
         static void setOpaque(VarHandle ob, Object oarray, int index, $type$ value) {
             Array handle = (Array)ob;
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                vh.setOpaque(oarray, index, value);
+                return;
+            }
+#end[Reference]
             UNSAFE.put$Type$Opaque(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
         static $type$ getAcquire(VarHandle ob, Object oarray, int index) {
@@ -879,24 +991,41 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.getAcquire(oarray, index);
+            }
+#end[Reference]
             return UNSAFE.get$Type$Acquire(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase);
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType});
         }
 
         @ForceInline
         static void setRelease(VarHandle ob, Object oarray, int index, $type$ value) {
             Array handle = (Array)ob;
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                vh.setRelease(oarray, index, value);
+                return;
+            }
+#end[Reference]
             UNSAFE.put$Type$Release(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 #if[CAS]
 
         @ForceInline
@@ -905,12 +1034,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.compareAndSet(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.compareAndSet$Type$(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -919,12 +1056,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.compareAndExchange(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.compareAndExchange$Type$(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -933,12 +1078,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.compareAndExchangeAcquire(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.compareAndExchange$Type$Acquire(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -947,12 +1100,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.compareAndExchangeRelease(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.compareAndExchange$Type$Release(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -961,12 +1122,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.weakCompareAndSetPlain(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.weakCompareAndSet$Type$Plain(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -975,12 +1144,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.weakCompareAndSet(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.weakCompareAndSet$Type$(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -989,12 +1166,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.weakCompareAndSetAcquire(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.weakCompareAndSet$Type$Acquire(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -1003,12 +1188,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.weakCompareAndSetRelease(oarray, index, expected, value);
+            }
+#end[Reference]
             return UNSAFE.weakCompareAndSet$Type$Release(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
                     {#if[Object]?handle.componentType.cast(expected):expected},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
@@ -1017,12 +1210,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.getAndSet(oarray, index, value);
+            }
+#end[Reference]
             return UNSAFE.getAndSet$Type$(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
         static $type$ getAndSetAcquire(VarHandle ob, Object oarray, int index, $type$ value) {
@@ -1030,12 +1231,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.getAndSetAcquire(oarray, index, value);
+            }
+#end[Reference]
             return UNSAFE.getAndSet$Type$Acquire(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 
         @ForceInline
         static $type$ getAndSetRelease(VarHandle ob, Object oarray, int index, $type$ value) {
@@ -1043,12 +1252,20 @@
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 #else[Object]
             $type$[] array = ($type$[]) oarray;
 #end[Object]
+#if[Reference]
+            Class<?> arrayType = oarray.getClass();
+            if (handle.arrayType != arrayType && UNSAFE.isFlatArray(arrayType)) {
+                // delegate to VarHandle of flat array
+                VarHandle vh = VarHandleValues.flatArrayVarHandle(arrayType);
+                return vh.getAndSetRelease(oarray, index, value);
+            }
+#end[Reference]
             return UNSAFE.getAndSet$Type$Release(array,
-                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
+                    (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
         }
 #end[CAS]
 #if[AtomicAdd]
 
@@ -1160,9 +1377,22 @@
             return UNSAFE.getAndBitwiseXor$Type$Acquire(array,
                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
                                        value);
         }
 #end[Bitwise]
-
         static final VarForm FORM = new VarForm(Array.class, {#if[Object]?Object[].class:$type$[].class}, {#if[Object]?Object.class:$type$.class}, int.class);
     }
+#if[Value]
+    static final ClassValue<Array> flatArrayVarHandles = new ClassValue<>() {
+        @Override protected Array computeValue(Class<?> arrayClass) {
+            assert UNSAFE.isFlatArray(arrayClass);
+            int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
+            int ascale = UNSAFE.arrayIndexScale(arrayClass);
+            int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
+            return new Array(aoffset, ashift, arrayClass);
+        }
+    };
+    static VarHandle flatArrayVarHandle(Class<?> arrayClass) {
+        return flatArrayVarHandles.get(arrayClass);
+    }
+#end[Value]
 }
