changeset 441:379345d2d26a

meth-info-8008688.patch: first cut
author jrose
date Tue, 23 Apr 2013 23:37:55 -0700
parents 7ee20b0bbd10
children 23f2de08d38b
files meth-info-8008688.patch
diffstat 1 files changed, 903 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meth-info-8008688.patch	Tue Apr 23 23:37:55 2013 -0700
@@ -0,0 +1,903 @@
+8008688: Make MethodHandleInfo public
+Summary: Polish the proposed MethodHandleInfo API.
+Reviewed-by: ?
+
+diff --git a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
+--- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
++++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java
+@@ -102,12 +102,12 @@
+         this.samBase = invokedType.returnType();
+ 
+         this.samMethod = samMethod;
+-        this.samInfo = new MethodHandleInfo(samMethod);
++        this.samInfo = caller.revealDirect(samMethod);
+         this.samClass = samInfo.getDeclaringClass();
+         this.samMethodType  = samInfo.getMethodType();
+ 
+         this.implMethod = implMethod;
+-        this.implInfo = new MethodHandleInfo(implMethod);
++        this.implInfo = caller.revealDirect(implMethod);
+         // @@@ Temporary work-around pending resolution of 8005119
+         this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial)
+                         ? MethodHandleInfo.REF_invokeVirtual
+diff --git a/src/share/classes/java/lang/invoke/LambdaMetafactory.java b/src/share/classes/java/lang/invoke/LambdaMetafactory.java
+--- a/src/share/classes/java/lang/invoke/LambdaMetafactory.java
++++ b/src/share/classes/java/lang/invoke/LambdaMetafactory.java
+@@ -111,7 +111,7 @@
+  * done on return type, while a strict version is applied to arguments.
+  *
+  * <p>A type Q is considered adaptable to S as follows:
+- * <table>
++ * <table summary="adaptable types">
+  *     <tr><th>Q</th><th>S</th><th>Link-time checks</th><th>Capture-time checks</th></tr>
+  *     <tr>
+  *         <td>Primitive</td><td>Primitive</td>
+@@ -174,7 +174,7 @@
+      * @param instantiatedMethodType The signature of the primary functional interface method after type variables
+      *                               are substituted with their instantiation from the capture site
+      * @return a CallSite, which, when invoked, will return an instance of the functional interface
+-     * @throws ReflectiveOperationException
++     * @throws ReflectiveOperationException if the caller is not able to reconstruct one of the method handles
+      * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+      */
+     public static CallSite metaFactory(MethodHandles.Lookup caller,
+@@ -226,7 +226,7 @@
+      *                    the first argument in the invocation signature will correspond to the receiver.
+      * @param  args       argument to pass, flags, marker interface count, and marker interfaces as described above
+      * @return a CallSite, which, when invoked, will return an instance of the functional interface
+-     * @throws ReflectiveOperationException
++     * @throws ReflectiveOperationException if the caller is not able to reconstruct one of the method handles
+      * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+      */
+     public static CallSite altMetaFactory(MethodHandles.Lookup caller,
+diff --git a/src/share/classes/java/lang/invoke/MemberName.java b/src/share/classes/java/lang/invoke/MemberName.java
+--- a/src/share/classes/java/lang/invoke/MemberName.java
++++ b/src/share/classes/java/lang/invoke/MemberName.java
+@@ -236,6 +236,8 @@
+             assert(MethodHandleNatives.refKindIsMethod(refKind));
+             if (clazz.isInterface())
+                 assert(refKind == REF_invokeInterface ||
++                       refKind == REF_invokeStatic ||  //JDK 8
++                       refKind == REF_invokeSpecial || //JDK 8
+                        refKind == REF_invokeVirtual && isObjectPublicMethod());
+         } else {
+             assert(false);
+diff --git a/src/share/classes/java/lang/invoke/MethodHandle.java b/src/share/classes/java/lang/invoke/MethodHandle.java
+--- a/src/share/classes/java/lang/invoke/MethodHandle.java
++++ b/src/share/classes/java/lang/invoke/MethodHandle.java
+@@ -44,7 +44,7 @@
+  * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
+  * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
+  *
+- * <h3>Method handle contents</h3>
++ * <h1>Method handle contents</h1>
+  * Method handles are dynamically and strongly typed according to their parameter and return types.
+  * They are not distinguished by the name or the defining class of their underlying methods.
+  * A method handle must be invoked using a symbolic type descriptor which matches
+@@ -81,7 +81,7 @@
+  * from its specific class, as the method handle class hierarchy (if any)
+  * may change from time to time or across implementations from different vendors.
+  *
+- * <h3>Method handle compilation</h3>
++ * <h1>Method handle compilation</h1>
+  * A Java method call expression naming {@code invokeExact} or {@code invoke}
+  * can invoke a method handle from Java source code.
+  * From the viewpoint of source code, these methods can take any arguments
+@@ -111,7 +111,7 @@
+  * The ambiguity with the type {@code Void} is harmless, since there are no references of type
+  * {@code Void} except the null reference.
+  *
+- * <h3>Method handle invocation</h3>
++ * <h1>Method handle invocation</h1>
+  * The first time a {@code invokevirtual} instruction is executed
+  * it is linked, by symbolically resolving the names in the instruction
+  * and verifying that the method call is statically legal.
+@@ -154,7 +154,7 @@
+  * (<em>Note:</em> The adjusted method handle {@code M2} is not directly observable,
+  * and implementations are therefore not required to materialize it.)
+  *
+- * <h3>Invocation checking</h3>
++ * <h1>Invocation checking</h1>
+  * In typical programs, method handle type matching will usually succeed.
+  * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
+  * either directly (in the case of {@code invokeExact}) or indirectly as if
+@@ -195,7 +195,7 @@
+  * They should not be passed to untrusted code unless their use from
+  * the untrusted code would be harmless.
+  *
+- * <h3>Method handle creation</h3>
++ * <h1>Method handle creation</h1>
+  * Java code can create a method handle that directly accesses
+  * any method, constructor, or field that is accessible to that code.
+  * This is done via a reflective, capability-based API called
+@@ -249,7 +249,7 @@
+  * receiver type.  Such a method handle simulates the effect of
+  * an {@code invokespecial} instruction to the same method.
+  *
+- * <h3>Usage examples</h3>
++ * <h1>Usage examples</h1>
+  * Here are some examples of usage:
+  * <p><blockquote><pre>
+ Object x, y; String s; int i;
+@@ -295,7 +295,7 @@
+  * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
+  * on its arguments, and asserts that the result is true.
+  *
+- * <h3>Exceptions</h3>
++ * <h1>Exceptions</h1>
+  * The methods {@code invokeExact} and {@code invoke} are declared
+  * to throw {@link java.lang.Throwable Throwable},
+  * which is to say that there is no static restriction on what a method handle
+@@ -308,7 +308,7 @@
+  * throwables locally, rethrowing only those which are legal in the context,
+  * and wrapping ones which are illegal.
+  *
+- * <h3><a name="sigpoly"></a>Signature polymorphism</h3>
++ * <h1><a name="sigpoly"></a>Signature polymorphism</h1>
+  * The unusual compilation and linkage behavior of
+  * {@code invokeExact} and plain {@code invoke}
+  * is referenced by the term <em>signature polymorphism</em>.
+@@ -333,7 +333,7 @@
+  * Tools which determine symbolic linkage are required to accept such
+  * untransformed descriptors, without reporting linkage errors.
+  *
+- * <h3>Interoperation between method handles and the Core Reflection API</h3>
++ * <h1>Interoperation between method handles and the Core Reflection API</h1>
+  * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup Lookup} API,
+  * any class member represented by a Core Reflection API object
+  * can be converted to a behaviorally equivalent method handle.
+@@ -375,7 +375,7 @@
+  * to call {@code invokeExact} or plain {@code invoke},
+  * for any specified type descriptor .
+  *
+- * <h3>Interoperation between method handles and Java generics</h3>
++ * <h1>Interoperation between method handles and Java generics</h1>
+  * A method handle can be obtained on a method, constructor, or field
+  * which is declared with Java generic types.
+  * As with the Core Reflection API, the type of the method handle
+@@ -457,6 +457,8 @@
+      * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
+      * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+      * it will throw an {@code UnsupportedOperationException}.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
+      * @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
+      * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+      */
+@@ -491,6 +493,8 @@
+      * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
+      * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+      * it will throw an {@code UnsupportedOperationException}.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
+      * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's symbolic type descriptor
+      * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
+      * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+@@ -511,15 +515,26 @@
+      * operations on outgoing argument values.)
+      * The caller can assume that the incoming result value is part of the range
+      * of the callee's return type.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
+      */
+     /*non-public*/ final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
+ 
++    /**
++     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeVirtual}.
++     * The caller signature is restricted to basic types as with {@code invokeBasic}.
++     * The trailing (not leading) argument must be a MemberName.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
++     */
+     /*non-public*/ static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
+ 
+     /**
+      * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
+      * The caller signature is restricted to basic types as with {@code invokeBasic}.
+      * The trailing (not leading) argument must be a MemberName.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
+      */
+     /*non-public*/ static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
+ 
+@@ -527,6 +542,8 @@
+      * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
+      * The caller signature is restricted to basic types as with {@code invokeBasic}.
+      * The trailing (not leading) argument must be a MemberName.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
+      */
+     /*non-public*/ static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
+ 
+@@ -534,6 +551,8 @@
+      * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
+      * The caller signature is restricted to basic types as with {@code invokeBasic}.
+      * The trailing (not leading) argument must be a MemberName.
++     * @param args the signature-polymorphic parameter list, statically represented using varargs
++     * @return the signature-polymorphic result, statically represented using {@code Object}
+      */
+     /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
+ 
+@@ -776,8 +795,8 @@
+ assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));
+ assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));
+ // asSpreader and asCollector are approximate inverses:
+-for (int n = 0; n <= 2; n++) {
+-    for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {
++for (int n = 0; n &lt;= 2; n++) {
++    for (Class&lt;?&gt; a : new Class&lt;?&gt;[]{Object[].class, String[].class, CharSequence[].class}) {
+         MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);
+         assert( (boolean) equals2.invokeWithArguments("me", "me"));
+         assert(!(boolean) equals2.invokeWithArguments("me", "thee"));
+diff --git a/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/src/share/classes/java/lang/invoke/MethodHandleInfo.java
+--- a/src/share/classes/java/lang/invoke/MethodHandleInfo.java
++++ b/src/share/classes/java/lang/invoke/MethodHandleInfo.java
+@@ -24,80 +24,258 @@
+  */
+ 
+ package java.lang.invoke;
++
++import java.util.Objects;
++import java.lang.reflect.*;
+ import java.lang.invoke.MethodHandleNatives.Constants;
++import java.lang.invoke.MethodHandles.Lookup;
++import static java.lang.invoke.MethodHandleStatics.*;
+ 
+ /**
+- * Cracking (reflecting) method handles back into their constituent symbolic parts.
++ * A mechanism for cracking a method handle back into its constituent symbolic parts.
++ * To crack a method handle, call {@link Lookup#revealDirect Lookup.revealDirect}.
++ * The method handle must be a direct method handle.
++ * Future editions of this API may extend cracking to bound or otherwise transformed method handles.)
++ * <p>
++ * A <em>direct method handle</em> represents a method, constructor, or field without
++ * any intervening argument bindings or other transformations.
++ * The method, constructor, or field referred to by a direct method handle is called
++ * its <em>underlying member</em>.
++ * Direct method handles may be obtained in any of these ways:
++ * <ul>
++ * <li>By executing an {@code ldc} instruction on a {@code CONSTANT_MethodHandle} constant.
++ *     (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.)
++ * <li>By calling one of the <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>,
++ *     such as {@link Lookup#findVirtual Lookup.findVirtual},
++ *     to resolve a symbolic reference into a method handle.
++ *     A symbolic reference consists of a class, name string, and type.
++ * <li>By calling the factory method {@link Lookup#unreflect Lookup.unreflect}
++ *     or {@link Lookup#unreflectSpecial Lookup.unreflectSpecial}
++ *     to convert a {@link Method} into a method handle.
++ * <li>By calling the factory method {@link Lookup#unreflectConstructor Lookup.unreflectConstructor}
++ *     to convert a {@link Constructor} into a method handle.
++ * <li>By calling the factory method {@link Lookup#unreflectGetter Lookup.unreflectGetter}
++ *     or {@link Lookup#unreflectSetter Lookup.unreflectSetter}
++ *     to convert a {@link Field} into a method handle.
++ * </ul>
++ * In all of these cases, it is possible to crack the resulting direct method handle
++ * to recover a symbolic reference for the underlying method, constructor, or field.
++ * <p>
++ * Cracking must be done via a {@code Lookup} object which is compatible with the
++ * lookup object or class that originally created the direct method handle.
++ * In general, you cannot crack a method handle that you could not have made in the first place.
+  *
++ * <h1><a name="refkinds"></a>Reference kinds</h1>
++ * The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>
++ * correspond to all major use cases for methods, constructors, and fields.
++ * These use cases may be distinguished using small integers as follows:
++ * <table border=1 cellpadding=5 summary="reference kinds">
++ * <tr><th>reference kind</th><th>descriptive name</th><th>scope</th><th>member</th><th>behavior</th></tr>
++ * <tr>
++ *     <td>{@code 1}</td><td>{@code REF_getField}</td><td>{@code class}</td>
++ *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 2}</td><td>{@code REF_getStatic}</td><td>{@code class} or {@code interface}</td>
++ *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 3}</td><td>{@code REF_putField}</td><td>{@code class}</td>
++ *     <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 4}</td><td>{@code REF_putStatic}</td><td>{@code class}</td>
++ *     <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 5}</td><td>{@code REF_invokeVirtual}</td><td>{@code class}</td>
++ *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 6}</td><td>{@code REF_invokeStatic}</td><td>{@code class} or {@code interface}</td>
++ *     <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 7}</td><td>{@code REF_invokeSpecial}</td><td>{@code class} or {@code interface}</td>
++ *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 8}</td><td>{@code REF_newInvokeSpecial}</td><td>{@code class}</td>
++ *     <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
++ * </tr>
++ * <tr>
++ *     <td>{@code 9}</td><td>{@code REF_invokeInterface}</td><td>{@code interface}</td>
++ *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
++ * </tr>
++ * </table>
+  */
+-final class MethodHandleInfo {
+-   public static final int
+-       REF_getField                = Constants.REF_getField,
+-       REF_getStatic               = Constants.REF_getStatic,
+-       REF_putField                = Constants.REF_putField,
+-       REF_putStatic               = Constants.REF_putStatic,
+-       REF_invokeVirtual           = Constants.REF_invokeVirtual,
+-       REF_invokeStatic            = Constants.REF_invokeStatic,
+-       REF_invokeSpecial           = Constants.REF_invokeSpecial,
+-       REF_newInvokeSpecial        = Constants.REF_newInvokeSpecial,
+-       REF_invokeInterface         = Constants.REF_invokeInterface;
++// FIXME:
++// Should this extend java.lang.reflect.Member?
++// Should the direct parts be separated into a sub-interface (to allow for future extensions)?
++//    If we don't have a subinterface, later on we might need an isDirect method.
++//    If we do have a subinterface, then MethodHandleInfo becomes an empty type (like java.lang.reflect.Type).
++// Define SecurityManager checks.
++public
++interface MethodHandleInfo {
++    /**
++     * A direct method handle reference kind,
++     * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
++     */
++    public static final int
++        REF_getField                = Constants.REF_getField,
++        REF_getStatic               = Constants.REF_getStatic,
++        REF_putField                = Constants.REF_putField,
++        REF_putStatic               = Constants.REF_putStatic,
++        REF_invokeVirtual           = Constants.REF_invokeVirtual,
++        REF_invokeStatic            = Constants.REF_invokeStatic,
++        REF_invokeSpecial           = Constants.REF_invokeSpecial,
++        REF_newInvokeSpecial        = Constants.REF_newInvokeSpecial,
++        REF_invokeInterface         = Constants.REF_invokeInterface;
+ 
+-   private final Class<?> declaringClass;
+-   private final String name;
+-   private final MethodType methodType;
+-   private final int referenceKind;
++    /**
++     * Returns the reference kind of the cracked method handle, which in turn
++     * determines whether the method handle's underlying member was a constructor, method, or field.
++     * See the <a href="MethodHandleInfo.html#refkinds">table above</a> for definitions.
++     * @return the integer code for the kind of reference used to access the underlying member
++     */
++    public int getReferenceKind();
+ 
+-   public MethodHandleInfo(MethodHandle mh) {
+-       MemberName mn = mh.internalMemberName();
+-       if (mn == null)  throw new IllegalArgumentException("not a direct method handle");
+-       this.declaringClass = mn.getDeclaringClass();
+-       this.name = mn.getName();
+-       this.methodType = mn.getMethodOrFieldType();
+-       byte refKind = mn.getReferenceKind();
+-       if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial())
+-           // Devirtualized method invocation is usually formally virtual.
+-           refKind = REF_invokeVirtual;
+-       this.referenceKind = refKind;
+-   }
++    /**
++     * Returns the class in which the cracked method handle's underlying member was defined.
++     * @return the declaring class of the underlying member
++     */
++    public Class<?> getDeclaringClass();
+ 
+-   public Class<?> getDeclaringClass() {
+-       return declaringClass;
+-   }
++    /**
++     * Returns the name of the cracked method handle's underlying member.
++     * This is {@code "&lt;init&gt;"} if the underlying member was a constructor,
++     * else it is a simple method name or field name.
++     * @return the simple name of the underlying member
++     */
++    public String getName();
+ 
+-   public String getName() {
+-       return name;
+-   }
++    /**
++     * Returns the nominal type of the underlying member, expressed as a method type.
++     * If it is a constructor, the return type will be {@code void}.
++     * If it is a non-static method, the method type will not mention the {@code this} parameter.
++     * If it is a field and the handle is a field getter,
++     * the method type will have no parameters and return the field type.
++     * If it is a field and the handle is a field setter,
++     * the method type will have one parameter of the field type and return {@code void}.
++     * <p>
++     * Note that the corresponding direct method handle may include {@code this},
++     * or (in the case of a constructor) will replace the {@code void} return type
++     * with the constructed class.
++     * @return the type of the underlying member, expressed as a method type
++     */
++    public MethodType getMethodType();
+ 
+-   public MethodType getMethodType() {
+-       return methodType;
+-   }
++    // /**
++    //  * Returns the access modifiers of the underlying member method, constructor, or field.
++    //  * @return the Java language modifiers for the underlying member
++    //  * @see Modifier
++    //  */
++    // public int getModifiers();
++    // NOTE: modifiers are not part of a symbolic reference, just class/name/type and reference kind
+ 
+-   public int getModifiers() {
+-       return -1; //TODO
+-   }
++    /*non-public*/
++    static class FromMemberName implements MethodHandleInfo {
++        private final MemberName member;
++        private final int referenceKind;
+ 
+-   public int getReferenceKind() {
+-       return referenceKind;
+-   }
++        FromMemberName(Lookup lookup, MemberName member, byte referenceKind) {
++            assert(member.referenceKindIsConsistentWith(referenceKind));
++            this.member = member;
++            this.referenceKind = referenceKind;
++        }
+ 
+-   static String getReferenceKindString(int referenceKind) {
+-        switch (referenceKind) {
+-            case REF_getField: return "getfield";
+-            case REF_getStatic: return "getstatic";
+-            case REF_putField: return "putfield";
+-            case REF_putStatic: return "putstatic";
+-            case REF_invokeVirtual: return "invokevirtual";
+-            case REF_invokeStatic: return "invokestatic";
+-            case REF_invokeSpecial: return "invokespecial";
+-            case REF_newInvokeSpecial: return "newinvokespecial";
+-            case REF_invokeInterface: return "invokeinterface";
+-            default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]";
++        @Override
++        public Class<?> getDeclaringClass() {
++            return member.getDeclaringClass();
+         }
++
++        @Override
++        public String getName() {
++            return member.getName();
++        }
++
++        @Override
++        public MethodType getMethodType() {
++            return member.getMethodType();
++        }
++
++        // @Override
++        // public int getModifiers() {
++        //     return member.getModifiers();
++        // }
++
++        @Override
++        public int getReferenceKind() {
++            return referenceKind;
++        }
++
++        @Override public String toString() { return MethodHandleInfo.toString(this); }
++        @Override public boolean equals(Object x) { return MethodHandleInfo.equals(this, x); }
++        @Override public int hashCode() { return MethodHandleInfo.hashCode(this); }
+     }
+ 
+-    @Override
+-    public String toString() {
+-        return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind),
+-                             declaringClass.getName(), name, methodType);
++    /**
++     * Returns the descriptive name of the given reference kind,
++     * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
++     * The conventional prefix "REF_" is omitted.
++     * @param referenceKind an integer code for a kind of reference used to access a class member
++     * @return a mixed-case string such as {@code "getField"}
++     * @throws IllegalArgumentException if the give number is not a reference kind
++     */
++    public static String getReferenceKindString(int referenceKind) {
++        if (!MethodHandleNatives.refKindIsValid(referenceKind))
++            throw newIllegalArgumentException("invalid reference kind", referenceKind);
++        return MethodHandleNatives.refKindName((byte)referenceKind);
++    }
++
++    /**
++     * Returns a string representation for the symbolic reference to this method.
++     * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the
++     * {@linkplain #getReferenceKindString reference kind string},
++     * {@code C} is the {@linkplain java.lang.Class#getName name} of the
++     * {@linkplain #getDeclaringClass declaring class},
++     * {@code N} is the {@linkplain #getName name}, and
++     * {@code MT} is the {@linkplain #getMethodType method type} of this reference.
++     * @param self this symbolic reference
++     * @return a string of the form {@code "RK C.N:MT"}
++     */
++    public static String toString(MethodHandleInfo self) {
++        return String.format("%s %s.%s:%s", getReferenceKindString(self.getReferenceKind()),
++                             self.getDeclaringClass().getName(), self.getName(), self.getMethodType());
++    }
++
++    /**
++     * Compares this symbolic reference to the specified object
++     * @param self this symbolic reference
++     * @param x the object to compare this symbolic reference against
++     * @return {@code true} if and only if the given object represents an equivalent symbolic reference
++     */
++    public static boolean equals(MethodHandleInfo self, Object x) {
++        if (!(x instanceof MethodHandleInfo))
++            return false;
++        MethodHandleInfo that = (MethodHandleInfo) x;
++        return (self.getDeclaringClass() == that.getDeclaringClass() &&
++                self.getName().equals(that.getName()) &&
++                self.getMethodType().equals(that.getMethodType()) &&
++                self.getReferenceKind() == that.getReferenceKind());
++    }
++
++    /**
++     * Returns a hash code for this symbolic reference.
++     * It is computed as if by {@link java.util.Objects#hash} on the
++     * declaring class, the name, the method type, and the reference kind, in that order.
++     * @param self this symbolic reference
++     * @return a hash code for this symbolic reference, computed as if by {@link java.util.Objects#hash}
++     */
++    public static int hashCode(MethodHandleInfo self) {
++        return Objects.hash(self.getDeclaringClass(),
++                            self.getName(),
++                            self.getMethodType(),
++                            self.getReferenceKind());
+     }
+ }
+diff --git a/src/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/share/classes/java/lang/invoke/MethodHandleProxies.java
+--- a/src/share/classes/java/lang/invoke/MethodHandleProxies.java
++++ b/src/share/classes/java/lang/invoke/MethodHandleProxies.java
+@@ -107,8 +107,9 @@
+      * Future versions of this API may also equip wrapper instances
+      * with one or more additional public "marker" interfaces.
+      *
++     * @param <T> the desired type of the wrapper, a single-method interface
++     * @param intfc a class object representing {@code T}
+      * @param target the method handle to invoke from the wrapper
+-     * @param intfc the desired type of the wrapper, a single-method interface
+      * @return a correctly-typed wrapper for the given target
+      * @throws NullPointerException if either argument is null
+      * @throws IllegalArgumentException if the {@code intfc} is not a
+diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
+--- a/src/share/classes/java/lang/invoke/MethodHandles.java
++++ b/src/share/classes/java/lang/invoke/MethodHandles.java
+@@ -64,6 +64,7 @@
+      * including direct method handles to private fields and methods.
+      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
+      * Do not store it in place where untrusted code can access it.
++     * @return a lookup object for the caller of this method
+      */
+     public static Lookup lookup() {
+         return new Lookup();
+@@ -81,6 +82,7 @@
+      * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
+      * Since all classes have equal access to public names,
+      * such a change would confer no new access rights.
++     * @return a lookup object which is trusted minimally
+      */
+     public static Lookup publicLookup() {
+         return Lookup.PUBLIC_LOOKUP;
+@@ -104,72 +106,73 @@
+      * on the {@code Lookup} object to create method handles for access-checked members.
+      * This includes all methods, constructors, and fields which are allowed to the lookup class,
+      * even private ones.
+-     * <p>
++     *
++     * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
+      * The factory methods on a {@code Lookup} object correspond to all major
+      * use cases for methods, constructors, and fields.
+      * Here is a summary of the correspondence between these factory methods and
+-     * the behavior the resulting method handles:
+-     * <code>
++     * the behavior of the resulting method handles:
+      * <table border=1 cellpadding=5 summary="lookup method behaviors">
+      * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
+-     *     <td>FT f;</td><td>(T) this.f;</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
++     *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
+-     *     <td>static<br>FT f;</td><td>(T) C.f;</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
++     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
+-     *     <td>FT f;</td><td>this.f = x;</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
++     *     <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
+-     *     <td>static<br>FT f;</td><td>C.f = arg;</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
++     *     <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
+-     *     <td>T m(A*);</td><td>(T) this.m(arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
++     *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
+-     *     <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
++     *     <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
+-     *     <td>T m(A*);</td><td>(T) super.m(arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
++     *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
+-     *     <td>C(A*);</td><td>(T) new C(arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
++     *     <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
+-     *     <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
++     *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
+-     *     <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
++     *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+-     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
++     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
+-     *     <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
++     *     <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
+      * </tr>
+      * <tr>
+-     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+-     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
++     *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
++     *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
+      * </tr>
+      * </table>
+-     * </code>
+      * Here, the type {@code C} is the class or interface being searched for a member,
+      * documented as a parameter named {@code refc} in the lookup methods.
+-     * The method or constructor type {@code MT} is composed from the return type {@code T}
++     * The method type {@code MT} is composed from the return type {@code T}
+      * and the sequence of argument types {@code A*}.
++     * The constructor also has a sequence of argument types {@code A*} and
++     * is deemed to return the newly-created object of type {@code C}.
+      * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
+      * The formal parameter {@code this} stands for the self-reference of type {@code C};
+      * if it is present, it is always the leading argument to the method handle invocation.
+@@ -203,7 +206,7 @@
+      * security manager checks.
+      * </ul>
+      *
+-     * <h3><a name="access"></a>Access checking</h3>
++     * <h1><a name="access"></a>Access checking</h1>
+      * Access checks are applied in the factory methods of {@code Lookup},
+      * when a method handle is created.
+      * This is a key difference from the Core Reflection API, since
+@@ -290,7 +293,7 @@
+      * with static methods of {@link MethodHandles},
+      * independently of any {@code Lookup} object.
+      *
+-     * <h3>Security manager interactions</h3>
++     * <h1>Security manager interactions</h1>
+      * <a name="secmgr"></a>
+      * If a security manager is present, member lookups are subject to
+      * additional checks.
+@@ -381,6 +384,7 @@
+          *  but the permissions may be additionally limited by the bitmask
+          *  {@link #lookupModes lookupModes}, which controls whether non-public members
+          *  can be accessed.
++         *  @return the lookup class, on behalf of which this lookup object finds members
+          */
+         public Class<?> lookupClass() {
+             return lookupClass;
+@@ -407,6 +411,7 @@
+          *  The purpose of this is to restrict access via the new lookup object,
+          *  so that it can access only names which can be reached by the original
+          *  lookup object, and also by the new lookup class.
++         *  @return the lookup modes, which limit the kinds of access performed by this lookup object
+          */
+         public int lookupModes() {
+             return allowedModes & ALL_MODES;
+@@ -1023,6 +1028,27 @@
+             return unreflectField(f, true);
+         }
+ 
++        /**
++         * Crack a direct method handle created by this lookup object or a similar one.
++         * @param target a direct method handle to crack into symbolic reference components
++         * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
++         * @throws ReflectiveOperationException if the cracking fails due to access limitations,
++         *         or because the target is not a direct method handle
++         */
++        public MethodHandleInfo revealDirect(MethodHandle target) throws ReflectiveOperationException {
++            MemberName member = target.internalMemberName();
++            if (member == null)
++                throw new ReflectiveOperationException("not a direct method handle");
++            byte refKind = member.getReferenceKind();
++            if (refKind == REF_invokeSpecial && !target.isInvokeSpecial())
++                // Devirtualized method invocation is usually formally virtual.
++                // To avoid creating extra MemberName objects for this common case,
++                // we encode this extra degree of freedom using MH.isInvokeSpecial.
++                refKind = REF_invokeVirtual;
++            //FIXME: Need to check permissions.
++            return new MethodHandleInfo.FromMemberName(this, member, refKind);
++        }
++
+         /// Helper methods, all package-private.
+ 
+         MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+@@ -1324,6 +1350,7 @@
+      * The type of the method handle will have a void return type.
+      * Its last argument will be the array's element type.
+      * The first and second arguments will be the array type and int.
++     * @param arrayClass the class of an array
+      * @return a method handle which can store values into the array type
+      * @throws NullPointerException if the argument is null
+      * @throws IllegalArgumentException if arrayClass is not an array type
+@@ -1552,12 +1579,12 @@
+ ...
+ MethodType intfn1 = methodType(int.class, int.class);
+ MethodType intfn2 = methodType(int.class, int.class, int.class);
+-MethodHandle sub = ... {int x, int y => x-y} ...;
++MethodHandle sub = ... (int x, int y) -&gt; (x-y) ...;
+ assert(sub.type().equals(intfn2));
+ MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
+ MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
+ assert((int)rsub.invokeExact(1, 100) == 99);
+-MethodHandle add = ... {int x, int y => x+y} ...;
++MethodHandle add = ... (int x, int y) -&gt; (x+y) ...;
+ assert(add.type().equals(intfn2));
+ MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
+ assert(twice.type().equals(intfn1));
+@@ -2233,6 +2260,8 @@
+      * The method type will nominally specify a return of {@code returnType}.
+      * The return type may be anything convenient:  It doesn't matter to the
+      * method handle's behavior, since it will never return normally.
++     * @param returnType the return type of the desired method handle
++     * @param exType the parameter type of the desired method handle
+      * @return method handle which can throw the given exceptions
+      * @throws NullPointerException if either argument is null
+      */
+diff --git a/src/share/classes/java/lang/invoke/MethodType.java b/src/share/classes/java/lang/invoke/MethodType.java
+--- a/src/share/classes/java/lang/invoke/MethodType.java
++++ b/src/share/classes/java/lang/invoke/MethodType.java
+@@ -191,6 +191,8 @@
+     /**
+      * Finds or creates a method type with the given components.
+      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
++     * @param rtype  the return type
++     * @param ptypes the parameter types
+      * @return a method type with the given components
+      * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+      * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+@@ -211,6 +213,9 @@
+      * Finds or creates a method type with the given components.
+      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+      * The leading parameter type is prepended to the remaining array.
++     * @param rtype  the return type
++     * @param ptype0 the first parameter type
++     * @param ptypes the remaining parameter types
+      * @return a method type with the given components
+      * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
+      * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
+@@ -227,6 +232,7 @@
+      * Finds or creates a method type with the given components.
+      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+      * The resulting method has no parameter types.
++     * @param rtype  the return type
+      * @return a method type with the given return value
+      * @throws NullPointerException if {@code rtype} is null
+      */
+@@ -239,6 +245,8 @@
+      * Finds or creates a method type with the given components.
+      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+      * The resulting method has the single given parameter type.
++     * @param rtype  the return type
++     * @param ptype0 the parameter type
+      * @return a method type with the given return value and parameter type
+      * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
+      * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
+@@ -253,6 +261,9 @@
+      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+      * The resulting method has the same parameter types as {@code ptypes},
+      * and the specified return type.
++     * @param rtype  the return type
++     * @param ptypes the method type which supplies the parameter types
++     * @return a method type with the given components
+      * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
+      */
+     public static
+@@ -935,7 +946,8 @@
+      * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
+      * For example, null values, or {@code void} parameter types,
+      * will lead to exceptions during deserialization.
+-     * @param the stream to write the object to
++     * @param s the stream to write the object to
++     * @throws java.io.IOException if there is a problem writing the object
+      */
+     private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+         s.defaultWriteObject();  // requires serialPersistentFields to be an empty array
+@@ -950,7 +962,9 @@
+      * It provides the parameters to the factory method called by
+      * {@link #readResolve readResolve}.
+      * After that call it is discarded.
+-     * @param the stream to read the object from
++     * @param s the stream to read the object from
++     * @throws java.io.IOException if there is a problem reading the object
++     * @throws ClassNotFoundException if one of the component classes cannot be resolved
+      * @see #MethodType()
+      * @see #readResolve
+      * @see #writeObject
+diff --git a/src/share/classes/java/lang/invoke/MutableCallSite.java b/src/share/classes/java/lang/invoke/MutableCallSite.java
+--- a/src/share/classes/java/lang/invoke/MutableCallSite.java
++++ b/src/share/classes/java/lang/invoke/MutableCallSite.java
+@@ -195,7 +195,7 @@
+      * processed before the method returns abnormally.
+      * Which elements these are (if any) is implementation-dependent.
+      *
+-     * <h3>Java Memory Model details</h3>
++     * <h1>Java Memory Model details</h1>
+      * In terms of the Java Memory Model, this operation performs a synchronization
+      * action which is comparable in effect to the writing of a volatile variable
+      * by the current thread, and an eventual volatile read by every other thread
+diff --git a/src/share/classes/java/lang/invoke/package-info.java b/src/share/classes/java/lang/invoke/package-info.java
+--- a/src/share/classes/java/lang/invoke/package-info.java
++++ b/src/share/classes/java/lang/invoke/package-info.java
+@@ -43,13 +43,13 @@
+  * </li>
+  * </ul>
+  *
+- * <h2><a name="jvm_mods"></a>Summary of relevant Java Virtual Machine changes</h2>
++ * <h1><a name="jvm_mods"></a>Summary of relevant Java Virtual Machine changes</h1>
+  * The following low-level information summarizes relevant parts of the
+  * Java Virtual Machine specification.  For full details, please see the
+  * current version of that specification.
+  *
+  * Each occurrence of an {@code invokedynamic} instruction is called a <em>dynamic call site</em>.
+- * <h3><a name="indyinsn"></a>{@code invokedynamic} instructions</h3>
++ * <h2><a name="indyinsn"></a>{@code invokedynamic} instructions</h2>
+  * A dynamic call site is originally in an unlinked state.  In this state, there is
+  * no target method for the call site to invoke.
+  * <p>
+@@ -97,7 +97,7 @@
+  * If this happens, the same error will the thrown for all subsequent
+  * attempts to execute the dynamic call site.
+  *
+- * <h3>timing of linkage</h3>
++ * <h2>timing of linkage</h2>
+  * A dynamic call site is linked just before its first execution.
+  * The bootstrap method call implementing the linkage occurs within
+  * a thread that is attempting a first execution.
+@@ -131,7 +131,7 @@
+  * just before its first invocation.
+  * There is no way to undo the effect of a completed bootstrap method call.
+  *
+- * <h3>types of bootstrap methods</h3>
++ * <h2>types of bootstrap methods</h2>
+  * As long as each bootstrap method can be correctly invoked
+  * by {@code MethodHandle.invoke}, its detailed type is arbitrary.
+  * For example, the first argument could be {@code Object}