--- 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);