< prev index next >

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

Print this page
rev 48994 : 8198831: Lazy initialization of ValueConversions MethodHandles
Reviewed-by: tbd


 360     static float zeroFloat() {
 361         return 0;
 362     }
 363 
 364     static double zeroDouble() {
 365         return 0;
 366     }
 367 
 368     private static final WrapperCache[] CONSTANT_FUNCTIONS = newWrapperCaches(2);
 369 
 370     public static MethodHandle zeroConstantFunction(Wrapper wrap) {
 371         WrapperCache cache = CONSTANT_FUNCTIONS[0];
 372         MethodHandle mh = cache.get(wrap);
 373         if (mh != null) {
 374             return mh;
 375         }
 376         // slow path
 377         MethodType type = MethodType.methodType(wrap.primitiveType());
 378         switch (wrap) {
 379             case VOID:
 380                 mh = EMPTY;
 381                 break;
 382             case OBJECT:
 383             case INT: case LONG: case FLOAT: case DOUBLE:
 384                 try {
 385                     mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.wrapperSimpleName(), type);
 386                 } catch (ReflectiveOperationException ex) {
 387                     mh = null;
 388                 }
 389                 break;
 390         }
 391         if (mh != null) {
 392             return cache.put(wrap, mh);
 393         }
 394 
 395         // use zeroInt and cast the result
 396         if (wrap.isSubwordOrInt() && wrap != Wrapper.INT) {
 397             mh = MethodHandles.explicitCastArguments(zeroConstantFunction(Wrapper.INT), type);
 398             return cache.put(wrap, mh);
 399         }
 400         throw new IllegalArgumentException("cannot find zero constant for " + wrap);
 401     }
 402 
 403     private static final MethodHandle CAST_REFERENCE, IGNORE, EMPTY;

 404     static {
 405         try {
 406             MethodType idType = MethodType.genericMethodType(1);
 407             MethodType ignoreType = idType.changeReturnType(void.class);
 408             CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
 409             IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
 410             EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
 411         } catch (NoSuchMethodException | IllegalAccessException ex) {
 412             throw newInternalError("uncaught exception", ex);
 413         }
 414     }

 415 
 416     public static MethodHandle ignore() {
 417         return IGNORE;
 418     }
 419 
 420     /** Return a method that casts its second argument (an Object) to the given type (a Class). */
 421     public static MethodHandle cast() {
 422         return CAST_REFERENCE;
 423     }
 424 
 425     /// Primitive conversions.
 426     // These are supported directly by the JVM, usually by a single instruction.
 427     // In the case of narrowing to a subword, there may be a pair of instructions.
 428     // In the case of booleans, there may be a helper routine to manage a 1-bit value.
 429     // This is the full 8x8 matrix (minus the diagonal).
 430 
 431     // narrow double to all other types:
 432     static float doubleToFloat(double x) {  // bytecode: d2f
 433         return (float) x;
 434     }
 435     static long doubleToLong(double x) {  // bytecode: d2l
 436         return (long) x;
 437     }
 438     static int doubleToInt(double x) {  // bytecode: d2i
 439         return (int) x;
 440     }
 441     static short doubleToShort(double x) {  // bytecodes: d2i, i2s
 442         return (short) x;




 360     static float zeroFloat() {
 361         return 0;
 362     }
 363 
 364     static double zeroDouble() {
 365         return 0;
 366     }
 367 
 368     private static final WrapperCache[] CONSTANT_FUNCTIONS = newWrapperCaches(2);
 369 
 370     public static MethodHandle zeroConstantFunction(Wrapper wrap) {
 371         WrapperCache cache = CONSTANT_FUNCTIONS[0];
 372         MethodHandle mh = cache.get(wrap);
 373         if (mh != null) {
 374             return mh;
 375         }
 376         // slow path
 377         MethodType type = MethodType.methodType(wrap.primitiveType());
 378         switch (wrap) {
 379             case VOID:
 380                 mh = Handles.EMPTY;
 381                 break;
 382             case OBJECT:
 383             case INT: case LONG: case FLOAT: case DOUBLE:
 384                 try {
 385                     mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.wrapperSimpleName(), type);
 386                 } catch (ReflectiveOperationException ex) {
 387                     mh = null;
 388                 }
 389                 break;
 390         }
 391         if (mh != null) {
 392             return cache.put(wrap, mh);
 393         }
 394 
 395         // use zeroInt and cast the result
 396         if (wrap.isSubwordOrInt() && wrap != Wrapper.INT) {
 397             mh = MethodHandles.explicitCastArguments(zeroConstantFunction(Wrapper.INT), type);
 398             return cache.put(wrap, mh);
 399         }
 400         throw new IllegalArgumentException("cannot find zero constant for " + wrap);
 401     }
 402 
 403     private static class Handles {
 404         static final MethodHandle CAST_REFERENCE, IGNORE, EMPTY;
 405         static {
 406             try {
 407                 MethodType idType = MethodType.genericMethodType(1);
 408                 MethodType ignoreType = idType.changeReturnType(void.class);
 409                 CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
 410                 IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
 411                 EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
 412             } catch (NoSuchMethodException | IllegalAccessException ex) {
 413                 throw newInternalError("uncaught exception", ex);
 414             }
 415         }
 416     }
 417 
 418     public static MethodHandle ignore() {
 419         return Handles.IGNORE;
 420     }
 421 
 422     /** Return a method that casts its second argument (an Object) to the given type (a Class). */
 423     public static MethodHandle cast() {
 424         return Handles.CAST_REFERENCE;
 425     }
 426 
 427     /// Primitive conversions.
 428     // These are supported directly by the JVM, usually by a single instruction.
 429     // In the case of narrowing to a subword, there may be a pair of instructions.
 430     // In the case of booleans, there may be a helper routine to manage a 1-bit value.
 431     // This is the full 8x8 matrix (minus the diagonal).
 432 
 433     // narrow double to all other types:
 434     static float doubleToFloat(double x) {  // bytecode: d2f
 435         return (float) x;
 436     }
 437     static long doubleToLong(double x) {  // bytecode: d2l
 438         return (long) x;
 439     }
 440     static int doubleToInt(double x) {  // bytecode: d2i
 441         return (int) x;
 442     }
 443     static short doubleToShort(double x) {  // bytecodes: d2i, i2s
 444         return (short) x;


< prev index next >