src/share/classes/java/lang/invoke/MethodType.java

Print this page
rev 8095 : JDK-8024635 v2
rev 8096 : JDK-8024635 v2


  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 java.lang.invoke;
  27 
  28 import sun.invoke.util.Wrapper;
  29 import java.lang.ref.WeakReference;
  30 import java.lang.ref.Reference;
  31 import java.lang.ref.ReferenceQueue;
  32 import java.util.Arrays;
  33 import java.util.Collections;
  34 import java.util.List;

  35 import java.util.concurrent.ConcurrentMap;
  36 import java.util.concurrent.ConcurrentHashMap;
  37 import sun.invoke.util.BytecodeDescriptor;
  38 import static java.lang.invoke.MethodHandleStatics.*;
  39 import sun.invoke.util.VerifyType;
  40 
  41 /**
  42  * A method type represents the arguments and return type accepted and
  43  * returned by a method handle, or the arguments and return type passed
  44  * and expected  by a method handle caller.  Method types must be properly
  45  * matched between a method handle and all its callers,
  46  * and the JVM's operations enforce this matching at, specifically
  47  * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
  48  * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
  49  * of {@code invokedynamic} instructions.
  50  * <p>
  51  * The structure is a return type accompanied by any number of parameter types.
  52  * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
  53  * (For ease of exposition, we treat {@code void} as if it were a type.
  54  * In fact, it denotes the absence of a return type.)


  80  * For more details, see the <a href="package-summary.html#mtcon">package summary</a>.
  81  * <p>
  82  * When the JVM materializes a {@code MethodType} from a descriptor string,
  83  * all classes named in the descriptor must be accessible, and will be loaded.
  84  * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
  85  * This loading may occur at any time before the {@code MethodType} object is first derived.
  86  * @author John Rose, JSR 292 EG
  87  */
  88 public final
  89 class MethodType implements java.io.Serializable {
  90     private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
  91 
  92     // The rtype and ptypes fields define the structural identity of the method type:
  93     private final Class<?>   rtype;
  94     private final Class<?>[] ptypes;
  95 
  96     // The remaining fields are caches of various sorts:
  97     private MethodTypeForm form; // erased form, plus cached data about primitives
  98     private MethodType wrapAlt;  // alternative wrapped/unwrapped version
  99     private Invokers invokers;   // cache of handy higher-order adapters

 100 
 101     /**
 102      * Check the given parameters for validity and store them into the final fields.
 103      */
 104     private MethodType(Class<?> rtype, Class<?>[] ptypes) {
 105         checkRtype(rtype);
 106         checkPtypes(ptypes);
 107         this.rtype = rtype;









 108         this.ptypes = ptypes;
 109     }
 110 
 111     /*trusted*/ MethodTypeForm form() { return form; }
 112     /*trusted*/ Class<?> rtype() { return rtype; }
 113     /*trusted*/ Class<?>[] ptypes() { return ptypes; }
 114 
 115     void setForm(MethodTypeForm f) { form = f; }
 116 
 117     /** This number, mandated by the JVM spec as 255,
 118      *  is the maximum number of <em>slots</em>
 119      *  that any Java method can receive in its argument list.
 120      *  It limits both JVM signatures and method type objects.
 121      *  The longest possible invocation will look like
 122      *  {@code staticMethod(arg1, arg2, ..., arg255)} or
 123      *  {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
 124      */
 125     /*non-public*/ static final int MAX_JVM_ARITY = 255;  // this is mandated by the JVM spec.
 126 
 127     /** This number is the maximum arity of a method handle, 254.
 128      *  It is derived from the absolute JVM-imposed arity by subtracting one,
 129      *  which is the slot occupied by the method handle itself at the
 130      *  beginning of the argument list used to invoke the method handle.
 131      *  The longest possible invocation will look like
 132      *  {@code mh.invoke(arg1, arg2, ..., arg254)}.
 133      */
 134     // Issue:  Should we allow MH.invokeWithArguments to go to the full 255?
 135     /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1;  // deduct one for mh receiver
 136 
 137     /** This number is the maximum arity of a method handle invoker, 253.
 138      *  It is derived from the absolute JVM-imposed arity by subtracting two,
 139      *  which are the slots occupied by invoke method handle, and the the
 140      *  target method handle, which are both at the beginning of the argument
 141      *  list used to invoke the target method handle.
 142      *  The longest possible invocation will look like
 143      *  {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
 144      */
 145     /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1;  // deduct one more for invoker
 146 
 147     private static void checkRtype(Class<?> rtype) {
 148         rtype.equals(rtype);  // null check
 149     }
 150     private static int checkPtype(Class<?> ptype) {
 151         ptype.getClass();  //NPE
 152         if (ptype == void.class)
 153             throw newIllegalArgumentException("parameter type cannot be void");
 154         if (ptype == double.class || ptype == long.class)  return 1;
 155         return 0;
 156     }
 157     /** Return number of extra slots (count of long/double args). */
 158     private static int checkPtypes(Class<?>[] ptypes) {
 159         int slots = 0;
 160         for (Class<?> ptype : ptypes) {
 161             slots += checkPtype(ptype);
 162         }
 163         checkSlotCount(ptypes.length + slots);
 164         return slots;
 165     }
 166     static void checkSlotCount(int count) {
 167         assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
 168         // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
 169         if ((count & MAX_JVM_ARITY) != count)
 170             throw newIllegalArgumentException("bad parameter count "+count);
 171     }


 266      * and the specified return type.
 267      * @param rtype  the return type
 268      * @param ptypes the method type which supplies the parameter types
 269      * @return a method type with the given components
 270      * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
 271      */
 272     public static
 273     MethodType methodType(Class<?> rtype, MethodType ptypes) {
 274         return makeImpl(rtype, ptypes.ptypes, true);
 275     }
 276 
 277     /**
 278      * Sole factory method to find or create an interned method type.
 279      * @param rtype desired return type
 280      * @param ptypes desired parameter types
 281      * @param trusted whether the ptypes can be used without cloning
 282      * @return the unique method type of the desired structure
 283      */
 284     /*trusted*/ static
 285     MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {



 286         if (ptypes.length == 0) {
 287             ptypes = NO_PTYPES; trusted = true;
 288         }
 289         MethodType mt1 = new MethodType(rtype, ptypes);
 290         MethodType mt0 = internTable.get(mt1);
 291         if (mt0 != null)
 292             return mt0;
 293         if (!trusted)
 294             // defensively copy the array passed in by the user
 295             mt1 = new MethodType(rtype, ptypes.clone());
 296         // promote the object to the Real Thing, and reprobe
 297         MethodTypeForm form = MethodTypeForm.findForm(mt1);
 298         mt1.form = form;
 299         return internTable.add(mt1);
 300     }
 301     private static final MethodType[] objectOnlyTypes = new MethodType[20];
 302 
 303     /**
 304      * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
 305      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
 306      * All parameters and the return type will be {@code Object},
 307      * except the final array parameter if any, which will be {@code Object[]}.
 308      * @param objectArgCount number of parameters (excluding the final array parameter if any)
 309      * @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
 310      * @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
 311      * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray} is true)
 312      * @see #genericMethodType(int)
 313      */
 314     public static
 315     MethodType genericMethodType(int objectArgCount, boolean finalArray) {
 316         MethodType mt;
 317         checkSlotCount(objectArgCount);
 318         int ivarargs = (!finalArray ? 0 : 1);
 319         int ootIndex = objectArgCount*2 + ivarargs;


 901         Class<?> rtype = types.remove(types.size() - 1);
 902         checkSlotCount(types.size());
 903         Class<?>[] ptypes = listToArray(types);
 904         return makeImpl(rtype, ptypes, true);
 905     }
 906 
 907     /**
 908      * Produces a bytecode descriptor representation of the method type.
 909      * <p>
 910      * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
 911      * Two distinct classes which share a common name but have different class loaders
 912      * will appear identical when viewed within descriptor strings.
 913      * <p>
 914      * This method is included for the benfit of applications that must
 915      * generate bytecodes that process method handles and {@code invokedynamic}.
 916      * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
 917      * because the latter requires a suitable class loader argument.
 918      * @return the bytecode type descriptor representation
 919      */
 920     public String toMethodDescriptorString() {
 921         return BytecodeDescriptor.unparse(this);





 922     }
 923 
 924     /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
 925         return BytecodeDescriptor.unparse(cls);
 926     }
 927 
 928     /// Serialization.
 929 
 930     /**
 931      * There are no serializable fields for {@code MethodType}.
 932      */
 933     private static final java.io.ObjectStreamField[] serialPersistentFields = { };
 934 
 935     /**
 936      * Save the {@code MethodType} instance to a stream.
 937      *
 938      * @serialData
 939      * For portability, the serialized format does not refer to named fields.
 940      * Instead, the return type and parameter type arrays are written directly
 941      * from the {@code writeObject} method, using two calls to {@code s.writeObject}




  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 java.lang.invoke;
  27 
  28 import sun.invoke.util.Wrapper;
  29 import java.lang.ref.WeakReference;
  30 import java.lang.ref.Reference;
  31 import java.lang.ref.ReferenceQueue;
  32 import java.util.Arrays;
  33 import java.util.Collections;
  34 import java.util.List;
  35 import java.util.Objects;
  36 import java.util.concurrent.ConcurrentMap;
  37 import java.util.concurrent.ConcurrentHashMap;
  38 import sun.invoke.util.BytecodeDescriptor;
  39 import static java.lang.invoke.MethodHandleStatics.*;
  40 import sun.invoke.util.VerifyType;
  41 
  42 /**
  43  * A method type represents the arguments and return type accepted and
  44  * returned by a method handle, or the arguments and return type passed
  45  * and expected  by a method handle caller.  Method types must be properly
  46  * matched between a method handle and all its callers,
  47  * and the JVM's operations enforce this matching at, specifically
  48  * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
  49  * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
  50  * of {@code invokedynamic} instructions.
  51  * <p>
  52  * The structure is a return type accompanied by any number of parameter types.
  53  * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
  54  * (For ease of exposition, we treat {@code void} as if it were a type.
  55  * In fact, it denotes the absence of a return type.)


  81  * For more details, see the <a href="package-summary.html#mtcon">package summary</a>.
  82  * <p>
  83  * When the JVM materializes a {@code MethodType} from a descriptor string,
  84  * all classes named in the descriptor must be accessible, and will be loaded.
  85  * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
  86  * This loading may occur at any time before the {@code MethodType} object is first derived.
  87  * @author John Rose, JSR 292 EG
  88  */
  89 public final
  90 class MethodType implements java.io.Serializable {
  91     private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
  92 
  93     // The rtype and ptypes fields define the structural identity of the method type:
  94     private final Class<?>   rtype;
  95     private final Class<?>[] ptypes;
  96 
  97     // The remaining fields are caches of various sorts:
  98     private MethodTypeForm form; // erased form, plus cached data about primitives
  99     private MethodType wrapAlt;  // alternative wrapped/unwrapped version
 100     private Invokers invokers;   // cache of handy higher-order adapters
 101     private String methodDescriptor;
 102 
 103     /**
 104      * Check the given parameters for validity and store them into the final fields.
 105      */
 106     private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
 107         checkRtype(rtype);
 108         checkPtypes(ptypes);
 109         this.rtype = rtype;
 110         // defensively copy the array passed in by the user
 111         this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
 112     }
 113 
 114     /**
 115      * Don't check the given parameters for validity - creates MethodType for usage as searching key only.
 116      */
 117     private MethodType(Class<?> rtype, Class<?>[] ptypes) {
 118         this.rtype = rtype;
 119         this.ptypes = ptypes;
 120     }
 121 
 122     /*trusted*/ MethodTypeForm form() { return form; }
 123     /*trusted*/ Class<?> rtype() { return rtype; }
 124     /*trusted*/ Class<?>[] ptypes() { return ptypes; }
 125 
 126     void setForm(MethodTypeForm f) { form = f; }
 127 
 128     /** This number, mandated by the JVM spec as 255,
 129      *  is the maximum number of <em>slots</em>
 130      *  that any Java method can receive in its argument list.
 131      *  It limits both JVM signatures and method type objects.
 132      *  The longest possible invocation will look like
 133      *  {@code staticMethod(arg1, arg2, ..., arg255)} or
 134      *  {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
 135      */
 136     /*non-public*/ static final int MAX_JVM_ARITY = 255;  // this is mandated by the JVM spec.
 137 
 138     /** This number is the maximum arity of a method handle, 254.
 139      *  It is derived from the absolute JVM-imposed arity by subtracting one,
 140      *  which is the slot occupied by the method handle itself at the
 141      *  beginning of the argument list used to invoke the method handle.
 142      *  The longest possible invocation will look like
 143      *  {@code mh.invoke(arg1, arg2, ..., arg254)}.
 144      */
 145     // Issue:  Should we allow MH.invokeWithArguments to go to the full 255?
 146     /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1;  // deduct one for mh receiver
 147 
 148     /** This number is the maximum arity of a method handle invoker, 253.
 149      *  It is derived from the absolute JVM-imposed arity by subtracting two,
 150      *  which are the slots occupied by invoke method handle, and the the
 151      *  target method handle, which are both at the beginning of the argument
 152      *  list used to invoke the target method handle.
 153      *  The longest possible invocation will look like
 154      *  {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
 155      */
 156     /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1;  // deduct one more for invoker
 157 
 158     private static void checkRtype(Class<?> rtype) {
 159         Objects.requireNonNull(rtype);  // null check
 160     }
 161     private static int checkPtype(Class<?> ptype) {
 162         Objects.requireNonNull(ptype);  // null check
 163         if (ptype == void.class)
 164             throw newIllegalArgumentException("parameter type cannot be void");
 165         if (ptype == double.class || ptype == long.class)  return 1;
 166         return 0;
 167     }
 168     /** Return number of extra slots (count of long/double args). */
 169     private static int checkPtypes(Class<?>[] ptypes) {
 170         int slots = 0;
 171         for (Class<?> ptype : ptypes) {
 172             slots += checkPtype(ptype);
 173         }
 174         checkSlotCount(ptypes.length + slots);
 175         return slots;
 176     }
 177     static void checkSlotCount(int count) {
 178         assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
 179         // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
 180         if ((count & MAX_JVM_ARITY) != count)
 181             throw newIllegalArgumentException("bad parameter count "+count);
 182     }


 277      * and the specified return type.
 278      * @param rtype  the return type
 279      * @param ptypes the method type which supplies the parameter types
 280      * @return a method type with the given components
 281      * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
 282      */
 283     public static
 284     MethodType methodType(Class<?> rtype, MethodType ptypes) {
 285         return makeImpl(rtype, ptypes.ptypes, true);
 286     }
 287 
 288     /**
 289      * Sole factory method to find or create an interned method type.
 290      * @param rtype desired return type
 291      * @param ptypes desired parameter types
 292      * @param trusted whether the ptypes can be used without cloning
 293      * @return the unique method type of the desired structure
 294      */
 295     /*trusted*/ static
 296     MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
 297         MethodType mt = internTable.get(new MethodType(rtype, ptypes));
 298         if (mt != null)
 299             return mt;
 300         if (ptypes.length == 0) {
 301             ptypes = NO_PTYPES; trusted = true;
 302         }
 303         mt = new MethodType(rtype, ptypes, trusted);






 304         // promote the object to the Real Thing, and reprobe
 305         mt.form = MethodTypeForm.findForm(mt);
 306         return internTable.add(mt);

 307     }
 308     private static final MethodType[] objectOnlyTypes = new MethodType[20];
 309 
 310     /**
 311      * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
 312      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
 313      * All parameters and the return type will be {@code Object},
 314      * except the final array parameter if any, which will be {@code Object[]}.
 315      * @param objectArgCount number of parameters (excluding the final array parameter if any)
 316      * @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
 317      * @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
 318      * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray} is true)
 319      * @see #genericMethodType(int)
 320      */
 321     public static
 322     MethodType genericMethodType(int objectArgCount, boolean finalArray) {
 323         MethodType mt;
 324         checkSlotCount(objectArgCount);
 325         int ivarargs = (!finalArray ? 0 : 1);
 326         int ootIndex = objectArgCount*2 + ivarargs;


 908         Class<?> rtype = types.remove(types.size() - 1);
 909         checkSlotCount(types.size());
 910         Class<?>[] ptypes = listToArray(types);
 911         return makeImpl(rtype, ptypes, true);
 912     }
 913 
 914     /**
 915      * Produces a bytecode descriptor representation of the method type.
 916      * <p>
 917      * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
 918      * Two distinct classes which share a common name but have different class loaders
 919      * will appear identical when viewed within descriptor strings.
 920      * <p>
 921      * This method is included for the benfit of applications that must
 922      * generate bytecodes that process method handles and {@code invokedynamic}.
 923      * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
 924      * because the latter requires a suitable class loader argument.
 925      * @return the bytecode type descriptor representation
 926      */
 927     public String toMethodDescriptorString() {
 928         String desc = methodDescriptor;
 929         if (desc == null) {
 930             desc = BytecodeDescriptor.unparse(this);
 931             methodDescriptor = desc;
 932         }
 933         return desc;
 934     }
 935 
 936     /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
 937         return BytecodeDescriptor.unparse(cls);
 938     }
 939 
 940     /// Serialization.
 941 
 942     /**
 943      * There are no serializable fields for {@code MethodType}.
 944      */
 945     private static final java.io.ObjectStreamField[] serialPersistentFields = { };
 946 
 947     /**
 948      * Save the {@code MethodType} instance to a stream.
 949      *
 950      * @serialData
 951      * For portability, the serialized format does not refer to named fields.
 952      * Instead, the return type and parameter type arrays are written directly
 953      * from the {@code writeObject} method, using two calls to {@code s.writeObject}