changeset 443:eabaf978d9ee

rebase; split and update meth-info-8008688.patch
author jrose
date Tue, 14 May 2013 22:58:15 -0700
parents 23f2de08d38b
children 469cff19f299
files meth-doc-8014634.patch meth-info-8008688.patch meth.patch series
diffstat 4 files changed, 952 insertions(+), 758 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meth-doc-8014634.patch	Tue May 14 22:58:15 2013 -0700
@@ -0,0 +1,522 @@
+8014634: JSR 292 javadoc needs cleanups and clarifications
+
+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/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/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
+@@ -108,8 +108,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
+@@ -68,6 +68,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
+      */
+     @CallerSensitive
+     public static Lookup lookup() {
+@@ -86,6 +87,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;
+@@ -109,72 +111,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.
+@@ -208,7 +211,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
+@@ -295,7 +298,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.
+@@ -386,6 +389,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;
+@@ -412,6 +416,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;
+@@ -1371,6 +1376,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
+@@ -1599,12 +1605,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));
+@@ -2280,6 +2286,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}
--- a/meth-info-8008688.patch	Thu May 02 19:25:01 2013 -0700
+++ b/meth-info-8008688.patch	Tue May 14 22:58:15 2013 -0700
@@ -5,7 +5,7 @@
 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,16 +102,13 @@
+@@ -102,12 +102,12 @@
          this.samBase = invokedType.returnType();
  
          this.samMethod = samMethod;
@@ -16,45 +16,126 @@
  
          this.implMethod = implMethod;
 -        this.implInfo = new MethodHandleInfo(implMethod);
--        // @@@ Temporary work-around pending resolution of 8005119
--        this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial)
--                        ? MethodHandleInfo.REF_invokeVirtual
--                        : implInfo.getReferenceKind();
 +        this.implInfo = caller.revealDirect(implMethod);
-+        this.implKind = implInfo.getReferenceKind();
-         this.implIsInstanceMethod =
-                 implKind == MethodHandleInfo.REF_invokeVirtual ||
-                 implKind == MethodHandleInfo.REF_invokeSpecial ||
-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,
+         // @@@ 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/InfoFromMemberName.java b/src/share/classes/java/lang/invoke/InfoFromMemberName.java
+new file mode 100644
+--- /dev/null
++++ b/src/share/classes/java/lang/invoke/InfoFromMemberName.java
+@@ -0,0 +1,111 @@
++/*
++ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package java.lang.invoke;
++
++import java.security.*;
++import java.lang.reflect.*;
++import java.lang.invoke.MethodHandleNatives.Constants;
++import java.lang.invoke.MethodHandles.Lookup;
++import static java.lang.invoke.MethodHandleStatics.*;
++
++/*
++ * Auxiliary to MethodHandleInfo, wants to nest in MethodHandleInfo but must be non-public.
++ */
++/*non-public*/
++class InfoFromMemberName implements MethodHandleInfo {
++    private final MemberName member;
++    private final int referenceKind;
++
++    InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) {
++        assert(member.referenceKindIsConsistentWith(referenceKind));
++        this.member = member;
++        this.referenceKind = referenceKind;
++    }
++
++    @Override
++    public Class<?> getDeclaringClass() {
++        return member.getDeclaringClass();
++    }
++
++    @Override
++    public String getName() {
++        return member.getName();
++    }
++
++    @Override
++    public MethodType getMethodType() {
++        return member.getMethodOrFieldType();
++    }
++
++    @Override
++    public int getModifiers() {
++        if (member == null || !member.isResolved())
++            return -1;  // API contract
++        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); }
++
++    /*package*/
++    static NoSuchMethodError notDirectMethodHandle() {
++        return new NoSuchMethodError("not a direct method handle");
++    }
++
++    // Helper for default MethodHandleInfo.asMember.
++    static Member reflectMember(MethodHandleInfo self) throws ReflectiveOperationException {
++        int mods = self.getModifiers();
++        if (mods == -1)  throw notDirectMethodHandle();
++        byte refKind = (byte) self.getReferenceKind();
++        Class<?> defc = self.getDeclaringClass();
++        boolean isPublic = Modifier.isPublic(mods);
++        if (MethodHandleNatives.refKindIsMethod(refKind)) {
++            if (isPublic)
++                return defc.getMethod(self.getName(), self.getMethodType().parameterArray());
++            else
++                return defc.getDeclaredMethod(self.getName(), self.getMethodType().parameterArray());
++        } else if (MethodHandleNatives.refKindIsConstructor(refKind)) {
++            if (isPublic)
++                return defc.getConstructor(self.getMethodType().parameterArray());
++            else
++                return defc.getDeclaredConstructor(self.getMethodType().parameterArray());
++        } else if (MethodHandleNatives.refKindIsField(refKind)) {
++            if (isPublic)
++                return defc.getField(self.getName());
++            else
++                return defc.getDeclaredField(self.getName());
++        } else {
++            throw new IllegalArgumentException("referenceKind="+refKind);
++        }
++    }
++
++}
 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
@@ -105,182 +186,15 @@
          case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
          }
          throw new IllegalArgumentException(this.toString());
-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,287 @@
+@@ -24,80 +24,210 @@
   */
  
  package java.lang.invoke;
 +
-+import java.util.Objects;
++import java.security.*;
 +import java.lang.reflect.*;
  import java.lang.invoke.MethodHandleNatives.Constants;
 +import java.lang.invoke.MethodHandles.Lookup;
@@ -288,10 +202,8 @@
  
  /**
 - * 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.)
++ * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts.
++ * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}.
 + * <p>
 + * A <em>direct method handle</em> represents a method, constructor, or field without
 + * any intervening argument bindings or other transformations.
@@ -316,10 +228,9 @@
 + * </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.
++ * Cracking must be done via a {@code Lookup} object equivalent to that which created
++ * the target method handle, or which has enough access permissions to recreate
++ * an equivalent method handle.
   *
 + * <h1><a name="refkinds"></a>Reference kinds</h1>
 + * The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>
@@ -438,17 +349,19 @@
 -       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,
++     * Returns the nominal type of the cracked symbolic reference, expressed as a method type.
++     * If the reference is to a constructor, the return type will be {@code void}.
++     * If it is to a non-static method, the method type will not mention the {@code this} parameter.
++     * If it is to a field and the requested access is to read the field,
 +     * the method type will have no parameters and return the field type.
-+     * If it is a field and the handle is a field setter,
++     * If it is to a field and the requested access is to write the field,
 +     * 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},
++     * Note that original direct method handle may include a leading {@code this} parameter,
 +     * or (in the case of a constructor) will replace the {@code void} return type
 +     * with the constructed class.
++     * The nominal type does not include any {@code this} parameter,
++     * and (in the case of a constructor) will return {@code void}.
 +     * @return the type of the underlying member, expressed as a method type
 +     */
 +    public MethodType getMethodType();
@@ -463,45 +376,7 @@
 -   public int getModifiers() {
 -       return -1; //TODO
 -   }
-+    /**
-+     * Reflects the underlying reflected member.
-+     * If the underlying member is public, the member is reflected as if by
-+     * {@code getMethod}, {@code getConstructor}, or {@code getField}.
-+     * Otherwise, it is reflected as if by
-+     * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}.
-+     * @param <T> the desired type of the result, either {@link Member} or a subtype
-+     * @param expected a class object representing the desired result type {@code T}
-+     * @return the method, constructor, or field
-+     * @throws ReflectiveOperationException if the original lookup object is not able to reflect
-+     * @throws ClassCastException if the member is not of the expected type
-+     * @throws SecurityException if a security manager is installed and forbids access
-+     */
-+    public default <T extends Member> T asMember(Class<T> expected) throws ReflectiveOperationException {
-+        byte refKind = (byte) getReferenceKind();
-+        Class<?> defc = getDeclaringClass();
-+        boolean isPublic = Modifier.isPublic(getModifiers());
-+        Member mem;
-+        if (MethodHandleNatives.refKindIsMethod(refKind)) {
-+            if (isPublic)
-+                mem = defc.getMethod(getName(), getMethodType().parameterArray());
-+            else
-+                mem = defc.getDeclaredMethod(getName(), getMethodType().parameterArray());
-+        } else if (MethodHandleNatives.refKindIsConstructor(refKind)) {
-+            if (isPublic)
-+                mem = defc.getConstructor(getMethodType().parameterArray());
-+            else
-+                mem = defc.getDeclaredConstructor(getMethodType().parameterArray());
-+        } else if (MethodHandleNatives.refKindIsField(refKind)) {
-+            if (isPublic)
-+                mem = defc.getField(getName());
-+            else
-+                mem = defc.getDeclaredField(getName());
-+        } else {
-+            throw new IllegalArgumentException("referenceKind="+refKind);
-+        }
-+        return expected.cast(mem);
-+    }
- 
+-
 -   public int getReferenceKind() {
 -       return referenceKind;
 -   }
@@ -518,17 +393,29 @@
 -            case REF_newInvokeSpecial: return "newinvokespecial";
 -            case REF_invokeInterface: return "invokeinterface";
 -            default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]";
+-        }
 +    /**
-+     * Returns the access modifiers of the underlying member method, constructor, or field.
-+     * @return the Java language modifiers for the underlying member, or -1 if the value cannot be obtained
-+     * @see Modifier
++     * Reflects the underlying member as a method, constructor, or field object.
++     * If the underlying member is public, it is reflected as if by
++     * {@code getMethod}, {@code getConstructor}, or {@code getField}.
++     * Otherwise, it is reflected as if by
++     * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}.
++     * @param <T> the desired type of the result, either {@link Member} or a subtype
++     * @param expected a class object representing the desired result type {@code T}
++     * @return a reference to the method, constructor, or field object
++     * @exception ClassCastException if the member is not of the expected type
 +     */
-+    public default int getModifiers() {
-+        try {
-+            return asMember(Member.class).getModifiers();
-+        } catch (ReflectiveOperationException ex) {
-+            throw new RuntimeException(ex);
-         }
++    public default <T extends Member> T asMember(Class<T> expected) {
++        Member mem = AccessController.doPrivileged(new PrivilegedAction<Member>() {
++                public Member run() {
++                    try {
++                        return InfoFromMemberName.reflectMember(MethodHandleInfo.this);
++                    } catch (ReflectiveOperationException ex) {
++                        throw newInternalError(ex);
++                    }
++                }
++            });
++        return expected.cast(mem);
      }
  
 -    @Override
@@ -536,61 +423,13 @@
 -        return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind),
 -                             declaringClass.getName(), name, methodType);
 +    /**
-+     * Determines if the underlying member was a variable arity method or constructor.
-+     *
-+     * @return {@code true} if and only if the underlying member was declared with variable arity.
++     * Returns the access modifiers of the underlying member.
++     * @return the Java language modifiers for underlying member,
++     *         or -1 if the member cannot be accessed
++     * @see Modifier
 +     */
-+    // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector
-+    public default boolean isVarArgs()  {
-+        // not in the public API: Modifier.VARARGS
-+        final int ACC_VARARGS = 0x00000080;  // from JVMS 4.6 (Table 4.20)
-+        return (getModifiers() & ACC_VARARGS) != 0;
-+    }
-+
-+    /*non-public*/
-+    static class FromMemberName implements MethodHandleInfo {
-+        private final MemberName member;
-+        private final int referenceKind;
-+
-+        FromMemberName(Lookup lookup, MemberName member, byte referenceKind) {
-+            assert(member.referenceKindIsConsistentWith(referenceKind));
-+            this.member = member;
-+            this.referenceKind = referenceKind;
-+        }
-+
-+        @Override
-+        public Class<?> getDeclaringClass() {
-+            return member.getDeclaringClass();
-+        }
-+
-+        @Override
-+        public String getName() {
-+            return member.getName();
-+        }
-+
-+        @Override
-+        public MethodType getMethodType() {
-+            return member.getMethodOrFieldType();
-+        }
-+
-+        @Override
-+        public int getModifiers() {
-+            return member.getModifiers();
-+        }
-+
-+        @Override
-+        public boolean isVarArgs() {
-+            return member.isVarargs();  // private spelling has 'args' not 'Args'
-+        }
-+
-+        @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); }
++    public default int getModifiers() {
++        return asMember(Member.class).getModifiers();
 +    }
 +
 +    /**
@@ -599,7 +438,7 @@
 +     * 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
++     * @exception IllegalArgumentException if the give number is not a reference kind
 +     */
 +    public static String getReferenceKindString(int referenceKind) {
 +        if (!MethodHandleNatives.refKindIsValid(referenceKind))
@@ -636,20 +475,6 @@
      static boolean refKindHasReceiver(byte refKind) {
          assert(refKindIsValid(refKind));
          return (refKind & 1) != 0;
-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
-@@ -108,8 +108,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
@@ -663,162 +488,52 @@
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Arrays;
-@@ -68,6 +67,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
-      */
-     @CallerSensitive
-     public static Lookup lookup() {
-@@ -86,6 +86,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;
-@@ -109,72 +110,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.
-@@ -208,7 +210,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
-@@ -295,7 +297,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.
-@@ -386,6 +388,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;
-@@ -412,6 +415,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;
-@@ -1022,6 +1026,86 @@
+@@ -92,6 +91,44 @@
+     }
+ 
+     /**
++     * Perform an unchecked "crack" of a direct method handle.
++     * The result is as if the user had obtained a lookup object capable enough
++     * to crack the target method handle, called
++     * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
++     * on the target to obtain its symbolic reference, and then called
++     * {@link java.lang.invoke.MethodHandleInfo#asMember MethodHandleInfo.asMember}
++     * to resolve the symbolic reference to a member.
++     * <p>
++     * If there is a security manager, its {@code checkPermission} method
++     * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
++     * @param <T> the desired type of the result, either {@link Member} or a subtype
++     * @param target a direct method handle to crack into symbolic reference components
++     * @param expected a class object representing the desired result type {@code T}
++     * @return the method, constructor, or field
++     * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
++     * @throws NoSuchMethodException if the target is not a direct method handle
++     * @exception ClassCastException if the member is not of the expected type
++     */
++    public static <T extends Member> T
++    revealDirectAsAccessibleObject(MethodHandle target, Class<T> expected)
++        throws NoSuchMethodException
++    {
++        SecurityManager smgr = System.getSecurityManager();
++        if (smgr != null)  smgr.checkPermission(ACCESS_PERMISSION);
++        try {
++            return Lookup.IMPL_LOOKUP.revealDirect(target).asMember(expected);
++        } catch (NoSuchMethodException ex) {
++            throw ex;
++        } catch (ReflectiveOperationException ex) {
++            // Privileged lookup object should not fail this way.
++            throw newInternalError(ex);
++        }
++    }
++    // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
++    static final private java.security.Permission ACCESS_PERMISSION =
++        new ReflectPermission("suppressAccessChecks");
++
++    /**
+      * A <em>lookup object</em> is a factory for creating method handles,
+      * when the creation requires access checking.
+      * Method handles do not perform
+@@ -1022,6 +1059,42 @@
              return unreflectField(f, true);
          }
  
@@ -830,82 +545,38 @@
 +         * but was created by an unrelated lookup object.
 +         * @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
++         * @exception SecurityException if a security manager is present and it
++         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
++         * @throws NoSuchMethodException if the target is not a direct method handle
++         * @throws IllegalAccessException if access checking fails
 +         */
-+        public MethodHandleInfo revealDirect(MethodHandle target) throws ReflectiveOperationException {
++        public MethodHandleInfo revealDirect(MethodHandle target)
++            throws IllegalAccessException, NoSuchMethodException
++        {
 +            MemberName member = target.internalMemberName();
-+            if (member == null)
-+                throw new ReflectiveOperationException("not a direct method handle");
++            if (member == null || !member.isResolved())
++                throw InfoFromMemberName.notDirectMethodHandle();
++            Class<?> defc = member.getDeclaringClass();
 +            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;
-+            // Check SM permissions and member access:
-+            Class<?> defc = member.getDeclaringClass();
-+            if (defc != lookupClass) {  // quick cutouts
-+                if (allowedModes != TRUSTED) {
-+                    checkSecurityManager(defc, member, lookupClass());
-+                    checkAccess(member.getReferenceKind(), defc, member);
-+                }
-+            }
-+            return new MethodHandleInfo.FromMemberName(this, member, refKind);
-+        }
-+
-+        /**
-+         * Crack a direct method handle created by this lookup object or a similar one.
-+         * If {@code bypassAccessibilityChecks} is true, performs the accessibility check
-+         * as calling {@link AccessibleObject#setAccessible AccessibleObject.setAccessible}.
-+         * If {@code bypassAccessibilityChecks} is false, the same checks are performed
-+         * as for the {@linkplain #revealDirect(MethodHandle) one-argument version} of this method.
-+         * @param target a direct method handle to crack into symbolic reference components
-+         * @param bypassAccessibilityChecks 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, boolean bypassAccessibilityChecks) throws ReflectiveOperationException {
-+            if (!bypassAccessibilityChecks || allowedModes == TRUSTED)
-+                return revealDirect(target);
-+            SecurityManager smgr = System.getSecurityManager();
-+            if (smgr != null) {
-+                try {
-+                    // The following is done just for side effect:
-+                    Lookup.class.getDeclaredField("IMPL_LOOKUP").setAccessible(true);
-+                } catch (SecurityException ex) {
-+                    throw ex;
-+                } catch (ReflectiveOperationException ex) {
-+                    throw newInternalError(ex);
-+                }
-+                // If we get here, we know we are privileged enough to do any reveal.
-+            }
-+            return IMPL_LOOKUP.revealDirect(target);
-+        }
-+        /** A copy of {@code java.lang.reflect.AccessibleObject.ACCESS_PERMISSION}. */
-+        private static final Permission ACCESS_PERMISSION = makeAccessPermission(false);
-+        static private Permission makeAccessPermission(boolean slowly) {
-+            final Permission perm = new ReflectPermission("suppressAccessChecks");
-+            if (!slowly)  return perm;
-+            assert(perm.equals(makeAccessPermission(true)));
-+            return AccessController.doPrivileged(new PrivilegedAction<Permission>() {
-+                    public Permission run() {
-+                        try {
-+                            Field f = AccessibleObject.class.getDeclaredField("ACCESS_PERMISSION");
-+                            f.setAccessible(true);
-+                            return (Permission) f.get(null);
-+                        } catch (ReflectiveOperationException ex) {
-+                            throw newInternalError(ex);
-+                        }
-+                    }
-+                });
++            if (refKind == REF_invokeVirtual && defc.isInterface())
++                // Symbolic reference is through interface but resolves to Object method (toString, etc.)
++                refKind = REF_invokeInterface;
++            // Check SM permissions and member access before cracking.
++            checkSecurityManager(defc, member, lookupClass());
++            checkAccess(member.getReferenceKind(), defc, member);
++            // Produce the handle to the results.
++            return new InfoFromMemberName(this, member, refKind);
 +        }
 +
          /// Helper methods, all package-private.
  
          MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-@@ -1264,6 +1348,7 @@
+@@ -1264,6 +1337,7 @@
              Class<?> refcAsSuper;
              if (refKind == REF_invokeSpecial &&
                  refc != lookupClass() &&
@@ -913,7 +584,7 @@
                  refc != (refcAsSuper = lookupClass().getSuperclass()) &&
                  refc.isAssignableFrom(lookupClass())) {
                  assert(!method.getName().equals("<init>"));  // not this code path
-@@ -1292,6 +1377,7 @@
+@@ -1292,6 +1366,7 @@
              return mh;
          }
          private MethodHandle fakeMethodHandleInvoke(MemberName method) {
@@ -921,7 +592,7 @@
              return throwException(method.getReturnType(), UnsupportedOperationException.class);
          }
          private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
-@@ -1304,6 +1390,7 @@
+@@ -1304,6 +1379,7 @@
                  hostClass = callerClass;  // callerClass came from a security manager style stack walk
              MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
              // Note: caller will apply varargs after this step happens.
@@ -929,15 +600,7 @@
              return cbmh;
          }
          private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
-@@ -1371,6 +1458,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
-@@ -1468,6 +1556,7 @@
+@@ -1468,6 +1544,7 @@
       */
      static public
      MethodHandle exactInvoker(MethodType type) {
@@ -945,7 +608,7 @@
          return type.invokers().exactInvoker();
      }
  
-@@ -1501,6 +1590,7 @@
+@@ -1501,6 +1578,7 @@
       */
      static public
      MethodHandle invoker(MethodType type) {
@@ -953,154 +616,72 @@
          return type.invokers().generalInvoker();
      }
  
-@@ -1599,12 +1689,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));
-@@ -2280,6 +2370,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/reflect/Modifier.java b/src/share/classes/java/lang/reflect/Modifier.java
+--- a/src/share/classes/java/lang/reflect/Modifier.java
++++ b/src/share/classes/java/lang/reflect/Modifier.java
+@@ -147,12 +147,33 @@
+      * @param   mod a set of modifiers
+      * @return {@code true} if {@code mod} includes the
+      * {@code transient} modifier; {@code false} otherwise.
++     * @see #isVarArgs
       */
-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 @@
+     public static boolean isTransient(int mod) {
+         return (mod & TRANSIENT) != 0;
+     }
+ 
      /**
-      * 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
++     * Assuming that the integer argument is regarded
++     * as modifiers for a method or constructor,
++     * return {@code true} if the executable was declared
++     * to take a variable number of arguments,
++     * {@code false} otherwise.
++     * <p>
++     * Note:  Since the bit position used for variable arity methods and constructors
++     * is also used for {@code transient} fields, this call may also be
++     * regarded as testing for the {@code transient} modifier.
++     *
++     * @param   mod a set of modifiers
++     * @return {@code true} if {@code mod} specifies
++     * a variable number of arguments; {@code false} otherwise.
++     * @see #isTransient
++     */
++    public static boolean isVarArgs(int mod) {
++        return (mod & VARARGS) != 0;
++    }
++
++    /**
+      * Return {@code true} if the integer argument includes the
+      * {@code native} modifier, {@code false} otherwise.
+      *
+@@ -332,12 +353,22 @@
       */
-@@ -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}
+     public static final int STRICT           = 0x00000800;
+ 
++    /**
++     * The {@code int} value used to declare that a method or constructor 
++     * takes a variable number of arguments.
++     * <p>
++     * Note: This value is also used to declare {@code transient} fields.
++     */
++    public static final int VARARGS          = 0x00000080;
++    static {
++        assert(VARARGS == TRANSIENT);
++    }
++
+     // Bits not (yet) exposed in the public API either because they
+     // have different meanings for fields and methods and there is no
+     // way to distinguish between the two in this class, or because
+     // they are not Java programming language keywords
+     static final int BRIDGE    = 0x00000040;
+-    static final int VARARGS   = 0x00000080;
+     static final int SYNTHETIC = 0x00001000;
+     static final int ANNOTATION  = 0x00002000;
+     static final int ENUM      = 0x00004000;
 diff --git a/test/java/lang/invoke/RevealDirectTest.java b/test/java/lang/invoke/RevealDirectTest.java
 new file mode 100644
 --- /dev/null
 +++ b/test/java/lang/invoke/RevealDirectTest.java
-@@ -0,0 +1,347 @@
+@@ -0,0 +1,342 @@
 +/*
 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -1133,7 +714,7 @@
 + *
 + * @test
 + * @summary verify Lookup.revealDirect on a variety of input handles, with security manager
-+ * @run junit/othervm -ea -esa -DSETSMGR test.java.lang.invoke.RevealDirectTest
++ * @run junit/othervm/policy=jtreg.security.policy/secure=java.lang.SecurityManager -ea -esa test.java.lang.invoke.RevealDirectTest
 + */
 +
 +/* To run manually:
@@ -1192,14 +773,6 @@
 +    @Test public void testPublicLookup() throws Throwable {
 +        testOnClass(publicLookup(), Simple.class, publicOnly(Simple.MEMBERS));
 +    }
-+    @Test public void testWithSecurityManager() throws Throwable {
-+        if (System.getSecurityManager() != null) {
-+            System.out.println("security manager already installed; existing unit test");
-+            return;
-+        }
-+        System.setSecurityManager(new SecurityManager());
-+        testOnClass(Simple.localLookup(), Simple.class, publicOnly(Simple.MEMBERS));
-+    }
 +
 +    static List<Member> getMembers(Class<?> cls) {
 +        ArrayList<Member> res = new ArrayList<>();
@@ -1404,9 +977,12 @@
 +        if (res.kind == REF_newInvokeSpecial)
 +            expectType = expectType.changeReturnType(void.class);
 +        assert(expectType.equals(info.getMethodType()));
-+        assert(res.mh.isVarargsCollector() == info.isVarArgs());
++        assert(res.mh.isVarargsCollector() == isVarArgs(info));
 +        return true;
 +    }
++    static boolean isVarArgs(MethodHandleInfo info) {
++        return Modifier.isVarArgs(info.getModifiers());
++    }
 +    static boolean consistent(Member mem, Member mem2) {
 +        assert(mem.equals(mem2));
 +        return true;
@@ -1417,7 +993,7 @@
 +        assert(info.getDeclaringClass() == info2.getDeclaringClass());
 +        assert(info.getName().equals(info2.getName()));
 +        assert(info.getMethodType().equals(info2.getMethodType()));
-+        assert(info.isVarArgs() == info2.isVarArgs());
++        assert(isVarArgs(info) == isVarArgs(info));
 +        return true;
 +    }
 +    static boolean consistent(MethodHandle mh, MethodHandle mh2) {
@@ -1448,3 +1024,17 @@
 +        }
 +    }
 +}
+diff --git a/test/java/lang/invoke/jtreg.security.policy b/test/java/lang/invoke/jtreg.security.policy
+new file mode 100644
+--- /dev/null
++++ b/test/java/lang/invoke/jtreg.security.policy
+@@ -0,0 +1,9 @@
++/*
++ * security policy used by the test process
++ * must allow file reads so that jtreg itself can run
++ */
++
++grant {
++  // standard test activation permissions
++  permission java.io.FilePermission "*", "read";
++};
--- a/meth.patch	Thu May 02 19:25:01 2013 -0700
+++ b/meth.patch	Tue May 14 22:58:15 2013 -0700
@@ -31,7 +31,7 @@
      }
  
 @@ -493,14 +489,14 @@
-         case REF_invokeVirtual:     return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+         case REF_invokeInterface:   return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
          case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
          }
 -        throw new IllegalArgumentException(this.toString());
@@ -138,36 +138,28 @@
      }
  
      private static final NamedFunction NF_checkSpreadArgument;
-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
-@@ -26,7 +26,8 @@
- package java.lang.invoke;
- import java.lang.invoke.MethodHandleNatives.Constants;
- 
--//Not yet public: public
-+/*not public*/
-+// FIXME in MR1: Make this a public API
- class MethodHandleInfo {
-    public static final int
-        REF_getField                = Constants.REF_getField,
 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
 @@ -28,6 +28,7 @@
- import java.lang.reflect.*;
- import sun.invoke.WrapperInstance;
- import java.util.ArrayList;
+ import sun.reflect.CallerSensitive;
+ import sun.reflect.Reflection;
+ import sun.reflect.misc.ReflectUtil;
 +import static java.lang.invoke.MethodHandleStatics.*;
  
  /**
   * This class consists exclusively of static methods that help adapt
-@@ -136,10 +137,10 @@
+@@ -136,7 +137,7 @@
      public static
      <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
          if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
 -            throw new IllegalArgumentException("not a public interface: "+intfc.getName());
 +            throw newIllegalArgumentException("not a public interface", intfc.getName());
+         final MethodHandle mh;
+         if (System.getSecurityManager() != null) {
+             final Class<?> caller = Reflection.getCallerClass();
+@@ -143,7 +144,7 @@
+         }
          final Method[] methods = getSingleNameMethods(intfc);
          if (methods == null)
 -            throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
@@ -195,10 +187,10 @@
      public static final
      class Lookup {
          /** The class on behalf of whom the lookup is being performed. */
-@@ -643,6 +644,7 @@
-          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+@@ -644,6 +645,7 @@
           * @throws NullPointerException if any argument is null
           */
+         @CallerSensitive
 +        // FIXME in MR1: clarify that name="<init>" elicits a NoSuchMethodException always (ctor != method)
          public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
              if (refc == MethodHandle.class) {
@@ -209,9 +201,9 @@
           */
 +        // FIXME in MR1: clarify that specialCaller access check happens first
 +        // FIXME in MR1: clarify that name="<init>" elicits a NoSuchMethodException always (ctor != method)
+         @CallerSensitive
          public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
                                          Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
-             checkSpecialCaller(specialCaller);
 @@ -964,7 +968,7 @@
           *                                is set and {@code asVarargsCollector} fails
           * @throws NullPointerException if the argument is null
@@ -251,8 +243,8 @@
 +
 +
          /**
-          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
-          * This function performs stack walk magic: do not refactor it.
+          * Find my trustable caller class if m is a caller sensitive method.
+          * If this lookup object has private access, then the caller class is the lookupClass.
 @@ -1344,7 +1355,7 @@
      static public
      MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
@@ -512,3 +504,91 @@
          }
          if (verbosity >= 3)
              System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
+diff --git a/test/java/lang/invoke/BigArityTest.java b/test/java/lang/invoke/BigArityTest.java
+--- a/test/java/lang/invoke/BigArityTest.java
++++ b/test/java/lang/invoke/BigArityTest.java
+@@ -235,21 +235,41 @@
+             MethodHandle mh_VA = mh.asSpreader(cls, arity);
+             assert(mh_VA.type().parameterType(0) == cls);
+             testArities(cls, arity, iterations, verbose, mh, mh_VA);
++            // mh_CA will collect arguments of a particular type and pass them to mh_VA
++            MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
++            MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
++            assert(mh_CA.type().equals(mh.type()));
++            assert(mh_VA2.type().equals(mh_VA.type()));
+             if (cls != Object[].class) {
+-                // mh_CA will collect arguments of a particular type and pass them to mh_VA
+-                MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
+-                MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
+                 try {
+                     mh_VA2.invokeWithArguments(new Object[arity]);
+                     throw new AssertionError("should not reach");
+                 } catch (ClassCastException | WrongMethodTypeException ex) {
+                 }
+-                assert(mh_CA.type().equals(mh.type()));
+-                assert(mh_VA2.type().equals(mh_VA.type()));
+-                testArities(cls, arity, iterations, false, mh_CA, mh_VA2);
+             }
++            int iterations_VA = iterations / 100;
++            testArities(cls, arity, iterations_VA, false, mh_CA, mh_VA2);
+         }
+     }
++ 
++   /**
++     * Tests calls to {@link BigArityTest#hashArguments hashArguments} as related to a single given arity N.
++     * Applies the given {@code mh} to a set of N integer arguments, checking the answer.
++     * Also applies the varargs variation {@code mh_VA} to an array of type C[] (given by {@code cls}).
++     * Test steps:
++     * <ul>
++     * <li>mh_VA.invokeExact(new C[]{ arg, ... })</li>
++     * <li>mh.invokeWithArguments((Object[]) new C[]{ arg, ... })</li>
++     * <li>exactInvoker(mh.type()).invokeWithArguments(new Object[]{ mh, arg, ... })</li>
++     * <li>invoker(mh.type()).invokeWithArguments(new Object[]{ mh, arg, ... })</li>
++     * </ul>
++     * @param cls     array type for varargs call (one of Object[], Number[], Integer[], Comparable[])
++     * @param arity   N, the number of arguments to {@code mh} and length of its varargs array, in [0..255]
++     * @param iterations  number of times to repeat each test step (at least 4)
++     * @param verbose are we printing extra output?
++     * @param mh      a fixed-arity version of {@code hashArguments}
++     * @param mh_VA   a variable-arity version of {@code hashArguments}, accepting the given array type {@code cls}
++     */
+     private void testArities(Class<? extends Object[]> cls,
+                              int arity,
+                              int iterations,
+@@ -648,7 +668,6 @@
+     // </editor-fold>
+     a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+         assertEquals(r0, r);
+-        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+         r = ximh.invokeWithArguments(cat(mh,a));
+         assertEquals(r0, r);
+         MethodHandle gimh = MethodHandles.invoker(mh.type());
+@@ -674,7 +693,6 @@
+     // </editor-fold>
+     a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+         assertEquals(r0, r);
+-        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+         r = gimh.invokeWithArguments(cat(mh,a));
+         assertEquals(r0, r);
+         mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+@@ -812,6 +830,12 @@
+         assertEquals(r0, r);
+         MethodType mt = MethodType.genericMethodType(ARITY);
+         MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
++        test254(mh, a, r0);
++        MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY);
++        test254(mh_CA, a, r0);
++    }
++    public void test254(MethodHandle mh, Object[] a, Object r0) throws Throwable {
++        Object r;
+         r = mh.invokeExact(
+     // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+     a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+@@ -833,7 +857,6 @@
+     // </editor-fold>
+     a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+         assertEquals(r0, r);
+-        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+         r = mh.invokeWithArguments(a);
+         assertEquals(r0, r);
+         try {
--- a/series	Thu May 02 19:25:01 2013 -0700
+++ b/series	Tue May 14 22:58:15 2013 -0700
@@ -1,29 +1,31 @@
-# base = df5619994dc3 in http://hg.openjdk.java.net/hsx/hotspot-comp/jdk [2012-11-29]
+# base = 53be90fb39d6 in http://hg.openjdk.java.net/hsx/hotspot-comp/jdk [2013-04-25]
 
 # review complete for hotspot-comp:
 # (none)
 
-# review pending before push to hotspot-comp:
+# review pending before push to hotspot-comp (or tl):
+meth-doc-8014634.patch          #-/meth #+53be90fb39d6
+meth-info-8008688.patch         #-/meth #+53be90fb39d6
 
 # non-pushed files are under review or development, or merely experimental:
-anno-stable-8001107.patch       #-/meth #+df5619994dc3
-meth-lfi-8001106.patch          #-/meth #+df5619994dc3
-meth-info-7087570.patch         #-/meth #+df5619994dc3
-meth-aclone-8001105.patch       #-/meth #+df5619994dc3
-meth.patch                      #-/meth #+df5619994dc3
-meth-7177472.patch              #-/meth #+df5619994dc3 #-buildable
-indy.pack.patch                 #-/meth #+df5619994dc3 #-buildable
+anno-stable-8001107.patch       #-/meth #+53be90fb39d6 #-testable
+meth-lfi-8001106.patch          #-/meth #+53be90fb39d6 #-testable
+meth-aclone-8001105.patch       #-/meth #+53be90fb39d6
+meth-catch-8005625.patch        #-/meth #+53be90fb39d6
+indy-bsm-8005626.patch          #-/meth #+53be90fb39d6
+meth.patch                      #-/meth #+53be90fb39d6
+meth-7177472.patch              #-/meth #+53be90fb39d6 #-buildable
 
 # Keep these separate, for debugging and review:
 dyncast.patch   #+dyncast       #-/dyncast
 inti.patch      #+inti          #-/inti #-buildable
 callcc_old.patch #+callcc_old   #-/callcc_old
-continuation.patch #+continuation #-/continuation #(df5619994dc3)
+continuation.patch #+continuation #-/continuation #(53be90fb39d6)
 tailc.patch     #+tailc         #-/tailc
-anonk.patch                     #-/anonk #+df5619994dc3
+anonk.patch                     #-/anonk #+anonk
 
 # Coroutine patches: full version and simple version (no thread migration, no serialization, no stack sharing) 
-coro.patch                      #+coro          #(df5619994dc3)
-coro-simple.patch               #+coro-simple   #(df5619994dc3)
+coro.patch                      #+coro          #(53be90fb39d6)
+coro-simple.patch               #+coro-simple   #(53be90fb39d6)
 
 tuple-tsig.patch                #-/tuple #-testable