jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java
changeset 37343 35a2231828a7
parent 36973 951bb58383a4
child 37344 52d3d8517efc
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed Apr 13 09:35:26 2016 -0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed Apr 13 15:05:48 2016 +0200
@@ -31,7 +31,9 @@
 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;
 import java.util.function.BiFunction;
 
 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
@@ -272,7 +274,7 @@
  * <pre> {@code
  * MethodHandle mh = MethodHandles.lookup().findVirtual(
  *                       VarHandle.class,
- *                       VarHandle.AccessMode.{access-mode}.name(),
+ *                       VarHandle.AccessMode.{access-mode}.methodName(),
  *                       MethodType.methodType(R, p1, p2, ..., pN));
  *
  * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
@@ -993,11 +995,11 @@
     Object addAndGet(Object... args);
 
     enum AccessType {
-        get,                  // 0
-        set,                  // 1
-        compareAndSwap,       // 2
-        compareAndExchange,   // 3
-        getAndUpdate;         // 4
+        GET,                    // 0
+        SET,                    // 1
+        COMPARE_AND_SWAP,       // 2
+        COMPARE_AND_EXCHANGE,   // 3
+        GET_AND_UPDATE;         // 4
 
         MethodType getMethodType(VarHandle vh) {
             return getMethodType(this.ordinal(), vh);
@@ -1036,126 +1038,179 @@
          * method
          * {@link VarHandle#get VarHandle.get}
          */
-        get(AccessType.get, Object.class),   // 0
+        GET("get", AccessType.GET, Object.class),   // 0
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#set VarHandle.set}
          */
-        set(AccessType.set, void.class),     // 1
+        SET("set", AccessType.SET, void.class),     // 1
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getVolatile VarHandle.getVolatile}
          */
-        getVolatile(AccessType.get, Object.class),  // 2
+        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),  // 2
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setVolatile VarHandle.setVolatile}
          */
-        setVolatile(AccessType.set, void.class),    // 3
+        SET_VOLATILE("setVolatile", AccessType.SET, void.class),    // 3
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAcquire VarHandle.getAcquire}
          */
-        getAcquire(AccessType.get, Object.class),   // 4
+        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),   // 4
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setRelease VarHandle.setRelease}
          */
-        setRelease(AccessType.set, void.class),     // 5
+        SET_RELEASE("setRelease", AccessType.SET, void.class),     // 5
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getOpaque VarHandle.getOpaque}
          */
-        getOpaque(AccessType.get, Object.class),    // 6
+        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),    // 6
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setOpaque VarHandle.setOpaque}
          */
-        setOpaque(AccessType.set, void.class),      // 7
+        SET_OPAQUE("setOpaque", AccessType.SET, void.class),      // 7
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
          */
-        compareAndSet(AccessType.compareAndSwap, boolean.class),    // 8
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),    // 8
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
          */
-        compareAndExchangeVolatile(AccessType.compareAndExchange, Object.class), // 9
+        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 9
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
          */
-        compareAndExchangeAcquire(AccessType.compareAndExchange, Object.class),  // 10
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 10
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
          */
-        compareAndExchangeRelease(AccessType.compareAndExchange, Object.class),  // 11
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 11
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
          */
-        weakCompareAndSet(AccessType.compareAndSwap, boolean.class),        // 12
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),        // 12
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
          */
-        weakCompareAndSetAcquire(AccessType.compareAndSwap, boolean.class), // 13
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), // 13
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
          */
-        weakCompareAndSetRelease(AccessType.compareAndSwap, boolean.class), // 14
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), // 14
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndSet VarHandle.getAndSet}
          */
-        getAndSet(AccessType.getAndUpdate, Object.class),   // 15
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),   // 15
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
          */
-        getAndAdd(AccessType.getAndUpdate, Object.class),   // 16
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),   // 16
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#addAndGet VarHandle.addAndGet}
          */
-        addAndGet(AccessType.getAndUpdate, Object.class),   // 17
+        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),   // 17
         ;
 
+        static final Map<String, AccessMode> methodNameToAccessMode;
+        static {
+            // Initial capacity of # values is sufficient to avoid resizes
+            // for the smallest table size (32)
+            methodNameToAccessMode = new HashMap<>(AccessMode.values().length);
+            for (AccessMode am : AccessMode.values()) {
+                methodNameToAccessMode.put(am.methodName, am);
+            }
+        }
+
+        final String methodName;
         final AccessType at;
         final boolean isPolyMorphicInReturnType;
         final Class<?> returnType;
 
-        AccessMode(AccessType at, Class<?> returnType) {
+        AccessMode(final String methodName, AccessType at, Class<?> returnType) {
+            this.methodName = methodName;
             this.at = at;
 
+            // Assert method name is correctly derived from value name
+            assert methodName.equals(toMethodName(name()));
             // Assert that return type is correct
             // Otherwise, when disabled avoid using reflection
-            assert returnType == getReturnType(name());
+            assert returnType == getReturnType(methodName);
 
             this.returnType = returnType;
             isPolyMorphicInReturnType = returnType != Object.class;
         }
 
+        /**
+         * Returns the {@code VarHandle} signature-polymorphic method name
+         * associated with this {@code AccessMode} value
+         *
+         * @return the signature-polymorphic method name
+         * @see #valueFromMethodName
+         */
+        public String methodName() {
+            return methodName;
+        }
+
+        /**
+         * Returns the {@code AccessMode} value associated with the specified
+         * {@code VarHandle} signature-polymorphic method name.
+         *
+         * @param methodName the signature-polymorphic method name
+         * @return the {@code AccessMode} value
+         * @throws IllegalArgumentException if there is no {@code AccessMode}
+         *         value associated with method name (indicating the method
+         *         name does not correspond to a {@code VarHandle}
+         *         signature-polymorphic method name).
+         * @see #methodName
+         */
+        public static AccessMode valueFromMethodName(String methodName) {
+            AccessMode am = methodNameToAccessMode.get(methodName);
+            if (am != null) return am;
+            throw new IllegalArgumentException("No AccessMode value for method name " + methodName);
+        }
+
+        private static String toMethodName(String name) {
+            StringBuilder s = new StringBuilder(name.toLowerCase());
+            int i;
+            while ((i = s.indexOf("_")) !=  -1) {
+                s.deleteCharAt(i);
+                s.setCharAt(i, Character.toUpperCase(s.charAt(i)));
+            }
+            return s.toString();
+        }
+
         private static Class<?> getReturnType(String name) {
             try {
                 Method m = VarHandle.class.getMethod(name, Object[].class);