jdk/src/share/classes/sun/dyn/util/ValueConversions.java
changeset 8821 2836ee97ee27
parent 8347 e5daa5772ffd
equal deleted inserted replaced
8693:2173b8120b13 8821:2836ee97ee27
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.dyn.util;
    26 package sun.dyn.util;
    27 
    27 
    28 import java.dyn.*;
    28 import java.dyn.MethodHandle;
       
    29 import java.dyn.MethodHandles;
    29 import java.dyn.MethodHandles.Lookup;
    30 import java.dyn.MethodHandles.Lookup;
       
    31 import java.dyn.MethodType;
    30 import java.util.ArrayList;
    32 import java.util.ArrayList;
    31 import java.util.Arrays;
    33 import java.util.Arrays;
    32 import java.util.EnumMap;
    34 import java.util.EnumMap;
    33 import java.util.List;
    35 import java.util.List;
    34 import sun.dyn.Access;
       
    35 import sun.dyn.AdapterMethodHandle;
       
    36 import sun.dyn.MethodHandleImpl;
       
    37 import static sun.dyn.MemberName.uncaughtException;
       
    38 
    36 
    39 public class ValueConversions {
    37 public class ValueConversions {
    40     private static final Access IMPL_TOKEN = Access.getToken();
    38     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
    41     private static final Lookup IMPL_LOOKUP = MethodHandleImpl.getLookup(IMPL_TOKEN);
       
    42 
    39 
    43     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
    40     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
    44         @SuppressWarnings("unchecked")
    41         @SuppressWarnings("unchecked")
    45         EnumMap<Wrapper, MethodHandle>[] caches
    42         EnumMap<Wrapper, MethodHandle>[] caches
    46                 = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n];  // unchecked warning expected here
    43                 = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n];  // unchecked warning expected here
   155                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
   152                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
   156             } catch (ReflectiveOperationException ex) {
   153             } catch (ReflectiveOperationException ex) {
   157                 mh = null;
   154                 mh = null;
   158             }
   155             }
   159         } else {
   156         } else {
   160             mh = retype(type, unbox(wrap, !exact, raw));
   157             mh = unbox(wrap, !exact, raw).asType(type);
   161         }
   158         }
   162         if (mh != null) {
   159         if (mh != null) {
   163             cache.put(wrap, mh);
   160             cache.put(wrap, mh);
   164             return mh;
   161             return mh;
   165         }
   162         }
   291                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   288                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   292             } catch (ReflectiveOperationException ex) {
   289             } catch (ReflectiveOperationException ex) {
   293                 mh = null;
   290                 mh = null;
   294             }
   291             }
   295         } else {
   292         } else {
   296             mh = retype(type.erase(), box(wrap, !exact, raw));
   293             mh = box(wrap, !exact, raw).asType(type.erase());
   297         }
   294         }
   298         if (mh != null) {
   295         if (mh != null) {
   299             cache.put(wrap, mh);
   296             cache.put(wrap, mh);
   300             return mh;
   297             return mh;
   301         }
   298         }
   410                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   407                 mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   411             } catch (ReflectiveOperationException ex) {
   408             } catch (ReflectiveOperationException ex) {
   412                 mh = null;
   409                 mh = null;
   413             }
   410             }
   414         } else {
   411         } else {
   415             mh = retype(IDENTITY.type(), rebox(wrap, !exact));
   412             mh = rebox(wrap, !exact).asType(IDENTITY.type());
   416         }
   413         }
   417         if (mh != null) {
   414         if (mh != null) {
   418             cache.put(wrap, mh);
   415             cache.put(wrap, mh);
   419             return mh;
   416             return mh;
   420         }
   417         }
   502             return mh;
   499             return mh;
   503         }
   500         }
   504 
   501 
   505         // use the raw method
   502         // use the raw method
   506         Wrapper rawWrap = wrap.rawPrimitive();
   503         Wrapper rawWrap = wrap.rawPrimitive();
   507         if (rawWrap != wrap) {
   504         if (mh == null && rawWrap != wrap) {
   508             mh = retype(type, zeroConstantFunction(rawWrap));
   505             mh = MethodHandles.explicitCastArguments(zeroConstantFunction(rawWrap), type);
   509         }
   506         }
   510         if (mh != null) {
   507         if (mh != null) {
   511             cache.put(wrap, mh);
   508             cache.put(wrap, mh);
   512             return mh;
   509             return mh;
   513         }
   510         }
   550      */
   547      */
   551     static int identity(int x) {
   548     static int identity(int x) {
   552         return x;
   549         return x;
   553     }
   550     }
   554 
   551 
       
   552     static byte identity(byte x) {
       
   553         return x;
       
   554     }
       
   555 
       
   556     static short identity(short x) {
       
   557         return x;
       
   558     }
       
   559 
       
   560     static boolean identity(boolean x) {
       
   561         return x;
       
   562     }
       
   563 
       
   564     static char identity(char x) {
       
   565         return x;
       
   566     }
       
   567 
   555     /**
   568     /**
   556      * Identity function on longs.
   569      * Identity function on longs.
   557      * @param x an arbitrary long value
   570      * @param x an arbitrary long value
   558      * @return the same value x
   571      * @return the same value x
   559      */
   572      */
   560     static long identity(long x) {
   573     static long identity(long x) {
       
   574         return x;
       
   575     }
       
   576 
       
   577     static float identity(float x) {
       
   578         return x;
       
   579     }
       
   580 
       
   581     static double identity(double x) {
   561         return x;
   582         return x;
   562     }
   583     }
   563 
   584 
   564     /**
   585     /**
   565      * Identity function, with reference cast.
   586      * Identity function, with reference cast.
   588             ALWAYS_ZERO = IMPL_LOOKUP.findStatic(ValueConversions.class, "alwaysZero", alwaysZeroType);
   609             ALWAYS_ZERO = IMPL_LOOKUP.findStatic(ValueConversions.class, "alwaysZero", alwaysZeroType);
   589             ZERO_OBJECT = IMPL_LOOKUP.findStatic(ValueConversions.class, "zeroObject", zeroObjectType);
   610             ZERO_OBJECT = IMPL_LOOKUP.findStatic(ValueConversions.class, "zeroObject", zeroObjectType);
   590             IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType);
   611             IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType);
   591             EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1));
   612             EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1));
   592         } catch (Exception ex) {
   613         } catch (Exception ex) {
   593             throw uncaughtException(ex);
   614             Error err = new InternalError("uncaught exception");
       
   615             err.initCause(ex);
       
   616             throw err;
   594         }
   617         }
   595     }
   618     }
   596 
   619 
   597     private static final EnumMap<Wrapper, MethodHandle> WRAPPER_CASTS
   620     private static final EnumMap<Wrapper, MethodHandle> WRAPPER_CASTS
   598             = new EnumMap<Wrapper, MethodHandle>(Wrapper.class);
   621             = new EnumMap<Wrapper, MethodHandle>(Wrapper.class);
   620             mh = ALWAYS_NULL;
   643             mh = ALWAYS_NULL;
   621         else
   644         else
   622             mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
   645             mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
   623         if (exact) {
   646         if (exact) {
   624             MethodType xmt = MethodType.methodType(type, Object.class);
   647             MethodType xmt = MethodType.methodType(type, Object.class);
   625             mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
   648             mh = MethodHandles.explicitCastArguments(mh, xmt);
       
   649             //mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
   626         }
   650         }
   627         if (cache != null)
   651         if (cache != null)
   628             cache.put(wrap, mh);
   652             cache.put(wrap, mh);
   629         return mh;
   653         return mh;
   630     }
   654     }
   632     public static MethodHandle identity() {
   656     public static MethodHandle identity() {
   633         return IDENTITY;
   657         return IDENTITY;
   634     }
   658     }
   635 
   659 
   636     public static MethodHandle identity(Class<?> type) {
   660     public static MethodHandle identity(Class<?> type) {
   637         if (type == Object.class)
   661         // This stuff has been moved into MethodHandles:
   638             return IDENTITY;
   662         return MethodHandles.identity(type);
   639         else if (!type.isPrimitive())
   663     }
   640             return retype(MethodType.methodType(type, type), IDENTITY);
   664 
   641         else
   665     public static MethodHandle identity(Wrapper wrap) {
   642             return identity(Wrapper.forPrimitiveType(type));
       
   643     }
       
   644 
       
   645     static MethodHandle identity(Wrapper wrap) {
       
   646         EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[1];
   666         EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[1];
   647         MethodHandle mh = cache.get(wrap);
   667         MethodHandle mh = cache.get(wrap);
   648         if (mh != null) {
   668         if (mh != null) {
   649             return mh;
   669             return mh;
   650         }
   670         }
   663         if (mh != null) {
   683         if (mh != null) {
   664             cache.put(wrap, mh);
   684             cache.put(wrap, mh);
   665             return mh;
   685             return mh;
   666         }
   686         }
   667 
   687 
   668         // use a raw conversion
       
   669         if (wrap.isSingleWord() && wrap != Wrapper.INT) {
       
   670             mh = retype(type, identity(Wrapper.INT));
       
   671         } else if (wrap.isDoubleWord() && wrap != Wrapper.LONG) {
       
   672             mh = retype(type, identity(Wrapper.LONG));
       
   673         }
       
   674         if (mh != null) {
   688         if (mh != null) {
   675             cache.put(wrap, mh);
   689             cache.put(wrap, mh);
   676             return mh;
   690             return mh;
   677         }
   691         }
   678         throw new IllegalArgumentException("cannot find identity for " + wrap);
   692         throw new IllegalArgumentException("cannot find identity for " + wrap);
   679     }
       
   680 
       
   681     private static MethodHandle retype(MethodType type, MethodHandle mh) {
       
   682         return AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, type, mh);
       
   683     }
   693     }
   684 
   694 
   685     private static final Object[] NO_ARGS_ARRAY = {};
   695     private static final Object[] NO_ARGS_ARRAY = {};
   686     private static Object[] makeArray(Object... args) { return args; }
   696     private static Object[] makeArray(Object... args) { return args; }
   687     private static Object[] array() { return NO_ARGS_ARRAY; }
   697     private static Object[] array() { return NO_ARGS_ARRAY; }