8151706: Update VarHandle implementation to use @Stable arrays
authorpsandoz
Mon, 11 Apr 2016 18:21:25 +0200
changeset 36973 951bb58383a4
parent 36972 27147cde3256
child 36974 86f49af093e5
8151706: Update VarHandle implementation to use @Stable arrays Reviewed-by: mhaupt, shade, redestad
jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java
jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Mon Apr 11 10:55:03 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Mon Apr 11 18:21:25 2016 +0200
@@ -24,16 +24,11 @@
  */
 package java.lang.invoke;
 
+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.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
 
 /**
  * A var handle form containing a set of member name, one for each operation.
@@ -43,51 +38,17 @@
 
     // Holds VarForm for VarHandle implementation classes
     private static final ClassValue<VarForm> VFORMS
-            = new ClassValue<VarForm>() {
+            = new ClassValue<>() {
         @Override
         protected VarForm computeValue(Class<?> impl) {
-            return new VarForm(link(staticMethodLinker(impl)));
+            return new VarForm(linkFromStatic(impl));
         }
     };
 
-    final MemberName mbGet;
-    final MemberName mbSet;
-    final MemberName mbGetVolatile;
-    final MemberName mbSetVolatile;
-    final MemberName mbGetAcquire;
-    final MemberName mbSetRelease;
-    final MemberName mbCompareAndSet;
-    final MemberName mbCompareAndExchangeVolatile;
-    final MemberName mbCompareAndExchangeAcquire;
-    final MemberName mbCompareAndExchangeRelease;
-    final MemberName mbWeakCompareAndSet;
-    final MemberName mbWeakCompareAndSetAcquire;
-    final MemberName mbWeakCompareAndSetRelease;
-    final MemberName mbGetAndSet;
-    final MemberName mbGetAndAdd;
-    final MemberName mbAddAndGet;
-    final MemberName mbGetOpaque;
-    final MemberName mbSetOpaque;
+    final @Stable MemberName[] table;
 
-    VarForm(Map<AccessMode, MemberName> linkMap) {
-        mbGet = linkMap.get(AccessMode.get);
-        mbSet = linkMap.get(AccessMode.set);
-        mbGetVolatile = linkMap.get(AccessMode.getVolatile);
-        mbSetVolatile = linkMap.get(AccessMode.setVolatile);
-        mbGetOpaque = linkMap.get(AccessMode.getOpaque);
-        mbSetOpaque = linkMap.get(AccessMode.setOpaque);
-        mbGetAcquire = linkMap.get(AccessMode.getAcquire);
-        mbSetRelease = linkMap.get(AccessMode.setRelease);
-        mbCompareAndSet = linkMap.get(AccessMode.compareAndSet);
-        mbCompareAndExchangeVolatile = linkMap.get(AccessMode.compareAndExchangeVolatile);
-        mbCompareAndExchangeAcquire = linkMap.get(AccessMode.compareAndExchangeAcquire);
-        mbCompareAndExchangeRelease = linkMap.get(AccessMode.compareAndExchangeRelease);
-        mbWeakCompareAndSet = linkMap.get(AccessMode.weakCompareAndSet);
-        mbWeakCompareAndSetAcquire = linkMap.get(AccessMode.weakCompareAndSetAcquire);
-        mbWeakCompareAndSetRelease = linkMap.get(AccessMode.weakCompareAndSetRelease);
-        mbGetAndSet = linkMap.get(AccessMode.getAndSet);
-        mbGetAndAdd = linkMap.get(AccessMode.getAndAdd);
-        mbAddAndGet = linkMap.get(AccessMode.addAndGet);
+    VarForm(MemberName[] table) {
+        this.table = table;
     }
 
     /**
@@ -102,63 +63,23 @@
     /**
      * Link all signature polymorphic methods.
      */
-    private static Map<AccessMode, MemberName> link(Function<AccessMode, MemberName> linker) {
-        Map<AccessMode, MemberName> links = new HashMap<>();
-        for (AccessMode ak : AccessMode.values()) {
-            links.put(ak, linker.apply(ak));
-        }
-        return links;
-    }
-
+    private static MemberName[] linkFromStatic(Class<?> implClass) {
+        MemberName[] table = new MemberName[AccessMode.values().length];
 
-    /**
-     * Returns a function that associates an AccessMode with a MemberName that
-     * is a static concrete method implementation for the access operation of
-     * the implementing class.
-     */
-    private static Function<AccessMode, MemberName> staticMethodLinker(Class<?> implClass) {
-        // Find all declared static methods on the implementation class and
-        // all super classes up to but not including VarHandle
-        List<Method> staticMethods = new ArrayList<>(AccessMode.values().length);
         for (Class<?> c = implClass; c != VarHandle.class; c = c.getSuperclass()) {
             for (Method m : c.getDeclaredMethods()) {
                 if (Modifier.isStatic(m.getModifiers())) {
-                    staticMethods.add(m);
+                    try {
+                        AccessMode am = AccessMode.valueOf(m.getName());
+                        assert table[am.ordinal()] == null;
+                        table[am.ordinal()] = new MemberName(m);
+                    } catch (IllegalArgumentException ex) {
+                        // Ignore. Note the try/catch will be removed when
+                        // AccessMode enum constant names are renamed
+                    }
                 }
             }
         }
-
-        // This needs to be an anonymous inner class and not a lambda expression
-        // The latter will cause the intialization of classes in java.lang.invoke
-        // resulting in circular dependencies if VarHandles are utilized early
-        // in the start up process.  For example, if ConcurrentHashMap
-        // is modified to use VarHandles.
-        return new Function<>() {
-            @Override
-            public MemberName apply(AccessMode ak) {
-                Method m = null;
-                for (Method to_m : staticMethods) {
-                    if (to_m.getName().equals(ak.name()) &&
-                        Modifier.isStatic(to_m.getModifiers())) {
-                        assert m == null : String.format(
-                                "Two or more static methods named %s are present on " +
-                                "class %s or a super class", ak.name(), implClass.getName());
-                        m = to_m;
-                    }
-                }
-
-                if (m == null)
-                    return null;
-
-                MemberName linkedMethod = new MemberName(m);
-                try {
-                    return MemberName.getFactory().resolveOrFail(
-                            REF_invokeStatic, linkedMethod, m.getDeclaringClass(), NoSuchMethodException.class);
-                }
-                catch (ReflectiveOperationException e) {
-                    throw new InternalError(e);
-                }
-            }
-        };
+        return table;
     }
-}
+}
\ No newline at end of file
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Mon Apr 11 10:55:03 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Mon Apr 11 18:21:25 2016 +0200
@@ -1168,63 +1168,7 @@
 
         @ForceInline
         static MemberName getMemberName(int ordinal, VarForm vform) {
-            if (ordinal == 0) {
-                return vform.mbGet;
-            }
-            else if (ordinal == 1) {
-                return vform.mbSet;
-            }
-            else if (ordinal == 2) {
-                return vform.mbGetVolatile;
-            }
-            else if (ordinal == 3) {
-                return vform.mbSetVolatile;
-            }
-            else if (ordinal == 4) {
-                return vform.mbGetAcquire;
-            }
-            else if (ordinal == 5) {
-                return vform.mbSetRelease;
-            }
-            else if (ordinal == 6) {
-                return vform.mbGetOpaque;
-            }
-            else if (ordinal == 7) {
-                return vform.mbSetOpaque;
-            }
-            else if (ordinal == 8) {
-                return vform.mbCompareAndSet;
-            }
-            else if (ordinal == 9) {
-                return vform.mbCompareAndExchangeVolatile;
-            }
-            else if (ordinal == 10) {
-                return vform.mbCompareAndExchangeAcquire;
-            }
-            else if (ordinal == 11) {
-                return vform.mbCompareAndExchangeRelease;
-            }
-            else if (ordinal == 12) {
-                return vform.mbWeakCompareAndSet;
-            }
-            else if (ordinal == 13) {
-                return vform.mbWeakCompareAndSetAcquire;
-            }
-            else if (ordinal == 14) {
-                return vform.mbWeakCompareAndSetRelease;
-            }
-            else if (ordinal == 15) {
-                return vform.mbGetAndSet;
-            }
-            else if (ordinal == 16) {
-                return vform.mbGetAndAdd;
-            }
-            else if (ordinal == 17) {
-                return vform.mbAddAndGet;
-            }
-            else {
-                throw new IllegalStateException("Illegal access mode: " + ordinal);
-            }
+            return vform.table[ordinal];
         }
     }