< prev index next >

src/java.base/share/classes/sun/invoke/util/ValueConversions.java

Print this page
rev 15320 : 8163370: Reduce number of classes loaded by common usage of java.lang.invoke
Reviewed-by: igerasim, psandoz

*** 27,59 **** import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; ! import java.util.EnumMap; public class ValueConversions { private static final Class<?> THIS_CLASS = ValueConversions.class; private static final Lookup IMPL_LOOKUP = MethodHandles.lookup(); ! /** Thread-safe canonicalized mapping from Wrapper to MethodHandle * with unsynchronized reads and synchronized writes. ! * It's safe to publish MethodHandles by data race because they are immutable. */ private static class WrapperCache { ! /** EnumMap uses preconstructed array internally, which is constant during it's lifetime. */ ! private final EnumMap<Wrapper, MethodHandle> map = new EnumMap<>(Wrapper.class); public MethodHandle get(Wrapper w) { ! return map.get(w); } public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) { ! // Simulate CAS to avoid racy duplication ! MethodHandle prev = map.putIfAbsent(w, mh); ! if (prev != null) return prev; return mh; } } private static WrapperCache[] newWrapperCaches(int n) { WrapperCache[] caches = new WrapperCache[n]; for (int i = 0; i < n; i++) caches[i] = new WrapperCache(); --- 27,64 ---- import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; ! import jdk.internal.vm.annotation.Stable; public class ValueConversions { private static final Class<?> THIS_CLASS = ValueConversions.class; private static final Lookup IMPL_LOOKUP = MethodHandles.lookup(); ! /** ! * Thread-safe canonicalized mapping from Wrapper to MethodHandle * with unsynchronized reads and synchronized writes. ! * It's safe to publish MethodHandles by data race because they are immutable. ! */ private static class WrapperCache { ! @Stable ! private final MethodHandle[] map = new MethodHandle[Wrapper.COUNT]; public MethodHandle get(Wrapper w) { ! return map[w.ordinal()]; } public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) { ! MethodHandle prev = map[w.ordinal()]; ! if (prev != null) { ! return prev; ! } else { ! map[w.ordinal()] = mh; return mh; } } + } private static WrapperCache[] newWrapperCaches(int n) { WrapperCache[] caches = new WrapperCache[n]; for (int i = 0; i < n; i++) caches[i] = new WrapperCache();
*** 621,631 **** static byte fromBoolean(boolean x) { // see javadoc for MethodHandles.explicitCastArguments return (x ? (byte)1 : (byte)0); } ! private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length); public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) { WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()]; MethodHandle mh = cache.get(wdst); if (mh != null) { --- 626,636 ---- static byte fromBoolean(boolean x) { // see javadoc for MethodHandles.explicitCastArguments return (x ? (byte)1 : (byte)0); } ! private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.COUNT); public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) { WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()]; MethodHandle mh = cache.get(wdst); if (mh != null) {
< prev index next >