8155258: VarHandle implementation improvements
authorpsandoz
Thu, 05 May 2016 11:39:08 -0700
changeset 37792 dd626e6f5967
parent 37791 ae33107fd8b3
child 37793 41844efbbcce
8155258: VarHandle implementation improvements Reviewed-by: shade, vlivanov
jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java
jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java
jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java
jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java
jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template
jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu May 05 11:39:08 2016 -0700
@@ -33,8 +33,6 @@
 import sun.invoke.util.Wrapper;
 
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Objects;
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Thu May 05 11:39:08 2016 -0700
@@ -396,7 +396,7 @@
         LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)),
                                           ARG_LIMIT + 1, names);
 
-        lform.prepare();
+        lform.compileToBytecode();
         return lform;
     }
 
@@ -448,7 +448,7 @@
         LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)),
                                           ARG_LIMIT, names);
 
-        lform.prepare();
+        lform.compileToBytecode();
         return lform;
     }
 
@@ -497,44 +497,33 @@
 
     /*non-public*/ static
     @ForceInline
-    MethodHandle checkVarHandleGenericType(VarHandle vh, VarHandle.AccessDescriptor vad) {
-        MethodType expected = vad.symbolicMethodType;
-        MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
-
-        MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
-        if (mn == null)
-            throw vh.unsupported();
-        // TODO the following MH is not constant, cache in stable field array
-        // on VarForm?
-        MethodHandle mh = DirectMethodHandle.make(mn);
-        if (actual == expected) {
+    MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        // Test for exact match on invoker types
+        // TODO match with erased types and add cast of return value to lambda form
+        MethodHandle mh = handle.getMethodHandle(ad.mode);
+        if (mh.type() == ad.symbolicMethodTypeInvoker) {
             return mh;
         }
         else {
-            // Adapt to the actual (which should never fail since mh's method
-            // type is in the basic form), then to the expected (which my fail
-            // if the symbolic type descriptor does not match)
-            // TODO optimize for the case of actual.erased() == expected.erased()
-            return mh.asType(actual.insertParameterTypes(0, VarHandle.class)).
-                    asType(expected.insertParameterTypes(0, VarHandle.class));
+            return mh.asType(ad.symbolicMethodTypeInvoker);
         }
     }
 
     /*non-public*/ static
     @ForceInline
-    void checkVarHandleExactType(VarHandle vh, VarHandle.AccessDescriptor vad) {
-        MethodType expected = vad.symbolicMethodType;
-        MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
-        if (actual != expected)
-            throw newWrongMethodTypeException(expected, actual);
+    void checkVarHandleExactType(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        MethodType erasedTarget = handle.vform.methodType_table[ad.type];
+        MethodType erasedSymbolic = ad.symbolicMethodTypeErased;
+        if (erasedTarget != erasedSymbolic)
+            throw newWrongMethodTypeException(erasedTarget, erasedSymbolic);
     }
 
     /*non-public*/ static
     @ForceInline
-    MemberName getVarHandleMemberName(VarHandle vh, VarHandle.AccessDescriptor vad) {
-        MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
+    MemberName getVarHandleMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
+        MemberName mn = handle.vform.memberName_table[ad.mode];
         if (mn == null) {
-            throw vh.unsupported();
+            throw handle.unsupported();
         }
         return mn;
     }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu May 05 11:39:08 2016 -0700
@@ -430,14 +430,14 @@
 
         // If not polymorphic in the return type, such as the compareAndSet
         // methods that return boolean
-        if (ak.isPolyMorphicInReturnType) {
-            if (ak.returnType != mtype.returnType()) {
+        if (ak.at.isMonomorphicInReturnType) {
+            if (ak.at.returnType != mtype.returnType()) {
                 // The caller contains a different return type than that
                 // defined by the method
                 throw newNoSuchMethodErrorOnVarHandle(name, mtype);
             }
             // Adjust the return type of the signature method type
-            sigType = sigType.changeReturnType(ak.returnType);
+            sigType = sigType.changeReturnType(ak.at.returnType);
         }
 
         // Get the guard method type for linking
@@ -455,26 +455,25 @@
             MemberName linker = new MemberName(
                     VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType),
                     guardType, REF_invokeStatic);
-            try {
-                return MemberName.getFactory().resolveOrFail(
-                        REF_invokeStatic, linker, VarHandleGuards.class, ReflectiveOperationException.class);
-            } catch (ReflectiveOperationException ex) {
-                // Fall back to lambda form linkage if guard method is not available
-                // TODO Optionally log fallback ?
+
+            linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
+                                                           VarHandleGuards.class);
+            if (linker != null) {
+                return linker;
             }
+            // Fall back to lambda form linkage if guard method is not available
+            // TODO Optionally log fallback ?
         }
         return Invokers.varHandleInvokeLinkerMethod(name, mtype);
     }
     static String getVarHandleMethodSignature(MethodType mt) {
-        StringBuilder sb = new StringBuilder(mt.parameterCount() + 1);
+        StringBuilder sb = new StringBuilder(mt.parameterCount() + 2);
 
         for (int i = 0; i < mt.parameterCount(); i++) {
             Class<?> pt = mt.parameterType(i);
             sb.append(getCharType(pt));
         }
-
         sb.append('_').append(getCharType(mt.returnType()));
-
         return sb.toString();
     }
     static char getCharType(Class<?> pt) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Thu May 05 11:39:08 2016 -0700
@@ -24,42 +24,102 @@
  */
 package java.lang.invoke;
 
+import jdk.internal.vm.annotation.ForceInline;
 import jdk.internal.vm.annotation.Stable;
 
 import java.lang.invoke.VarHandle.AccessMode;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * A var handle form containing a set of member name, one for each operation.
  * Each member characterizes a static method.
  */
-class VarForm {
+final class VarForm {
+
+    final @Stable MethodType[] methodType_table;
+
+    final @Stable MemberName[] memberName_table;
+
+    VarForm(Class<?> implClass, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
+        this.methodType_table = new MethodType[VarHandle.AccessType.values().length];
+
+        // TODO lazily calculate
+        this.memberName_table = linkFromStatic(implClass);
+
+        // (Receiver, <Intermediates>)
+        List<Class<?>> l = new ArrayList<>();
+        if (receiver != null)
+            l.add(receiver);
+        l.addAll(Arrays.asList(intermediate));
 
-    // Holds VarForm for VarHandle implementation classes
-    private static final ClassValue<VarForm> VFORMS
-            = new ClassValue<>() {
-        @Override
-        protected VarForm computeValue(Class<?> impl) {
-            return new VarForm(linkFromStatic(impl));
-        }
-    };
+        // (Receiver, <Intermediates>)Value
+        methodType_table[VarHandle.AccessType.GET.ordinal()] =
+                MethodType.methodType(value, l).erase();
+
+        // (Receiver, <Intermediates>, Value)void
+        l.add(value);
+        methodType_table[VarHandle.AccessType.SET.ordinal()] =
+                MethodType.methodType(void.class, l).erase();
 
-    final @Stable MemberName[] table;
+        // (Receiver, <Intermediates>, Value)Value
+        methodType_table[VarHandle.AccessType.GET_AND_UPDATE.ordinal()] =
+                MethodType.methodType(value, l).erase();
 
-    VarForm(MemberName[] table) {
-        this.table = table;
+        // (Receiver, <Intermediates>, Value, Value)boolean
+        l.add(value);
+        methodType_table[VarHandle.AccessType.COMPARE_AND_SWAP.ordinal()] =
+                MethodType.methodType(boolean.class, l).erase();
+
+        // (Receiver, <Intermediates>, Value, Value)Value
+        methodType_table[VarHandle.AccessType.COMPARE_AND_EXCHANGE.ordinal()] =
+                MethodType.methodType(value, l).erase();
     }
 
-    /**
-     * Creates a var form given an VarHandle implementation class.
-     * Each signature polymorphic method is linked to a static method of the
-     * same name on the implementation class or a super class.
-     */
-    static VarForm createFromStatic(Class<? extends VarHandle> impl) {
-        return VFORMS.get(impl);
+    @ForceInline
+    final MethodType getMethodType(int type) {
+        return methodType_table[type];
+    }
+
+    @ForceInline
+    final MemberName getMemberName(int mode) {
+        // TODO calculate lazily
+        MemberName mn = memberName_table[mode];
+        if (mn == null) {
+            throw new UnsupportedOperationException();
+        }
+        return mn;
     }
 
+
+    @Stable
+    MethodType[] methodType_V_table;
+
+    @ForceInline
+    final MethodType[] getMethodType_V_init() {
+        MethodType[] table = new MethodType[VarHandle.AccessType.values().length];
+        for (int i = 0; i < methodType_table.length; i++) {
+            MethodType mt = methodType_table[i];
+            // TODO only adjust for sig-poly methods returning Object
+            table[i] = mt.changeReturnType(void.class);
+        }
+        methodType_V_table = table;
+        return table;
+    }
+
+    @ForceInline
+    final MethodType getMethodType_V(int type) {
+        MethodType[] table = methodType_V_table;
+        if (table == null) {
+            table = getMethodType_V_init();
+        }
+        return table[type];
+    }
+
+
     /**
      * Link all signature polymorphic methods.
      */
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu May 05 11:39:08 2016 -0700
@@ -27,10 +27,9 @@
 
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.vm.annotation.ForceInline;
+import jdk.internal.vm.annotation.Stable;
 
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -406,42 +405,10 @@
  * @since 9
  */
 public abstract class VarHandle {
-    // Use explicit final fields rather than an @Stable array as
-    // this can reduce the memory per handle
-    // e.g. by 24 bytes on 64 bit architectures
-    final MethodType typeGet;
-    final MethodType typeSet;
-    final MethodType typeCompareSwap;
-    final MethodType typeCompareExchange;
-    final MethodType typeGetAndUpdate;
-
     final VarForm vform;
 
-    VarHandle(VarForm vform, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
+    VarHandle(VarForm vform) {
         this.vform = vform;
-
-        // (Receiver, <Intermediates>)
-        List<Class<?>> l = new ArrayList<>();
-        if (receiver != null)
-            l.add(receiver);
-        l.addAll(Arrays.asList(intermediate));
-
-        // (Receiver, <Intermediates>)Value
-        this.typeGet = MethodType.methodType(value, l);
-
-        // (Receiver, <Intermediates>, Value)void
-        l.add(value);
-        this.typeSet = MethodType.methodType(void.class, l);
-
-        // (Receiver, <Intermediates>, Value)Value
-        this.typeGetAndUpdate = MethodType.methodType(value, l);
-
-        // (Receiver, <Intermediates>, Value, Value)boolean
-        l.add(value);
-        this.typeCompareSwap = MethodType.methodType(boolean.class, l);
-
-        // (Receiver, <Intermediates>, Value, Value)Value
-        this.typeCompareExchange = MethodType.methodType(value, l);
     }
 
     RuntimeException unsupported() {
@@ -1090,36 +1057,83 @@
     Object addAndGet(Object... args);
 
     enum AccessType {
-        GET,                    // 0
-        SET,                    // 1
-        COMPARE_AND_SWAP,       // 2
-        COMPARE_AND_EXCHANGE,   // 3
-        GET_AND_UPDATE;         // 4
+        GET(Object.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(0, receiver, intermediate);
+                fillParameters(ps, receiver, intermediate);
+                return MethodType.methodType(value, ps);
+            }
+        },
+        SET(void.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i] = value;
+                return MethodType.methodType(void.class, ps);
+            }
+        },
+        COMPARE_AND_SWAP(boolean.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i++] = value;
+                ps[i] = value;
+                return MethodType.methodType(boolean.class, ps);
+            }
+        },
+        COMPARE_AND_EXCHANGE(Object.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i++] = value;
+                ps[i] = value;
+                return MethodType.methodType(value, ps);
+            }
+        },
+        GET_AND_UPDATE(Object.class) {
+            @Override
+            MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                      Class<?>... intermediate) {
+                Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
+                int i = fillParameters(ps, receiver, intermediate);
+                ps[i] = value;
+                return MethodType.methodType(value, ps);
+            }
+        };
 
-        MethodType getMethodType(VarHandle vh) {
-            return getMethodType(this.ordinal(), vh);
+        final Class<?> returnType;
+        final boolean isMonomorphicInReturnType;
+
+        AccessType(Class<?> returnType) {
+            this.returnType = returnType;
+            isMonomorphicInReturnType = returnType != Object.class;
         }
 
-        @ForceInline
-        static MethodType getMethodType(int ordinal, VarHandle vh) {
-            if (ordinal == 0) {
-                return vh.typeGet;
-            }
-            else if (ordinal == 1) {
-                return vh.typeSet;
-            }
-            else if (ordinal == 2) {
-                return vh.typeCompareSwap;
-            }
-            else if (ordinal == 3) {
-                return vh.typeCompareExchange;
-            }
-            else if (ordinal == 4) {
-                return vh.typeGetAndUpdate;
-            }
-            else {
-                throw new IllegalStateException("Illegal access type: " + ordinal);
-            }
+        abstract MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                           Class<?>... intermediate);
+
+        private static Class<?>[] allocateParameters(int values,
+                                                     Class<?> receiver, Class<?>... intermediate) {
+            int size = ((receiver != null) ? 1 : 0) + intermediate.length + values;
+            return new Class<?>[size];
+        }
+
+        private static int fillParameters(Class<?>[] ps,
+                                          Class<?> receiver, Class<?>... intermediate) {
+            int i = 0;
+            if (receiver != null)
+                ps[i++] = receiver;
+            for (int j = 0; j < intermediate.length; j++)
+                ps[i++] = intermediate[j];
+            return i;
         }
     }
 
@@ -1133,115 +1147,115 @@
          * method
          * {@link VarHandle#get VarHandle.get}
          */
-        GET("get", AccessType.GET, Object.class),
+        GET("get", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#set VarHandle.set}
          */
-        SET("set", AccessType.SET, void.class),
+        SET("set", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getVolatile VarHandle.getVolatile}
          */
-        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
+        GET_VOLATILE("getVolatile", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setVolatile VarHandle.setVolatile}
          */
-        SET_VOLATILE("setVolatile", AccessType.SET, void.class),
+        SET_VOLATILE("setVolatile", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAcquire VarHandle.getAcquire}
          */
-        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
+        GET_ACQUIRE("getAcquire", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setRelease VarHandle.setRelease}
          */
-        SET_RELEASE("setRelease", AccessType.SET, void.class),
+        SET_RELEASE("setRelease", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getOpaque VarHandle.getOpaque}
          */
-        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
+        GET_OPAQUE("getOpaque", AccessType.GET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setOpaque VarHandle.setOpaque}
          */
-        SET_OPAQUE("setOpaque", AccessType.SET, void.class),
+        SET_OPAQUE("setOpaque", AccessType.SET),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
          */
-        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
          */
-        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
+        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
          */
-        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
          */
-        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
          */
-        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
          */
-        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
          */
-        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
          */
-        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndSet VarHandle.getAndSet}
          */
-        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
          */
-        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#addAndGet VarHandle.addAndGet}
          */
-        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
+        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE),
         ;
 
         static final Map<String, AccessMode> methodNameToAccessMode;
@@ -1256,10 +1270,8 @@
 
         final String methodName;
         final AccessType at;
-        final boolean isPolyMorphicInReturnType;
-        final Class<?> returnType;
 
-        AccessMode(final String methodName, AccessType at, Class<?> returnType) {
+        AccessMode(final String methodName, AccessType at) {
             this.methodName = methodName;
             this.at = at;
 
@@ -1267,10 +1279,7 @@
             assert methodName.equals(toMethodName(name()));
             // Assert that return type is correct
             // Otherwise, when disabled avoid using reflection
-            assert returnType == getReturnType(methodName);
-
-            this.returnType = returnType;
-            isPolyMorphicInReturnType = returnType != Object.class;
+            assert at.returnType == getReturnType(methodName);
         }
 
         /**
@@ -1324,17 +1333,21 @@
 
         @ForceInline
         static MemberName getMemberName(int ordinal, VarForm vform) {
-            return vform.table[ordinal];
+            return vform.memberName_table[ordinal];
         }
     }
 
     static final class AccessDescriptor {
-        final MethodType symbolicMethodType;
+        final MethodType symbolicMethodTypeErased;
+        final MethodType symbolicMethodTypeInvoker;
+        final Class<?> returnType;
         final int type;
         final int mode;
 
         public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
-            this.symbolicMethodType = symbolicMethodType;
+            this.symbolicMethodTypeErased = symbolicMethodType.erase();
+            this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class);
+            this.returnType = symbolicMethodType.returnType();
             this.type = type;
             this.mode = mode;
         }
@@ -1346,6 +1359,7 @@
      * @return the variable type of variables referenced by this VarHandle
      */
     public final Class<?> varType() {
+        MethodType typeSet = accessModeType(AccessMode.SET);
         return typeSet.parameterType(typeSet.parameterCount() - 1);
     }
 
@@ -1356,6 +1370,7 @@
      * list is unmodifiable
      */
     public final List<Class<?>> coordinateTypes() {
+        MethodType typeGet = accessModeType(AccessMode.GET);
         return typeGet.parameterList();
     }
 
@@ -1374,9 +1389,15 @@
      * @return the access mode type for the given access mode
      */
     public final MethodType accessModeType(AccessMode accessMode) {
-        return accessMode.at.getMethodType(this);
+        TypesAndInvokers tis = getTypesAndInvokers();
+        MethodType mt = tis.methodType_table[accessMode.at.ordinal()];
+        if (mt == null) {
+            mt = tis.methodType_table[accessMode.at.ordinal()] =
+                    accessModeTypeUncached(accessMode);
+        }
+        return mt;
     }
-
+    abstract MethodType accessModeTypeUncached(AccessMode accessMode);
 
     /**
      * Returns {@code true} if the given access mode is supported, otherwise
@@ -1417,9 +1438,8 @@
     public final MethodHandle toMethodHandle(AccessMode accessMode) {
         MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
         if (mn != null) {
-            return DirectMethodHandle.make(mn).
-                    bindTo(this).
-                    asType(accessMode.at.getMethodType(this));
+            MethodHandle mh = getMethodHandle(accessMode.ordinal());
+            return mh.bindTo(this);
         }
         else {
             // Ensure an UnsupportedOperationException is thrown
@@ -1428,6 +1448,51 @@
         }
     }
 
+    @Stable
+    TypesAndInvokers typesAndInvokers;
+
+    static class TypesAndInvokers {
+        final @Stable
+        MethodType[] methodType_table =
+                new MethodType[VarHandle.AccessType.values().length];
+
+        final @Stable
+        MethodHandle[] methodHandle_table =
+                new MethodHandle[AccessMode.values().length];
+    }
+
+    @ForceInline
+    private final TypesAndInvokers getTypesAndInvokers() {
+        TypesAndInvokers tis = typesAndInvokers;
+        if (tis == null) {
+            tis = typesAndInvokers = new TypesAndInvokers();
+        }
+        return tis;
+    }
+
+    @ForceInline
+    final MethodHandle getMethodHandle(int mode) {
+        TypesAndInvokers tis = getTypesAndInvokers();
+        MethodHandle mh = tis.methodHandle_table[mode];
+        if (mh == null) {
+            mh = tis.methodHandle_table[mode] = getMethodHandleUncached(tis, mode);
+        }
+        return mh;
+    }
+    private final MethodHandle getMethodHandleUncached(TypesAndInvokers tis, int mode) {
+        MethodType mt = accessModeType(AccessMode.values()[mode]).
+                insertParameterTypes(0, VarHandle.class);
+        MemberName mn = vform.getMemberName(mode);
+        DirectMethodHandle dmh = DirectMethodHandle.make(mn);
+        // Such a method handle must not be publically exposed directly
+        // otherwise it can be cracked, it must be transformed or rebound
+        // before exposure
+        MethodHandle mh = dmh.copyWith(mt, dmh.form);
+        assert mh.type().erase() == mn.getMethodType().erase();
+        return mh;
+    }
+
+
     /*non-public*/
     final void updateVarForm(VarForm newVForm) {
         if (vform == newVForm) return;
@@ -1453,6 +1518,10 @@
         catch (ReflectiveOperationException e) {
             throw newInternalError(e);
         }
+
+        // The VarHandleGuards must be initialized to ensure correct
+        // compilation of the guard methods
+        UNSAFE.ensureClassInitialized(VarHandleGuards.class);
     }
 
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java	Thu May 05 11:39:08 2016 -0700
@@ -30,1361 +30,1008 @@
 final class VarHandleGuards {
 
     @ForceInline
-    final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
-        MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);
-        if (mn == null) {
-            throw handle.unsupported();
-        }
-        return mn;
-    }
-
-    @ForceInline
     @LambdaForm.Compiled
     final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-            return symbolic.returnType().cast(r);
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
+            return ad.returnType.cast(r);
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (float) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (double) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (int) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
-        else if (target.erase() == symbolic.erase()) {
-            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+        else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
+            MethodHandle.linkToStatic(handle, arg0, arg1, arg2, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (boolean) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
     @ForceInline
     @LambdaForm.Compiled
     final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
-        MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
-        MethodType symbolic = ad.symbolicMethodType;
-        if (target == symbolic) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
-        }
-        else if (target.erase() == symbolic.erase()) {
-            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+        if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
+            return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, handle.vform.getMemberName(ad.mode));
         }
         else {
-            MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
-            return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+            MethodHandle mh = handle.getMethodHandle(ad.mode);
+            return (long) mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(handle, arg0, arg1, arg2, arg3);
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu May 05 11:39:08 2016 -0700
@@ -280,28 +280,29 @@
 //                "@ForceInline\n" +
 //                "@LambdaForm.Compiled\n" +
 //                "final static <METHOD> throws Throwable {\n" +
-//                "    MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);\n" +
-//                "    MethodType symbolic = ad.symbolicMethodType;\n" +
-//                "    if (target == symbolic) {\n" +
-//                "        <RETURN>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
-//                "    }\n" +
-//                "    else if (target.erase() == symbolic.erase()) {\n" +
+//                "    if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodType) {\n" +
 //                "        <RESULT_ERASED>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);<RETURN_ERASED>\n" +
 //                "    }\n" +
 //                "    else {\n" +
-//                "        MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);\n" +
-//                "        <RETURN>vh_invoker.invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
+//                "        MethodHandle mh = handle.getMethodHandle(ad.mode);\n" +
+//                "        <RETURN>mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
 //                "    }\n" +
 //                "}";
 //
-//        static final String GET_MEMBER_NAME_METHOD =
+//        static final String GUARD_METHOD_TEMPLATE_V =
 //                "@ForceInline\n" +
-//                "final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {\n" +
-//                "    MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);\n" +
-//                "    if (mn == null) {\n" +
-//                "        throw handle.unsupported();\n" +
+//                "@LambdaForm.Compiled\n" +
+//                "final static <METHOD> throws Throwable {\n" +
+//                "    if (handle.vform.methodType_table[ad.type] == ad.symbolicMethodType) {\n" +
+//                "        MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
 //                "    }\n" +
-//                "    return mn;\n" +
+//                "    else if (handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodType) {\n" +
+//                "        MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
+//                "    }\n" +
+//                "    else {\n" +
+//                "        MethodHandle mh = handle.getMethodHandle(ad.mode);\n" +
+//                "        mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
+//                "    }\n" +
 //                "}";
 //
 //        // A template for deriving the operations
@@ -345,8 +346,6 @@
 //            System.out.println("final class VarHandleGuards {");
 //
 //            System.out.println();
-//            System.out.println(GET_MEMBER_NAME_METHOD);
-//            System.out.println();
 //
 //            // Declare the stream of shapes
 //            Stream<HandleType> hts = Stream.of(
@@ -445,7 +444,10 @@
 //
 //            List<String> LINK_TO_STATIC_ARGS = params.keySet().stream().
 //                    collect(toList());
-//            LINK_TO_STATIC_ARGS.add("getMemberName(handle, ad)");
+//            LINK_TO_STATIC_ARGS.add("handle.vform.getMemberName(ad.mode)");
+//            List<String> LINK_TO_STATIC_ARGS_V = params.keySet().stream().
+//                    collect(toList());
+//            LINK_TO_STATIC_ARGS_V.add("handle.vform.getMemberName_V(ad.mode)");
 //
 //            List<String> LINK_TO_INVOKER_ARGS = params.keySet().stream().
 //                    collect(toList());
@@ -464,9 +466,12 @@
 //
 //            String RETURN_ERASED = returnType != Object.class
 //                                   ? ""
-//                                   : " return symbolic.returnType().cast(r);";
+//                                   : " return ad.returnType.cast(r);";
 //
-//            return GUARD_METHOD_TEMPLATE.
+//            String template = returnType == void.class
+//                              ? GUARD_METHOD_TEMPLATE_V
+//                              : GUARD_METHOD_TEMPLATE;
+//            return template.
 //                    replace("<METHOD>", METHOD).
 //                    replace("<NAME>", NAME).
 //                    replaceAll("<RETURN>", RETURN).
@@ -474,6 +479,8 @@
 //                    replace("<RETURN_ERASED>", RETURN_ERASED).
 //                    replaceAll("<LINK_TO_STATIC_ARGS>", LINK_TO_STATIC_ARGS.stream().
 //                            collect(joining(", "))).
+//                    replaceAll("<LINK_TO_STATIC_ARGS_V>", LINK_TO_STATIC_ARGS_V.stream().
+//                            collect(joining(", "))).
 //                    replace("<LINK_TO_INVOKER_ARGS>", LINK_TO_INVOKER_ARGS.stream().
 //                            collect(joining(", ")))
 //                    ;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu May 05 11:39:08 2016 -0700
@@ -41,12 +41,12 @@
 #end[Object]
 
         FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.class);
+            this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.FORM);
         }
 
         protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
-                                        Class<? extends FieldInstanceReadOnly> handle) {
-            super(VarForm.createFromStatic(handle), receiverType, {#if[Object]?fieldType:$type$.class});
+                                        VarForm form) {
+            super(form);
             this.fieldOffset = fieldOffset;
             this.receiverType = receiverType;
 #if[Object]
@@ -54,6 +54,11 @@
 #end[Object]
         }
 
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class});
+        }
+
         @ForceInline
         static $type$ get(FieldInstanceReadOnly handle, Object holder) {
             return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
@@ -77,12 +82,14 @@
             return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
                                  handle.fieldOffset);
         }
+
+        static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, $type$.class);
     }
 
-    static class FieldInstanceReadWrite extends FieldInstanceReadOnly {
+    static final class FieldInstanceReadWrite extends FieldInstanceReadOnly {
 
         FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.class);
+            super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.FORM);
         }
 
         @ForceInline
@@ -202,6 +209,8 @@
                                        value) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(FieldInstanceReadWrite.class, Object.class, $type$.class);
     }
 
 
@@ -213,12 +222,12 @@
 #end[Object]
 
         FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.class);
+            this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM);
         }
 
         protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
-                                      Class<? extends FieldStaticReadOnly> handle) {
-            super(VarForm.createFromStatic(handle), null, {#if[Object]?fieldType:$type$.class});
+                                      VarForm form) {
+            super(form);
             this.base = base;
             this.fieldOffset = fieldOffset;
 #if[Object]
@@ -226,6 +235,11 @@
 #end[Object]
         }
 
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(null, {#if[Object]?fieldType:$type$.class});
+        }
+
         @ForceInline
         static $type$ get(FieldStaticReadOnly handle) {
             return UNSAFE.get$Type$(handle.base,
@@ -249,12 +263,14 @@
             return UNSAFE.get$Type$Acquire(handle.base,
                                  handle.fieldOffset);
         }
+
+        static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, $type$.class);
     }
 
-    static class FieldStaticReadWrite extends FieldStaticReadOnly {
+    static final class FieldStaticReadWrite extends FieldStaticReadOnly {
 
         FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
-            super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.class);
+            super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM);
         }
 
         @ForceInline
@@ -375,6 +391,8 @@
                                        value) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, $type$.class);
     }
 
 
@@ -387,8 +405,7 @@
 #end[Object]
 
         Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}) {
-            super(VarForm.createFromStatic(Array.class),
-                  {#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+            super(Array.FORM);
             this.abase = abase;
             this.ashift = ashift;
 #if[Object]
@@ -397,6 +414,11 @@
 #end[Object]
         }
 
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+        }
+
         @ForceInline
         static $type$ get(Array handle, Object oarray, int index) {
 #if[Object]
@@ -630,5 +652,7 @@
                     value) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(Array.class, {#if[Object]?Object[].class:$type$[].class}, {#if[Object]?Object.class:$type$.class}, int.class);
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Thu May 05 11:37:18 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Thu May 05 11:39:08 2016 -0700
@@ -59,13 +59,11 @@
 #end[floatingPoint]
 
 
-    private static class ByteArrayViewVarHandle extends VarHandle {
+    private static abstract class ByteArrayViewVarHandle extends VarHandle {
         final boolean be;
 
-        ByteArrayViewVarHandle(Class<? extends ByteArrayViewVarHandle> implSubType,
-                               Class<?> arrayType, Class<?> component, boolean be) {
-            super(VarForm.createFromStatic(implSubType),
-                  arrayType, component, int.class);
+        ByteArrayViewVarHandle(VarForm form, boolean be) {
+            super(form);
             this.be = be;
         }
     }
@@ -73,7 +71,12 @@
     static final class ArrayHandle extends ByteArrayViewVarHandle {
 
         ArrayHandle(boolean be) {
-            super(ArrayHandle.class, byte[].class, $type$.class, be);
+            super(ArrayHandle.FORM, be);
+        }
+
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(byte[].class, $type$.class, int.class);
         }
 
         @ForceInline
@@ -286,13 +289,20 @@
                     convEndian(handle.be, value))) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(ArrayHandle.class, byte[].class, $type$.class, int.class);
     }
 
 
     static final class ByteBufferHandle extends ByteArrayViewVarHandle {
 
         ByteBufferHandle(boolean be) {
-            super(ByteBufferHandle.class, ByteBuffer.class, $type$.class, be);
+            super(ByteBufferHandle.FORM, be);
+        }
+
+        @Override
+        final MethodType accessModeTypeUncached(AccessMode accessMode) {
+            return accessMode.at.accessModeType(ByteBuffer.class, $type$.class, int.class);
         }
 
         @ForceInline
@@ -513,5 +523,7 @@
                                       convEndian(handle.be, value))) + value;
         }
 #end[AtomicAdd]
+
+        static final VarForm FORM = new VarForm(ByteBufferHandle.class, ByteBuffer.class, $type$.class, int.class);
     }
 }