< 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


  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.invoke.util;
  27 
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodHandles.Lookup;
  31 import java.lang.invoke.MethodType;
  32 import java.util.EnumMap;
  33 
  34 public class ValueConversions {
  35     private static final Class<?> THIS_CLASS = ValueConversions.class;
  36     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
  37 
  38     /** Thread-safe canonicalized mapping from Wrapper to MethodHandle

  39      * with unsynchronized reads and synchronized writes.
  40      * It's safe to publish MethodHandles by data race because they are immutable. */

  41     private static class WrapperCache {
  42         /** EnumMap uses preconstructed array internally, which is constant during it's lifetime. */
  43         private final EnumMap<Wrapper, MethodHandle> map = new EnumMap<>(Wrapper.class);
  44 
  45         public MethodHandle get(Wrapper w) {
  46             return map.get(w);
  47         }
  48         public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) {
  49             // Simulate CAS to avoid racy duplication
  50             MethodHandle prev = map.putIfAbsent(w, mh);
  51             if (prev != null)  return prev;


  52             return mh;
  53         }
  54     }

  55 
  56     private static WrapperCache[] newWrapperCaches(int n) {
  57         WrapperCache[] caches = new WrapperCache[n];
  58         for (int i = 0; i < n; i++)
  59             caches[i] = new WrapperCache();
  60         return caches;
  61     }
  62 
  63     /// Converting references to values.
  64 
  65     // There are several levels of this unboxing conversions:
  66     //   no conversions:  exactly Integer.valueOf, etc.
  67     //   implicit conversions sanctioned by JLS 5.1.2, etc.
  68     //   explicit conversions as allowed by explicitCastArguments
  69 
  70     static int unboxInteger(Integer x) {
  71         return x;
  72     }
  73     static int unboxInteger(Object x, boolean cast) {
  74         if (x instanceof Integer)


 606     static short booleanToShort(boolean x) {
 607         return fromBoolean(x);
 608     }
 609     static char booleanToChar(boolean x) {
 610         return (char)fromBoolean(x);
 611     }
 612     static byte booleanToByte(boolean x) {
 613         return fromBoolean(x);
 614     }
 615 
 616     // helpers to force boolean into the conversion scheme:
 617     static boolean toBoolean(byte x) {
 618         // see javadoc for MethodHandles.explicitCastArguments
 619         return ((x & 1) != 0);
 620     }
 621     static byte fromBoolean(boolean x) {
 622         // see javadoc for MethodHandles.explicitCastArguments
 623         return (x ? (byte)1 : (byte)0);
 624     }
 625 
 626     private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length);
 627 
 628     public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) {
 629         WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];
 630         MethodHandle mh = cache.get(wdst);
 631         if (mh != null) {
 632             return mh;
 633         }
 634         // slow path
 635         Class<?> src = wsrc.primitiveType();
 636         Class<?> dst = wdst.primitiveType();
 637         MethodType type = MethodType.methodType(dst, src);
 638         if (wsrc == wdst) {
 639             mh = MethodHandles.identity(src);
 640         } else {
 641             assert(src.isPrimitive() && dst.isPrimitive());
 642             try {
 643                 mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type);
 644             } catch (ReflectiveOperationException ex) {
 645                 mh = null;
 646             }




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.invoke.util;
  27 
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodHandles.Lookup;
  31 import java.lang.invoke.MethodType;
  32 import jdk.internal.vm.annotation.Stable;
  33 
  34 public class ValueConversions {
  35     private static final Class<?> THIS_CLASS = ValueConversions.class;
  36     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
  37 
  38     /**
  39      * Thread-safe canonicalized mapping from Wrapper to MethodHandle
  40      * with unsynchronized reads and synchronized writes.
  41      * It's safe to publish MethodHandles by data race because they are immutable.
  42      */
  43     private static class WrapperCache {
  44         @Stable
  45         private final MethodHandle[] map = new MethodHandle[Wrapper.COUNT];
  46 
  47         public MethodHandle get(Wrapper w) {
  48             return map[w.ordinal()];
  49         }
  50         public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) {
  51             MethodHandle prev = map[w.ordinal()];
  52             if (prev != null) {
  53                 return prev;
  54             } else {
  55                 map[w.ordinal()] = mh;
  56                 return mh;
  57             }
  58         }
  59     }
  60 
  61     private static WrapperCache[] newWrapperCaches(int n) {
  62         WrapperCache[] caches = new WrapperCache[n];
  63         for (int i = 0; i < n; i++)
  64             caches[i] = new WrapperCache();
  65         return caches;
  66     }
  67 
  68     /// Converting references to values.
  69 
  70     // There are several levels of this unboxing conversions:
  71     //   no conversions:  exactly Integer.valueOf, etc.
  72     //   implicit conversions sanctioned by JLS 5.1.2, etc.
  73     //   explicit conversions as allowed by explicitCastArguments
  74 
  75     static int unboxInteger(Integer x) {
  76         return x;
  77     }
  78     static int unboxInteger(Object x, boolean cast) {
  79         if (x instanceof Integer)


 611     static short booleanToShort(boolean x) {
 612         return fromBoolean(x);
 613     }
 614     static char booleanToChar(boolean x) {
 615         return (char)fromBoolean(x);
 616     }
 617     static byte booleanToByte(boolean x) {
 618         return fromBoolean(x);
 619     }
 620 
 621     // helpers to force boolean into the conversion scheme:
 622     static boolean toBoolean(byte x) {
 623         // see javadoc for MethodHandles.explicitCastArguments
 624         return ((x & 1) != 0);
 625     }
 626     static byte fromBoolean(boolean x) {
 627         // see javadoc for MethodHandles.explicitCastArguments
 628         return (x ? (byte)1 : (byte)0);
 629     }
 630 
 631     private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.COUNT);
 632 
 633     public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) {
 634         WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];
 635         MethodHandle mh = cache.get(wdst);
 636         if (mh != null) {
 637             return mh;
 638         }
 639         // slow path
 640         Class<?> src = wsrc.primitiveType();
 641         Class<?> dst = wdst.primitiveType();
 642         MethodType type = MethodType.methodType(dst, src);
 643         if (wsrc == wdst) {
 644             mh = MethodHandles.identity(src);
 645         } else {
 646             assert(src.isPrimitive() && dst.isPrimitive());
 647             try {
 648                 mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type);
 649             } catch (ReflectiveOperationException ex) {
 650                 mh = null;
 651             }


< prev index next >