jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java
changeset 37792 dd626e6f5967
parent 37719 add11bc0e6e2
child 38328 40435a469d25
child 38367 21801e8e9344
equal deleted inserted replaced
37791:ae33107fd8b3 37792:dd626e6f5967
    25 
    25 
    26 package java.lang.invoke;
    26 package java.lang.invoke;
    27 
    27 
    28 import jdk.internal.HotSpotIntrinsicCandidate;
    28 import jdk.internal.HotSpotIntrinsicCandidate;
    29 import jdk.internal.vm.annotation.ForceInline;
    29 import jdk.internal.vm.annotation.ForceInline;
       
    30 import jdk.internal.vm.annotation.Stable;
    30 
    31 
    31 import java.lang.reflect.Method;
    32 import java.lang.reflect.Method;
    32 import java.util.ArrayList;
       
    33 import java.util.Arrays;
       
    34 import java.util.HashMap;
    33 import java.util.HashMap;
    35 import java.util.List;
    34 import java.util.List;
    36 import java.util.Map;
    35 import java.util.Map;
    37 import java.util.Objects;
    36 import java.util.Objects;
    38 import java.util.function.BiFunction;
    37 import java.util.function.BiFunction;
   404  * @see MethodHandles
   403  * @see MethodHandles
   405  * @see MethodType
   404  * @see MethodType
   406  * @since 9
   405  * @since 9
   407  */
   406  */
   408 public abstract class VarHandle {
   407 public abstract class VarHandle {
   409     // Use explicit final fields rather than an @Stable array as
       
   410     // this can reduce the memory per handle
       
   411     // e.g. by 24 bytes on 64 bit architectures
       
   412     final MethodType typeGet;
       
   413     final MethodType typeSet;
       
   414     final MethodType typeCompareSwap;
       
   415     final MethodType typeCompareExchange;
       
   416     final MethodType typeGetAndUpdate;
       
   417 
       
   418     final VarForm vform;
   408     final VarForm vform;
   419 
   409 
   420     VarHandle(VarForm vform, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
   410     VarHandle(VarForm vform) {
   421         this.vform = vform;
   411         this.vform = vform;
   422 
       
   423         // (Receiver, <Intermediates>)
       
   424         List<Class<?>> l = new ArrayList<>();
       
   425         if (receiver != null)
       
   426             l.add(receiver);
       
   427         l.addAll(Arrays.asList(intermediate));
       
   428 
       
   429         // (Receiver, <Intermediates>)Value
       
   430         this.typeGet = MethodType.methodType(value, l);
       
   431 
       
   432         // (Receiver, <Intermediates>, Value)void
       
   433         l.add(value);
       
   434         this.typeSet = MethodType.methodType(void.class, l);
       
   435 
       
   436         // (Receiver, <Intermediates>, Value)Value
       
   437         this.typeGetAndUpdate = MethodType.methodType(value, l);
       
   438 
       
   439         // (Receiver, <Intermediates>, Value, Value)boolean
       
   440         l.add(value);
       
   441         this.typeCompareSwap = MethodType.methodType(boolean.class, l);
       
   442 
       
   443         // (Receiver, <Intermediates>, Value, Value)Value
       
   444         this.typeCompareExchange = MethodType.methodType(value, l);
       
   445     }
   412     }
   446 
   413 
   447     RuntimeException unsupported() {
   414     RuntimeException unsupported() {
   448         return new UnsupportedOperationException();
   415         return new UnsupportedOperationException();
   449     }
   416     }
  1088     @MethodHandle.PolymorphicSignature
  1055     @MethodHandle.PolymorphicSignature
  1089     @HotSpotIntrinsicCandidate
  1056     @HotSpotIntrinsicCandidate
  1090     Object addAndGet(Object... args);
  1057     Object addAndGet(Object... args);
  1091 
  1058 
  1092     enum AccessType {
  1059     enum AccessType {
  1093         GET,                    // 0
  1060         GET(Object.class) {
  1094         SET,                    // 1
  1061             @Override
  1095         COMPARE_AND_SWAP,       // 2
  1062             MethodType accessModeType(Class<?> receiver, Class<?> value,
  1096         COMPARE_AND_EXCHANGE,   // 3
  1063                                       Class<?>... intermediate) {
  1097         GET_AND_UPDATE;         // 4
  1064                 Class<?>[] ps =  allocateParameters(0, receiver, intermediate);
  1098 
  1065                 fillParameters(ps, receiver, intermediate);
  1099         MethodType getMethodType(VarHandle vh) {
  1066                 return MethodType.methodType(value, ps);
  1100             return getMethodType(this.ordinal(), vh);
       
  1101         }
       
  1102 
       
  1103         @ForceInline
       
  1104         static MethodType getMethodType(int ordinal, VarHandle vh) {
       
  1105             if (ordinal == 0) {
       
  1106                 return vh.typeGet;
       
  1107             }
  1067             }
  1108             else if (ordinal == 1) {
  1068         },
  1109                 return vh.typeSet;
  1069         SET(void.class) {
       
  1070             @Override
       
  1071             MethodType accessModeType(Class<?> receiver, Class<?> value,
       
  1072                                       Class<?>... intermediate) {
       
  1073                 Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
       
  1074                 int i = fillParameters(ps, receiver, intermediate);
       
  1075                 ps[i] = value;
       
  1076                 return MethodType.methodType(void.class, ps);
  1110             }
  1077             }
  1111             else if (ordinal == 2) {
  1078         },
  1112                 return vh.typeCompareSwap;
  1079         COMPARE_AND_SWAP(boolean.class) {
       
  1080             @Override
       
  1081             MethodType accessModeType(Class<?> receiver, Class<?> value,
       
  1082                                       Class<?>... intermediate) {
       
  1083                 Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
       
  1084                 int i = fillParameters(ps, receiver, intermediate);
       
  1085                 ps[i++] = value;
       
  1086                 ps[i] = value;
       
  1087                 return MethodType.methodType(boolean.class, ps);
  1113             }
  1088             }
  1114             else if (ordinal == 3) {
  1089         },
  1115                 return vh.typeCompareExchange;
  1090         COMPARE_AND_EXCHANGE(Object.class) {
       
  1091             @Override
       
  1092             MethodType accessModeType(Class<?> receiver, Class<?> value,
       
  1093                                       Class<?>... intermediate) {
       
  1094                 Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
       
  1095                 int i = fillParameters(ps, receiver, intermediate);
       
  1096                 ps[i++] = value;
       
  1097                 ps[i] = value;
       
  1098                 return MethodType.methodType(value, ps);
  1116             }
  1099             }
  1117             else if (ordinal == 4) {
  1100         },
  1118                 return vh.typeGetAndUpdate;
  1101         GET_AND_UPDATE(Object.class) {
       
  1102             @Override
       
  1103             MethodType accessModeType(Class<?> receiver, Class<?> value,
       
  1104                                       Class<?>... intermediate) {
       
  1105                 Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
       
  1106                 int i = fillParameters(ps, receiver, intermediate);
       
  1107                 ps[i] = value;
       
  1108                 return MethodType.methodType(value, ps);
  1119             }
  1109             }
  1120             else {
  1110         };
  1121                 throw new IllegalStateException("Illegal access type: " + ordinal);
  1111 
  1122             }
  1112         final Class<?> returnType;
       
  1113         final boolean isMonomorphicInReturnType;
       
  1114 
       
  1115         AccessType(Class<?> returnType) {
       
  1116             this.returnType = returnType;
       
  1117             isMonomorphicInReturnType = returnType != Object.class;
       
  1118         }
       
  1119 
       
  1120         abstract MethodType accessModeType(Class<?> receiver, Class<?> value,
       
  1121                                            Class<?>... intermediate);
       
  1122 
       
  1123         private static Class<?>[] allocateParameters(int values,
       
  1124                                                      Class<?> receiver, Class<?>... intermediate) {
       
  1125             int size = ((receiver != null) ? 1 : 0) + intermediate.length + values;
       
  1126             return new Class<?>[size];
       
  1127         }
       
  1128 
       
  1129         private static int fillParameters(Class<?>[] ps,
       
  1130                                           Class<?> receiver, Class<?>... intermediate) {
       
  1131             int i = 0;
       
  1132             if (receiver != null)
       
  1133                 ps[i++] = receiver;
       
  1134             for (int j = 0; j < intermediate.length; j++)
       
  1135                 ps[i++] = intermediate[j];
       
  1136             return i;
  1123         }
  1137         }
  1124     }
  1138     }
  1125 
  1139 
  1126     /**
  1140     /**
  1127      * The set of access modes that specify how a variable, referenced by a
  1141      * The set of access modes that specify how a variable, referenced by a
  1131         /**
  1145         /**
  1132          * The access mode whose access is specified by the corresponding
  1146          * The access mode whose access is specified by the corresponding
  1133          * method
  1147          * method
  1134          * {@link VarHandle#get VarHandle.get}
  1148          * {@link VarHandle#get VarHandle.get}
  1135          */
  1149          */
  1136         GET("get", AccessType.GET, Object.class),
  1150         GET("get", AccessType.GET),
  1137         /**
  1151         /**
  1138          * The access mode whose access is specified by the corresponding
  1152          * The access mode whose access is specified by the corresponding
  1139          * method
  1153          * method
  1140          * {@link VarHandle#set VarHandle.set}
  1154          * {@link VarHandle#set VarHandle.set}
  1141          */
  1155          */
  1142         SET("set", AccessType.SET, void.class),
  1156         SET("set", AccessType.SET),
  1143         /**
  1157         /**
  1144          * The access mode whose access is specified by the corresponding
  1158          * The access mode whose access is specified by the corresponding
  1145          * method
  1159          * method
  1146          * {@link VarHandle#getVolatile VarHandle.getVolatile}
  1160          * {@link VarHandle#getVolatile VarHandle.getVolatile}
  1147          */
  1161          */
  1148         GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
  1162         GET_VOLATILE("getVolatile", AccessType.GET),
  1149         /**
  1163         /**
  1150          * The access mode whose access is specified by the corresponding
  1164          * The access mode whose access is specified by the corresponding
  1151          * method
  1165          * method
  1152          * {@link VarHandle#setVolatile VarHandle.setVolatile}
  1166          * {@link VarHandle#setVolatile VarHandle.setVolatile}
  1153          */
  1167          */
  1154         SET_VOLATILE("setVolatile", AccessType.SET, void.class),
  1168         SET_VOLATILE("setVolatile", AccessType.SET),
  1155         /**
  1169         /**
  1156          * The access mode whose access is specified by the corresponding
  1170          * The access mode whose access is specified by the corresponding
  1157          * method
  1171          * method
  1158          * {@link VarHandle#getAcquire VarHandle.getAcquire}
  1172          * {@link VarHandle#getAcquire VarHandle.getAcquire}
  1159          */
  1173          */
  1160         GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
  1174         GET_ACQUIRE("getAcquire", AccessType.GET),
  1161         /**
  1175         /**
  1162          * The access mode whose access is specified by the corresponding
  1176          * The access mode whose access is specified by the corresponding
  1163          * method
  1177          * method
  1164          * {@link VarHandle#setRelease VarHandle.setRelease}
  1178          * {@link VarHandle#setRelease VarHandle.setRelease}
  1165          */
  1179          */
  1166         SET_RELEASE("setRelease", AccessType.SET, void.class),
  1180         SET_RELEASE("setRelease", AccessType.SET),
  1167         /**
  1181         /**
  1168          * The access mode whose access is specified by the corresponding
  1182          * The access mode whose access is specified by the corresponding
  1169          * method
  1183          * method
  1170          * {@link VarHandle#getOpaque VarHandle.getOpaque}
  1184          * {@link VarHandle#getOpaque VarHandle.getOpaque}
  1171          */
  1185          */
  1172         GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
  1186         GET_OPAQUE("getOpaque", AccessType.GET),
  1173         /**
  1187         /**
  1174          * The access mode whose access is specified by the corresponding
  1188          * The access mode whose access is specified by the corresponding
  1175          * method
  1189          * method
  1176          * {@link VarHandle#setOpaque VarHandle.setOpaque}
  1190          * {@link VarHandle#setOpaque VarHandle.setOpaque}
  1177          */
  1191          */
  1178         SET_OPAQUE("setOpaque", AccessType.SET, void.class),
  1192         SET_OPAQUE("setOpaque", AccessType.SET),
  1179         /**
  1193         /**
  1180          * The access mode whose access is specified by the corresponding
  1194          * The access mode whose access is specified by the corresponding
  1181          * method
  1195          * method
  1182          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
  1196          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
  1183          */
  1197          */
  1184         COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
  1198         COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP),
  1185         /**
  1199         /**
  1186          * The access mode whose access is specified by the corresponding
  1200          * The access mode whose access is specified by the corresponding
  1187          * method
  1201          * method
  1188          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
  1202          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
  1189          */
  1203          */
  1190         COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
  1204         COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE),
  1191         /**
  1205         /**
  1192          * The access mode whose access is specified by the corresponding
  1206          * The access mode whose access is specified by the corresponding
  1193          * method
  1207          * method
  1194          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
  1208          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
  1195          */
  1209          */
  1196         COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
  1210         COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE),
  1197         /**
  1211         /**
  1198          * The access mode whose access is specified by the corresponding
  1212          * The access mode whose access is specified by the corresponding
  1199          * method
  1213          * method
  1200          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
  1214          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
  1201          */
  1215          */
  1202         COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
  1216         COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE),
  1203         /**
  1217         /**
  1204          * The access mode whose access is specified by the corresponding
  1218          * The access mode whose access is specified by the corresponding
  1205          * method
  1219          * method
  1206          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
  1220          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
  1207          */
  1221          */
  1208         WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
  1222         WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP),
  1209         /**
  1223         /**
  1210          * The access mode whose access is specified by the corresponding
  1224          * The access mode whose access is specified by the corresponding
  1211          * method
  1225          * method
  1212          * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
  1226          * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
  1213          */
  1227          */
  1214         WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
  1228         WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP),
  1215         /**
  1229         /**
  1216          * The access mode whose access is specified by the corresponding
  1230          * The access mode whose access is specified by the corresponding
  1217          * method
  1231          * method
  1218          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
  1232          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
  1219          */
  1233          */
  1220         WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
  1234         WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP),
  1221         /**
  1235         /**
  1222          * The access mode whose access is specified by the corresponding
  1236          * The access mode whose access is specified by the corresponding
  1223          * method
  1237          * method
  1224          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
  1238          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
  1225          */
  1239          */
  1226         WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
  1240         WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP),
  1227         /**
  1241         /**
  1228          * The access mode whose access is specified by the corresponding
  1242          * The access mode whose access is specified by the corresponding
  1229          * method
  1243          * method
  1230          * {@link VarHandle#getAndSet VarHandle.getAndSet}
  1244          * {@link VarHandle#getAndSet VarHandle.getAndSet}
  1231          */
  1245          */
  1232         GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
  1246         GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE),
  1233         /**
  1247         /**
  1234          * The access mode whose access is specified by the corresponding
  1248          * The access mode whose access is specified by the corresponding
  1235          * method
  1249          * method
  1236          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
  1250          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
  1237          */
  1251          */
  1238         GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
  1252         GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE),
  1239         /**
  1253         /**
  1240          * The access mode whose access is specified by the corresponding
  1254          * The access mode whose access is specified by the corresponding
  1241          * method
  1255          * method
  1242          * {@link VarHandle#addAndGet VarHandle.addAndGet}
  1256          * {@link VarHandle#addAndGet VarHandle.addAndGet}
  1243          */
  1257          */
  1244         ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
  1258         ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE),
  1245         ;
  1259         ;
  1246 
  1260 
  1247         static final Map<String, AccessMode> methodNameToAccessMode;
  1261         static final Map<String, AccessMode> methodNameToAccessMode;
  1248         static {
  1262         static {
  1249             // Initial capacity of # values is sufficient to avoid resizes
  1263             // Initial capacity of # values is sufficient to avoid resizes
  1254             }
  1268             }
  1255         }
  1269         }
  1256 
  1270 
  1257         final String methodName;
  1271         final String methodName;
  1258         final AccessType at;
  1272         final AccessType at;
  1259         final boolean isPolyMorphicInReturnType;
  1273 
  1260         final Class<?> returnType;
  1274         AccessMode(final String methodName, AccessType at) {
  1261 
       
  1262         AccessMode(final String methodName, AccessType at, Class<?> returnType) {
       
  1263             this.methodName = methodName;
  1275             this.methodName = methodName;
  1264             this.at = at;
  1276             this.at = at;
  1265 
  1277 
  1266             // Assert method name is correctly derived from value name
  1278             // Assert method name is correctly derived from value name
  1267             assert methodName.equals(toMethodName(name()));
  1279             assert methodName.equals(toMethodName(name()));
  1268             // Assert that return type is correct
  1280             // Assert that return type is correct
  1269             // Otherwise, when disabled avoid using reflection
  1281             // Otherwise, when disabled avoid using reflection
  1270             assert returnType == getReturnType(methodName);
  1282             assert at.returnType == getReturnType(methodName);
  1271 
       
  1272             this.returnType = returnType;
       
  1273             isPolyMorphicInReturnType = returnType != Object.class;
       
  1274         }
  1283         }
  1275 
  1284 
  1276         /**
  1285         /**
  1277          * Returns the {@code VarHandle} signature-polymorphic method name
  1286          * Returns the {@code VarHandle} signature-polymorphic method name
  1278          * associated with this {@code AccessMode} value
  1287          * associated with this {@code AccessMode} value
  1322             }
  1331             }
  1323         }
  1332         }
  1324 
  1333 
  1325         @ForceInline
  1334         @ForceInline
  1326         static MemberName getMemberName(int ordinal, VarForm vform) {
  1335         static MemberName getMemberName(int ordinal, VarForm vform) {
  1327             return vform.table[ordinal];
  1336             return vform.memberName_table[ordinal];
  1328         }
  1337         }
  1329     }
  1338     }
  1330 
  1339 
  1331     static final class AccessDescriptor {
  1340     static final class AccessDescriptor {
  1332         final MethodType symbolicMethodType;
  1341         final MethodType symbolicMethodTypeErased;
       
  1342         final MethodType symbolicMethodTypeInvoker;
       
  1343         final Class<?> returnType;
  1333         final int type;
  1344         final int type;
  1334         final int mode;
  1345         final int mode;
  1335 
  1346 
  1336         public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
  1347         public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
  1337             this.symbolicMethodType = symbolicMethodType;
  1348             this.symbolicMethodTypeErased = symbolicMethodType.erase();
       
  1349             this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class);
       
  1350             this.returnType = symbolicMethodType.returnType();
  1338             this.type = type;
  1351             this.type = type;
  1339             this.mode = mode;
  1352             this.mode = mode;
  1340         }
  1353         }
  1341     }
  1354     }
  1342 
  1355 
  1344      * Returns the variable type of variables referenced by this VarHandle.
  1357      * Returns the variable type of variables referenced by this VarHandle.
  1345      *
  1358      *
  1346      * @return the variable type of variables referenced by this VarHandle
  1359      * @return the variable type of variables referenced by this VarHandle
  1347      */
  1360      */
  1348     public final Class<?> varType() {
  1361     public final Class<?> varType() {
       
  1362         MethodType typeSet = accessModeType(AccessMode.SET);
  1349         return typeSet.parameterType(typeSet.parameterCount() - 1);
  1363         return typeSet.parameterType(typeSet.parameterCount() - 1);
  1350     }
  1364     }
  1351 
  1365 
  1352     /**
  1366     /**
  1353      * Returns the coordinate types for this VarHandle.
  1367      * Returns the coordinate types for this VarHandle.
  1354      *
  1368      *
  1355      * @return the coordinate types for this VarHandle. The returned
  1369      * @return the coordinate types for this VarHandle. The returned
  1356      * list is unmodifiable
  1370      * list is unmodifiable
  1357      */
  1371      */
  1358     public final List<Class<?>> coordinateTypes() {
  1372     public final List<Class<?>> coordinateTypes() {
       
  1373         MethodType typeGet = accessModeType(AccessMode.GET);
  1359         return typeGet.parameterList();
  1374         return typeGet.parameterList();
  1360     }
  1375     }
  1361 
  1376 
  1362     /**
  1377     /**
  1363      * Obtains the canonical access mode type for this VarHandle and a given
  1378      * Obtains the canonical access mode type for this VarHandle and a given
  1372      * @param accessMode the access mode, corresponding to the
  1387      * @param accessMode the access mode, corresponding to the
  1373      * signature-polymorphic method of the same name
  1388      * signature-polymorphic method of the same name
  1374      * @return the access mode type for the given access mode
  1389      * @return the access mode type for the given access mode
  1375      */
  1390      */
  1376     public final MethodType accessModeType(AccessMode accessMode) {
  1391     public final MethodType accessModeType(AccessMode accessMode) {
  1377         return accessMode.at.getMethodType(this);
  1392         TypesAndInvokers tis = getTypesAndInvokers();
  1378     }
  1393         MethodType mt = tis.methodType_table[accessMode.at.ordinal()];
  1379 
  1394         if (mt == null) {
       
  1395             mt = tis.methodType_table[accessMode.at.ordinal()] =
       
  1396                     accessModeTypeUncached(accessMode);
       
  1397         }
       
  1398         return mt;
       
  1399     }
       
  1400     abstract MethodType accessModeTypeUncached(AccessMode accessMode);
  1380 
  1401 
  1381     /**
  1402     /**
  1382      * Returns {@code true} if the given access mode is supported, otherwise
  1403      * Returns {@code true} if the given access mode is supported, otherwise
  1383      * {@code false}.
  1404      * {@code false}.
  1384      *
  1405      *
  1415      * @return a method handle bound to this VarHandle and the given access mode
  1436      * @return a method handle bound to this VarHandle and the given access mode
  1416      */
  1437      */
  1417     public final MethodHandle toMethodHandle(AccessMode accessMode) {
  1438     public final MethodHandle toMethodHandle(AccessMode accessMode) {
  1418         MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
  1439         MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
  1419         if (mn != null) {
  1440         if (mn != null) {
  1420             return DirectMethodHandle.make(mn).
  1441             MethodHandle mh = getMethodHandle(accessMode.ordinal());
  1421                     bindTo(this).
  1442             return mh.bindTo(this);
  1422                     asType(accessMode.at.getMethodType(this));
       
  1423         }
  1443         }
  1424         else {
  1444         else {
  1425             // Ensure an UnsupportedOperationException is thrown
  1445             // Ensure an UnsupportedOperationException is thrown
  1426             return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
  1446             return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
  1427                     bindTo(this);
  1447                     bindTo(this);
  1428         }
  1448         }
  1429     }
  1449     }
       
  1450 
       
  1451     @Stable
       
  1452     TypesAndInvokers typesAndInvokers;
       
  1453 
       
  1454     static class TypesAndInvokers {
       
  1455         final @Stable
       
  1456         MethodType[] methodType_table =
       
  1457                 new MethodType[VarHandle.AccessType.values().length];
       
  1458 
       
  1459         final @Stable
       
  1460         MethodHandle[] methodHandle_table =
       
  1461                 new MethodHandle[AccessMode.values().length];
       
  1462     }
       
  1463 
       
  1464     @ForceInline
       
  1465     private final TypesAndInvokers getTypesAndInvokers() {
       
  1466         TypesAndInvokers tis = typesAndInvokers;
       
  1467         if (tis == null) {
       
  1468             tis = typesAndInvokers = new TypesAndInvokers();
       
  1469         }
       
  1470         return tis;
       
  1471     }
       
  1472 
       
  1473     @ForceInline
       
  1474     final MethodHandle getMethodHandle(int mode) {
       
  1475         TypesAndInvokers tis = getTypesAndInvokers();
       
  1476         MethodHandle mh = tis.methodHandle_table[mode];
       
  1477         if (mh == null) {
       
  1478             mh = tis.methodHandle_table[mode] = getMethodHandleUncached(tis, mode);
       
  1479         }
       
  1480         return mh;
       
  1481     }
       
  1482     private final MethodHandle getMethodHandleUncached(TypesAndInvokers tis, int mode) {
       
  1483         MethodType mt = accessModeType(AccessMode.values()[mode]).
       
  1484                 insertParameterTypes(0, VarHandle.class);
       
  1485         MemberName mn = vform.getMemberName(mode);
       
  1486         DirectMethodHandle dmh = DirectMethodHandle.make(mn);
       
  1487         // Such a method handle must not be publically exposed directly
       
  1488         // otherwise it can be cracked, it must be transformed or rebound
       
  1489         // before exposure
       
  1490         MethodHandle mh = dmh.copyWith(mt, dmh.form);
       
  1491         assert mh.type().erase() == mn.getMethodType().erase();
       
  1492         return mh;
       
  1493     }
       
  1494 
  1430 
  1495 
  1431     /*non-public*/
  1496     /*non-public*/
  1432     final void updateVarForm(VarForm newVForm) {
  1497     final void updateVarForm(VarForm newVForm) {
  1433         if (vform == newVForm) return;
  1498         if (vform == newVForm) return;
  1434         UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
  1499         UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
  1451             VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
  1516             VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
  1452         }
  1517         }
  1453         catch (ReflectiveOperationException e) {
  1518         catch (ReflectiveOperationException e) {
  1454             throw newInternalError(e);
  1519             throw newInternalError(e);
  1455         }
  1520         }
       
  1521 
       
  1522         // The VarHandleGuards must be initialized to ensure correct
       
  1523         // compilation of the guard methods
       
  1524         UNSAFE.ensureClassInitialized(VarHandleGuards.class);
  1456     }
  1525     }
  1457 
  1526 
  1458 
  1527 
  1459     // Fence methods
  1528     // Fence methods
  1460 
  1529