jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
changeset 31802 cb6542e7d329
parent 31671 362e0c0acece
child 33841 1d1d1ea6a5f2
equal deleted inserted replaced
31801:1297473ab237 31802:cb6542e7d329
     1 /*
     1 /*
     2  * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   217         for (int i = 0; i < convSpecs.length-1; i++) {
   217         for (int i = 0; i < convSpecs.length-1; i++) {
   218             Object convSpec = convSpecs[i];
   218             Object convSpec = convSpecs[i];
   219             if (convSpec == null)  continue;
   219             if (convSpec == null)  continue;
   220             MethodHandle fn;
   220             MethodHandle fn;
   221             if (convSpec instanceof Class) {
   221             if (convSpec instanceof Class) {
   222                 fn = Lazy.MH_castReference.bindTo(convSpec);
   222                 fn = Lazy.MH_cast.bindTo(convSpec);
   223             } else {
   223             } else {
   224                 fn = (MethodHandle) convSpec;
   224                 fn = (MethodHandle) convSpec;
   225             }
   225             }
   226             Class<?> newType = basicSrcType.parameterType(i);
   226             Class<?> newType = basicSrcType.parameterType(i);
   227             if (--convCount == 0)
   227             if (--convCount == 0)
   237             MethodHandle fn;
   237             MethodHandle fn;
   238             if (convSpec instanceof Class) {
   238             if (convSpec instanceof Class) {
   239                 if (convSpec == void.class)
   239                 if (convSpec == void.class)
   240                     fn = null;
   240                     fn = null;
   241                 else
   241                 else
   242                     fn = Lazy.MH_castReference.bindTo(convSpec);
   242                     fn = Lazy.MH_cast.bindTo(convSpec);
   243             } else {
   243             } else {
   244                 fn = (MethodHandle) convSpec;
   244                 fn = (MethodHandle) convSpec;
   245             }
   245             }
   246             Class<?> newType = basicSrcType.returnType();
   246             Class<?> newType = basicSrcType.returnType();
   247             assert(--convCount == 0);
   247             assert(--convCount == 0);
   300             }
   300             }
   301 
   301 
   302             Name conv;
   302             Name conv;
   303             if (convSpec instanceof Class) {
   303             if (convSpec instanceof Class) {
   304                 Class<?> convClass = (Class<?>) convSpec;
   304                 Class<?> convClass = (Class<?>) convSpec;
   305                 conv = new Name(Lazy.MH_castReference, convClass, names[INARG_BASE + i]);
   305                 conv = new Name(Lazy.MH_cast, convClass, names[INARG_BASE + i]);
   306             } else {
   306             } else {
   307                 MethodHandle fn = (MethodHandle) convSpec;
   307                 MethodHandle fn = (MethodHandle) convSpec;
   308                 conv = new Name(fn, names[INARG_BASE + i]);
   308                 conv = new Name(fn, names[INARG_BASE + i]);
   309             }
   309             }
   310             assert(names[nameCursor] == null);
   310             assert(names[nameCursor] == null);
   324             Name conv;
   324             Name conv;
   325             if (convSpec == void.class) {
   325             if (convSpec == void.class) {
   326                 conv = new Name(LambdaForm.constantZero(BasicType.basicType(srcType.returnType())));
   326                 conv = new Name(LambdaForm.constantZero(BasicType.basicType(srcType.returnType())));
   327             } else if (convSpec instanceof Class) {
   327             } else if (convSpec instanceof Class) {
   328                 Class<?> convClass = (Class<?>) convSpec;
   328                 Class<?> convClass = (Class<?>) convSpec;
   329                 conv = new Name(Lazy.MH_castReference, convClass, names[OUT_CALL]);
   329                 conv = new Name(Lazy.MH_cast, convClass, names[OUT_CALL]);
   330             } else {
   330             } else {
   331                 MethodHandle fn = (MethodHandle) convSpec;
   331                 MethodHandle fn = (MethodHandle) convSpec;
   332                 if (fn.type().parameterCount() == 0)
   332                 if (fn.type().parameterCount() == 0)
   333                     conv = new Name(fn);  // don't pass retval to void conversion
   333                     conv = new Name(fn);  // don't pass retval to void conversion
   334                 else
   334                 else
   339             assert(RETURN_CONV == names.length-1);
   339             assert(RETURN_CONV == names.length-1);
   340         }
   340         }
   341 
   341 
   342         LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names, RESULT);
   342         LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names, RESULT);
   343         return SimpleMethodHandle.make(srcType, form);
   343         return SimpleMethodHandle.make(srcType, form);
   344     }
       
   345 
       
   346     /**
       
   347      * Identity function, with reference cast.
       
   348      * @param t an arbitrary reference type
       
   349      * @param x an arbitrary reference value
       
   350      * @return the same value x
       
   351      */
       
   352     @ForceInline
       
   353     @SuppressWarnings("unchecked")
       
   354     static <T,U> T castReference(Class<? extends T> t, U x) {
       
   355         // inlined Class.cast because we can't ForceInline it
       
   356         if (x != null && !t.isInstance(x))
       
   357             throw newClassCastException(t, x);
       
   358         return (T) x;
       
   359     }
       
   360 
       
   361     private static ClassCastException newClassCastException(Class<?> t, Object obj) {
       
   362         return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
       
   363     }
   344     }
   364 
   345 
   365     static Object[] computeValueConversions(MethodType srcType, MethodType dstType,
   346     static Object[] computeValueConversions(MethodType srcType, MethodType dstType,
   366                                             boolean strict, boolean monobox) {
   347                                             boolean strict, boolean monobox) {
   367         final int INARG_COUNT = srcType.parameterCount();
   348         final int INARG_COUNT = srcType.parameterCount();
   589      * Pre-initialized NamedFunctions for bootstrapping purposes.
   570      * Pre-initialized NamedFunctions for bootstrapping purposes.
   590      * Factored in an inner class to delay initialization until first usage.
   571      * Factored in an inner class to delay initialization until first usage.
   591      */
   572      */
   592     static class Lazy {
   573     static class Lazy {
   593         private static final Class<?> MHI = MethodHandleImpl.class;
   574         private static final Class<?> MHI = MethodHandleImpl.class;
       
   575         private static final Class<?> CLS = Class.class;
   594 
   576 
   595         private static final MethodHandle[] ARRAYS;
   577         private static final MethodHandle[] ARRAYS;
   596         private static final MethodHandle[] FILL_ARRAYS;
   578         private static final MethodHandle[] FILL_ARRAYS;
   597 
   579 
   598         static final NamedFunction NF_checkSpreadArgument;
   580         static final NamedFunction NF_checkSpreadArgument;
   599         static final NamedFunction NF_guardWithCatch;
   581         static final NamedFunction NF_guardWithCatch;
   600         static final NamedFunction NF_throwException;
   582         static final NamedFunction NF_throwException;
   601         static final NamedFunction NF_profileBoolean;
   583         static final NamedFunction NF_profileBoolean;
   602 
   584 
   603         static final MethodHandle MH_castReference;
   585         static final MethodHandle MH_cast;
   604         static final MethodHandle MH_selectAlternative;
   586         static final MethodHandle MH_selectAlternative;
   605         static final MethodHandle MH_copyAsPrimitiveArray;
   587         static final MethodHandle MH_copyAsPrimitiveArray;
   606         static final MethodHandle MH_fillNewTypedArray;
   588         static final MethodHandle MH_fillNewTypedArray;
   607         static final MethodHandle MH_fillNewArray;
   589         static final MethodHandle MH_fillNewArray;
   608         static final MethodHandle MH_arrayIdentity;
   590         static final MethodHandle MH_arrayIdentity;
   621                 NF_checkSpreadArgument.resolve();
   603                 NF_checkSpreadArgument.resolve();
   622                 NF_guardWithCatch.resolve();
   604                 NF_guardWithCatch.resolve();
   623                 NF_throwException.resolve();
   605                 NF_throwException.resolve();
   624                 NF_profileBoolean.resolve();
   606                 NF_profileBoolean.resolve();
   625 
   607 
   626                 MH_castReference        = IMPL_LOOKUP.findStatic(MHI, "castReference",
   608                 MH_cast                 = IMPL_LOOKUP.findVirtual(CLS, "cast",
   627                                             MethodType.methodType(Object.class, Class.class, Object.class));
   609                                             MethodType.methodType(Object.class, Object.class));
   628                 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
   610                 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
   629                                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
   611                                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
   630                 MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
   612                 MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
   631                                             MethodType.methodType(Object[].class, Object[].class));
   613                                             MethodType.methodType(Object[].class, Object[].class));
   632                 MH_fillNewArray         = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
   614                 MH_fillNewArray         = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",