# HG changeset patch # User psandoz # Date 1460391685 -7200 # Node ID 951bb58383a40ff23072050856fa21bdc9b6996a # Parent 27147cde32565c35dba4baaf8efeb1957ebbd45c 8151706: Update VarHandle implementation to use @Stable arrays Reviewed-by: mhaupt, shade, redestad diff -r 27147cde3256 -r 951bb58383a4 jdk/src/java.base/share/classes/java/lang/invoke/VarForm.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 VFORMS - = new ClassValue() { + = 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 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 link(Function linker) { - Map 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 staticMethodLinker(Class implClass) { - // Find all declared static methods on the implementation class and - // all super classes up to but not including VarHandle - List 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 diff -r 27147cde3256 -r 951bb58383a4 jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java --- 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]; } }