changeset 8824:0762fa26f813

Merge
author trims
date Tue, 29 Mar 2011 13:28:10 -0700
parents ddac2c4891b9 7cd28219a1e4
children 7863dcae4b91
files jdk/make/java/dyn/Makefile jdk/src/share/classes/java/dyn/CallSite.java jdk/src/share/classes/java/dyn/ClassValue.java jdk/src/share/classes/java/dyn/ConstantCallSite.java jdk/src/share/classes/java/dyn/InvokeDynamic.java jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java jdk/src/share/classes/java/dyn/Linkage.java jdk/src/share/classes/java/dyn/MethodHandle.java jdk/src/share/classes/java/dyn/MethodHandles.java jdk/src/share/classes/java/dyn/MethodType.java jdk/src/share/classes/java/dyn/MethodTypeForm.java jdk/src/share/classes/java/dyn/MutableCallSite.java jdk/src/share/classes/java/dyn/SwitchPoint.java jdk/src/share/classes/java/dyn/VolatileCallSite.java jdk/src/share/classes/java/dyn/WrongMethodTypeException.java jdk/src/share/classes/java/dyn/package-info.java jdk/src/share/classes/sun/dyn/Access.java jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java jdk/src/share/classes/sun/dyn/BoundMethodHandle.java jdk/src/share/classes/sun/dyn/CallSiteImpl.java jdk/src/share/classes/sun/dyn/DirectMethodHandle.java jdk/src/share/classes/sun/dyn/FilterGeneric.java jdk/src/share/classes/sun/dyn/FilterOneArgument.java jdk/src/share/classes/sun/dyn/FromGeneric.java jdk/src/share/classes/sun/dyn/InvokeGeneric.java jdk/src/share/classes/sun/dyn/Invokers.java jdk/src/share/classes/sun/dyn/MemberName.java jdk/src/share/classes/sun/dyn/MethodHandleImpl.java jdk/src/share/classes/sun/dyn/MethodHandleNatives.java jdk/src/share/classes/sun/dyn/MethodTypeImpl.java jdk/src/share/classes/sun/dyn/SpreadGeneric.java jdk/src/share/classes/sun/dyn/ToGeneric.java jdk/src/share/classes/sun/dyn/WrapperInstance.java jdk/src/share/classes/sun/dyn/anon/AnonymousClassLoader.java jdk/src/share/classes/sun/dyn/anon/ConstantPoolParser.java jdk/src/share/classes/sun/dyn/anon/ConstantPoolPatch.java jdk/src/share/classes/sun/dyn/anon/ConstantPoolVisitor.java jdk/src/share/classes/sun/dyn/anon/InvalidConstantPoolFormatException.java jdk/src/share/classes/sun/dyn/empty/Empty.java jdk/src/share/classes/sun/dyn/package-info.java jdk/src/share/classes/sun/dyn/util/BytecodeDescriptor.java jdk/src/share/classes/sun/dyn/util/BytecodeName.java jdk/src/share/classes/sun/dyn/util/ValueConversions.java jdk/src/share/classes/sun/dyn/util/VerifyAccess.java jdk/src/share/classes/sun/dyn/util/VerifyType.java jdk/src/share/classes/sun/dyn/util/Wrapper.java jdk/src/share/classes/sun/dyn/util/package-info.java jdk/test/java/dyn/ClassValueTest.java jdk/test/java/dyn/InvokeDynamicPrintArgs.java jdk/test/java/dyn/InvokeGenericTest.java jdk/test/java/dyn/JavaDocExamplesTest.java jdk/test/java/dyn/MethodHandlesTest.java jdk/test/java/dyn/MethodTypeTest.java jdk/test/java/dyn/indify/Indify.java
diffstat 111 files changed, 28026 insertions(+), 27869 deletions(-) [+]
line wrap: on
line diff
--- a/jdk/make/common/Release.gmk	Sat Mar 26 00:10:12 2011 -0700
+++ b/jdk/make/common/Release.gmk	Tue Mar 29 13:28:10 2011 -0700
@@ -54,9 +54,6 @@
                         com.sun.java.swing.plaf.motif    \
                         com.sun.java.swing.plaf.gtk
 
-# This is a stopgap until 6839872 is fixed.
-EXCLUDE_PROPWARN_PKGS += sun.dyn
-
 #
 # Include the exported private packages in ct.sym.
 # This is an interim solution until the ct.sym is replaced
--- a/jdk/make/docs/CORE_PKGS.gmk	Sat Mar 26 00:10:12 2011 -0700
+++ b/jdk/make/docs/CORE_PKGS.gmk	Tue Mar 29 13:28:10 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2011, 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
@@ -55,7 +55,7 @@
 # This is a list of regular expressions. So foo.* matches "foo" and "foo.bar".
 #
 ACTIVE_JSR_PKGS= \
-  java.dyn \
+  java.lang.invoke \
   java.sql  \
   javax.activation  \
   javax.annotation.*  \
@@ -97,11 +97,11 @@
   java.awt.print                                 \
   java.beans                                     \
   java.beans.beancontext                         \
-  java.dyn                                       \
   java.io                                        \
   java.lang                                      \
   java.lang.annotation                           \
   java.lang.instrument                           \
+  java.lang.invoke                               \
   java.lang.management                           \
   java.lang.ref                                  \
   java.lang.reflect                              \
--- a/jdk/make/java/Makefile	Sat Mar 26 00:10:12 2011 -0700
+++ b/jdk/make/java/Makefile	Tue Mar 29 13:28:10 2011 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2011, 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
@@ -44,7 +44,7 @@
 SUBDIRS_desktop    = awt applet beans
 SUBDIRS_management = management
 SUBDIRS_misc       = npt java_crw_demo java_hprof_demo \
-                     logging instrument dyn sql rmi
+                     logging instrument invoke sql rmi
 
 
 ifeq ($(PLATFORM), solaris)
--- a/jdk/make/java/dyn/Makefile	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#
-# Copyright (c) 2008, 2010, 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.
-#
-
-BUILDDIR = ../..
-
-PACKAGE = java.dyn
-PRODUCT = java
-include $(BUILDDIR)/common/Defs.gmk
-
-AUTO_FILES_JAVA_DIRS = java/dyn sun/dyn
-
-# The sources built here use new language syntax to generate
-# method handle calls.  Let's be sure we are using that format.
-LANGUAGE_VERSION = -source 7
-CLASS_VERSION = -target 7
-
-# Tell the compiler not to accept transitional forms.
-OTHER_JAVACFLAGS = -XDallowTransitionalJSR292=no
-
-include $(BUILDDIR)/common/Classes.gmk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/java/invoke/Makefile	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2008, 2011, 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.
+#
+
+BUILDDIR = ../..
+
+PACKAGE = java.lang.invoke
+PRODUCT = java
+include $(BUILDDIR)/common/Defs.gmk
+
+AUTO_FILES_JAVA_DIRS = java/lang/invoke sun/invoke
+FILES_java = \
+    java/lang/ClassValue.java \
+    java/lang/BootstrapMethodError.java
+
+# The sources built here use new language syntax to generate
+# method handle calls.  Let's be sure we are using that format.
+LANGUAGE_VERSION = -source 7
+CLASS_VERSION = -target 7
+
+include $(BUILDDIR)/common/Classes.gmk
--- a/jdk/src/share/classes/java/dyn/CallSite.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.dyn;
-
-import sun.dyn.*;
-import sun.dyn.empty.Empty;
-import sun.misc.Unsafe;
-import java.util.Collection;
-
-/**
- * A {@code CallSite} is a holder for a variable {@link MethodHandle},
- * which is called its {@code target}.
- * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
- * all calls to the site's current target.
- * A {@code CallSite} may be associated with several {@code invokedynamic}
- * instructions, or it may be "free floating", associated with none.
- * In any case, it may be invoked through an associated method handle
- * called its {@linkplain #dynamicInvoker dynamic invoker}.
- * <p>
- * {@code CallSite} is an abstract class which does not allow
- * direct subclassing by users.  It has three immediate,
- * concrete subclasses that may be either instantiated or subclassed.
- * <ul>
- * <li>If a mutable target is not required, an {@code invokedynamic} instruction
- * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
- * <li>If a mutable target is required which has volatile variable semantics,
- * because updates to the target must be immediately and reliably witnessed by other threads,
- * a {@linkplain VolatileCallSite volatile call site} may be used.
- * <li>Otherwise, if a mutable target is required,
- * a {@linkplain MutableCallSite mutable call site} may be used.
- * </ul>
- * <p>
- * A non-constant call site may be <em>relinked</em> by changing its target.
- * The new target must have the same {@linkplain MethodHandle#type() type}
- * as the previous target.
- * Thus, though a call site can be relinked to a series of
- * successive targets, it cannot change its type.
- * <p>
- * Here is a sample use of call sites and bootstrap methods which links every
- * dynamic call site to print its arguments:
-<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
-static void test() throws Throwable {
-    // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
-    InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
-}
-private static void printArgs(Object... args) {
-  System.out.println(java.util.Arrays.deepToString(args));
-}
-private static final MethodHandle printArgs;
-static {
-  MethodHandles.Lookup lookup = MethodHandles.lookup();
-  Class thisClass = lookup.lookupClass();  // (who am I?)
-  printArgs = lookup.findStatic(thisClass,
-      "printArgs", MethodType.methodType(void.class, Object[].class));
-}
-private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
-  // ignore caller and name, but match the type:
-  return new ConstantCallSite(printArgs.asType(type));
-}
-</pre></blockquote>
- * @author John Rose, JSR 292 EG
- */
-abstract
-public class CallSite {
-    private static final Access IMPL_TOKEN = Access.getToken();
-    static { MethodHandleImpl.initStatics(); }
-
-    // Fields used only by the JVM.  Do not use or change.
-    private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
-    private int        vmindex;  // supplied by the JVM (BCI within calling method)
-
-    // The actual payload of this call site:
-    /*package-private*/
-    MethodHandle target;
-
-    // Remove this field for PFD and delete deprecated methods:
-    private MemberName calleeNameRemoveForPFD;
-
-    /**
-     * Make a blank call site object with the given method type.
-     * An initial target method is supplied which will throw
-     * an {@link IllegalStateException} if called.
-     * <p>
-     * Before this {@code CallSite} object is returned from a bootstrap method,
-     * it is usually provided with a more useful target method,
-     * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
-     * @throws NullPointerException if the proposed type is null
-     */
-    /*package-private*/
-    CallSite(MethodType type) {
-        target = MethodHandles.invokers(type).uninitializedCallSite();
-    }
-
-    /**
-     * Make a blank call site object, possibly equipped with an initial target method handle.
-     * @param target the method handle which will be the initial target of the call site
-     * @throws NullPointerException if the proposed target is null
-     */
-    /*package-private*/
-    CallSite(MethodHandle target) {
-        target.type();  // null check
-        this.target = target;
-    }
-
-    /**
-     * Returns the type of this call site's target.
-     * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
-     * The {@code setTarget} method enforces this invariant by refusing any new target that does
-     * not have the previous target's type.
-     * @return the type of the current target, which is also the type of any future target
-     */
-    public MethodType type() {
-        return target.type();
-    }
-
-    /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
-     *  The parameters are JVM-specific.
-     */
-    void initializeFromJVM(String name,
-                           MethodType type,
-                           MemberName callerMethod,
-                           int        callerBCI) {
-        if (this.vmmethod != null) {
-            // FIXME
-            throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction");
-        }
-        if (!this.type().equals(type)) {
-            throw wrongTargetType(target, type);
-        }
-        this.vmindex  = callerBCI;
-        this.vmmethod = callerMethod;
-    }
-
-    /**
-     * Returns the target method of the call site, according to the
-     * behavior defined by this call site's specific class.
-     * The immediate subclasses of {@code CallSite} document the
-     * class-specific behaviors of this method.
-     *
-     * @return the current linkage state of the call site, its target method handle
-     * @see ConstantCallSite
-     * @see VolatileCallSite
-     * @see #setTarget
-     * @see ConstantCallSite#getTarget
-     * @see MutableCallSite#getTarget
-     * @see VolatileCallSite#getTarget
-     */
-    public abstract MethodHandle getTarget();
-
-    /**
-     * Updates the target method of this call site, according to the
-     * behavior defined by this call site's specific class.
-     * The immediate subclasses of {@code CallSite} document the
-     * class-specific behaviors of this method.
-     * <p>
-     * The type of the new target must be {@linkplain MethodType#equals equal to}
-     * the type of the old target.
-     *
-     * @param newTarget the new target
-     * @throws NullPointerException if the proposed new target is null
-     * @throws WrongMethodTypeException if the proposed new target
-     *         has a method type that differs from the previous target
-     * @see CallSite#getTarget
-     * @see ConstantCallSite#setTarget
-     * @see MutableCallSite#setTarget
-     * @see VolatileCallSite#setTarget
-     */
-    public abstract void setTarget(MethodHandle newTarget);
-
-    void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
-        MethodType oldType = oldTarget.type();
-        MethodType newType = newTarget.type();  // null check!
-        if (!newType.equals(oldType))
-            throw wrongTargetType(newTarget, oldType);
-    }
-
-    private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
-        return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
-    }
-
-    /**
-     * Produce a method handle equivalent to an invokedynamic instruction
-     * which has been linked to this call site.
-     * <p>
-     * This method is equivalent to the following code:
-     * <blockquote><pre>
-     * MethodHandle getTarget, invoker, result;
-     * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
-     * invoker = MethodHandles.exactInvoker(this.type());
-     * result = MethodHandles.foldArguments(invoker, getTarget)
-     * </pre></blockquote>
-     *
-     * @return a method handle which always invokes this call site's current target
-     */
-    public abstract MethodHandle dynamicInvoker();
-
-    /*non-public*/ MethodHandle makeDynamicInvoker() {
-        MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this);
-        MethodHandle invoker = MethodHandles.exactInvoker(this.type());
-        return MethodHandles.foldArguments(invoker, getTarget);
-    }
-
-    private static final MethodHandle GET_TARGET;
-    static {
-        try {
-            GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP.
-                findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
-        } catch (ReflectiveOperationException ignore) {
-            throw new InternalError();
-        }
-    }
-
-    /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
-    /*package-private*/
-    static Empty uninitializedCallSite() {
-        throw new IllegalStateException("uninitialized call site");
-    }
-
-    // unsafe stuff:
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long TARGET_OFFSET;
-
-    static {
-        try {
-            TARGET_OFFSET = unsafe.objectFieldOffset(CallSite.class.getDeclaredField("target"));
-        } catch (Exception ex) { throw new Error(ex); }
-    }
-
-    /*package-private*/
-    void setTargetNormal(MethodHandle newTarget) {
-        target = newTarget;
-        //CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
-    }
-    /*package-private*/
-    MethodHandle getTargetVolatile() {
-        return (MethodHandle) unsafe.getObjectVolatile(this, TARGET_OFFSET);
-    }
-    /*package-private*/
-    void setTargetVolatile(MethodHandle newTarget) {
-        unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
-        //CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/ClassValue.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.dyn;
-
-import java.util.WeakHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.lang.reflect.UndeclaredThrowableException;
-
-/**
- * Lazily associate a computed value with (potentially) every type.
- * For example, if a dynamic language needs to construct a message dispatch
- * table for each class encountered at a message send call site,
- * it can use a {@code ClassValue} to cache information needed to
- * perform the message send quickly, for each class encountered.
- * @author John Rose, JSR 292 EG
- */
-public abstract class ClassValue<T> {
-    /**
-     * Compute the given class's derived value for this {@code ClassValue}.
-     * <p>
-     * This method will be invoked within the first thread that accesses
-     * the value with the {@link #get get} method.
-     * <p>
-     * Normally, this method is invoked at most once per class,
-     * but it may be invoked again if there has been a call to
-     * {@link #remove remove}.
-     * <p>
-     * If this method throws an exception, the corresponding call to {@code get}
-     * will terminate abnormally with that exception, and no class value will be recorded.
-     *
-     * @param type the type whose class value must be computed
-     * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface
-     * @see #get
-     * @see #remove
-     */
-    protected abstract T computeValue(Class<?> type);
-
-    /**
-     * Returns the value for the given class.
-     * If no value has yet been computed, it is obtained by
-     * an invocation of the {@link #computeValue computeValue} method.
-     * <p>
-     * The actual installation of the value on the class
-     * is performed atomically.
-     * At that point, if several racing threads have
-     * computed values, one is chosen, and returned to
-     * all the racing threads.
-     * <p>
-     * The {@code type} parameter is typically a class, but it may be any type,
-     * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}.
-     * <p>
-     * In the absence of {@code remove} calls, a class value has a simple
-     * state diagram:  uninitialized and initialized.
-     * When {@code remove} calls are made,
-     * the rules for value observation are more complex.
-     * See the documentation for {@link #remove remove} for more information.
-     *
-     * @param type the type whose class value must be computed or retrieved
-     * @return the current value associated with this {@code ClassValue}, for the given class or interface
-     * @throws NullPointerException if the argument is null
-     * @see #remove
-     * @see #computeValue
-     */
-    public T get(Class<?> type) {
-        ClassValueMap map = getMap(type);
-        if (map != null) {
-            Object x = map.get(this);
-            if (x != null) {
-                return (T) map.unmaskNull(x);
-            }
-        }
-        return setComputedValue(type);
-    }
-
-    /**
-     * Removes the associated value for the given class.
-     * If this value is subsequently {@linkplain #get read} for the same class,
-     * its value will be reinitialized by invoking its {@link #computeValue computeValue} method.
-     * This may result in an additional invocation of the
-     * {@code computeValue computeValue} method for the given class.
-     * <p>
-     * In order to explain the interaction between {@code get} and {@code remove} calls,
-     * we must model the state transitions of a class value to take into account
-     * the alternation between uninitialized and initialized states.
-     * To do this, number these states sequentially from zero, and note that
-     * uninitialized (or removed) states are numbered with even numbers,
-     * while initialized (or re-initialized) states have odd numbers.
-     * <p>
-     * When a thread {@code T} removes a class value in state {@code 2N},
-     * nothing happens, since the class value is already uninitialized.
-     * Otherwise, the state is advanced atomically to {@code 2N+1}.
-     * <p>
-     * When a thread {@code T} queries a class value in state {@code 2N},
-     * the thread first attempts to initialize the class value to state {@code 2N+1}
-     * by invoking {@code computeValue} and installing the resulting value.
-     * <p>
-     * When {@code T} attempts to install the newly computed value,
-     * if the state is still at {@code 2N}, the class value will be initialized
-     * with the computed value, advancing it to state {@code 2N+1}.
-     * <p>
-     * Otherwise, whether the new state is even or odd,
-     * {@code T} will discard the newly computed value
-     * and retry the {@code get} operation.
-     * <p>
-     * Discarding and retrying is an important proviso,
-     * since otherwise {@code T} could potentially install
-     * a disastrously stale value.  For example:
-     * <ul>
-     * <li>{@code T} calls {@code CV.get(C)} and sees state {@code 2N}
-     * <li>{@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it
-     * <li>{@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time
-     * <li>...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N}
-     * <li>{@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)}
-     * <li>{@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work
-     * <li> the previous actions of {@code T2} are repeated several times
-     * <li> also, the relevant computed values change over time: {@code V1}, {@code V2}, ...
-     * <li>...meanwhile, {@code T} wakes up and attempts to install {@code V0}; <em>this must fail</em>
-     * </ul>
-     * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
-     * observe the time-dependent states as it computes {@code V1}, etc.
-     * This does not remove the threat of a stale value, since there is a window of time
-     * between the return of {@code computeValue} in {@code T} and the installation
-     * of the the new value.  No user synchronization is possible during this time.
-     *
-     * @param type the type whose class value must be removed
-     * @throws NullPointerException if the argument is null
-     */
-    public void remove(Class<?> type) {
-        ClassValueMap map = getMap(type);
-        if (map != null) {
-            synchronized (map) {
-                map.remove(this);
-            }
-        }
-    }
-
-    /// Implementation...
-
-    // The hash code for this type is based on the identity of the object,
-    // and is well-dispersed for power-of-two tables.
-    /** @deprecated This override, which is implementation-specific, will be removed for PFD. */
-    public final int hashCode() { return hashCode; }
-    private final int hashCode = HASH_CODES.getAndAdd(0x61c88647);
-    private static final AtomicInteger HASH_CODES = new AtomicInteger();
-
-    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
-
-    /** Slow path for {@link #get}. */
-    private T setComputedValue(Class<?> type) {
-        ClassValueMap map = getMap(type);
-        if (map == null) {
-            map = initializeMap(type);
-        }
-        T value = computeValue(type);
-        STORE_BARRIER.lazySet(0);
-        // All stores pending from computeValue are completed.
-        synchronized (map) {
-            // Warm up the table with a null entry.
-            map.preInitializeEntry(this);
-        }
-        STORE_BARRIER.lazySet(0);
-        // All stores pending from table expansion are completed.
-        synchronized (map) {
-            value = (T) map.initializeEntry(this, value);
-            // One might fear a possible race condition here
-            // if the code for map.put has flushed the write
-            // to map.table[*] before the writes to the Map.Entry
-            // are done.  This is not possible, since we have
-            // warmed up the table with an empty entry.
-        }
-        return value;
-    }
-
-    // Replace this map by a per-class slot.
-    private static final WeakHashMap<Class<?>, ClassValueMap> ROOT
-        = new WeakHashMap<Class<?>, ClassValueMap>();
-
-    private static ClassValueMap getMap(Class<?> type) {
-        return ROOT.get(type);
-    }
-
-    private static ClassValueMap initializeMap(Class<?> type) {
-        synchronized (ClassValue.class) {
-            ClassValueMap map = ROOT.get(type);
-            if (map == null)
-                ROOT.put(type, map = new ClassValueMap());
-            return map;
-        }
-    }
-
-    static class ClassValueMap extends WeakHashMap<ClassValue, Object> {
-        /** Make sure this table contains an Entry for the given key, even if it is empty. */
-        void preInitializeEntry(ClassValue key) {
-            if (!this.containsKey(key))
-                this.put(key, null);
-        }
-        /** Make sure this table contains a non-empty Entry for the given key. */
-        Object initializeEntry(ClassValue key, Object value) {
-            Object prior = this.get(key);
-            if (prior != null) {
-                return unmaskNull(prior);
-            }
-            this.put(key, maskNull(value));
-            return value;
-        }
-
-        Object maskNull(Object x) {
-            return x == null ? this : x;
-        }
-        Object unmaskNull(Object x) {
-            return x == this ? null : x;
-        }
-    }
-}
--- a/jdk/src/share/classes/java/dyn/ConstantCallSite.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.dyn;
-
-/**
- * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
- * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
- * bound to the call site's target.
- * @author John Rose, JSR 292 EG
- */
-public class ConstantCallSite extends CallSite {
-    /**
-     * Creates a call site with a permanent target.
-     * @param target the target to be permanently associated with this call site
-     * @throws NullPointerException if the proposed target is null
-     */
-    public ConstantCallSite(MethodHandle target) {
-        super(target);
-    }
-
-    /**
-     * Returns the target method of the call site, which behaves
-     * like a {@code final} field of the {@code ConstantCallSite}.
-     * That is, the the target is always the original value passed
-     * to the constructor call which created this instance.
-     *
-     * @return the immutable linkage state of this call site, a constant method handle
-     * @throws UnsupportedOperationException because this kind of call site cannot change its target
-     */
-    @Override public final MethodHandle getTarget() {
-        return target;
-    }
-
-    /**
-     * Always throws an {@link UnsupportedOperationException}.
-     * This kind of call site cannot change its target.
-     * @param ignore a new target proposed for the call site, which is ignored
-     * @throws UnsupportedOperationException because this kind of call site cannot change its target
-     */
-    @Override public final void setTarget(MethodHandle ignore) {
-        throw new UnsupportedOperationException("ConstantCallSite");
-    }
-
-    /**
-     * Returns this call site's permanent target.
-     * Since that target will never change, this is a correct implementation
-     * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
-     * @return the immutable linkage state of this call site, a constant method handle
-     */
-    @Override
-    public final MethodHandle dynamicInvoker() {
-        return getTarget();
-    }
-}
--- a/jdk/src/share/classes/java/dyn/InvokeDynamic.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.dyn;
-
-/**
- * This is a place-holder class.  Some HotSpot implementations need to see it.
- */
-final class InvokeDynamic {
-    private InvokeDynamic() { throw new InternalError(); }  // do not instantiate
-}
--- a/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.dyn;
-
-/**
- * Thrown to indicate that an {@code invokedynamic} instruction has
- * failed to find its
- * {@linkplain BootstrapMethod bootstrap method},
- * or the bootstrap method has
- * failed to provide a
- * {@linkplain CallSite call site} with a {@linkplain CallSite#getTarget target}
- * of the correct {@linkplain MethodHandle#type method type}.
- *
- * @author John Rose, JSR 292 EG
- * @since 1.7
- */
-public class InvokeDynamicBootstrapError extends LinkageError {
-    private static final long serialVersionUID = 292L;
-
-    /**
-     * Constructs an {@code InvokeDynamicBootstrapError} with no detail message.
-     */
-    public InvokeDynamicBootstrapError() {
-        super();
-    }
-
-    /**
-     * Constructs an {@code InvokeDynamicBootstrapError} with the specified
-     * detail message.
-     *
-     * @param s the detail message.
-     */
-    public InvokeDynamicBootstrapError(String s) {
-        super(s);
-    }
-
-    /**
-     * Constructs a {@code InvokeDynamicBootstrapError} with the specified
-     * detail message and cause.
-     *
-     * @param s the detail message.
-     * @param cause the cause, may be {@code null}.
-     */
-    public InvokeDynamicBootstrapError(String s, Throwable cause) {
-        super(s, cause);
-    }
-
-    /**
-     * Constructs a {@code InvokeDynamicBootstrapError} with the specified
-     * cause.
-     *
-     * @param cause the cause, may be {@code null}.
-     */
-    public InvokeDynamicBootstrapError(Throwable cause) {
-        // cf. Throwable(Throwable cause) constructor.
-        super(cause == null ? null : cause.toString());
-        initCause(cause);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/Linkage.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.dyn;
-
-import java.dyn.MethodHandles.Lookup;
-import java.util.WeakHashMap;
-import sun.dyn.Access;
-import sun.dyn.MethodHandleImpl;
-import sun.dyn.util.VerifyAccess;
-import sun.reflect.Reflection;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * <em>CLASS WILL BE REMOVED FOR PFD:</em>
- * Static routines for controlling invokedynamic behavior.
- * Replaced by non-static APIs.
- * @author John Rose, JSR 292 EG
- * @deprecated This class will be removed in the Public Final Draft.
- */
-public class Linkage {
-    private static final Access IMPL_TOKEN = Access.getToken();
-
-    private Linkage() {}  // do not instantiate
-
-    /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
-     * Register a <em>bootstrap method</em> to use when linking dynamic call sites within
-     * a given caller class.
-     * @deprecated Use @{@link BootstrapMethod} annotations instead.
-     */
-    public static
-    void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
-        Class callc = Reflection.getCallerClass(2);
-        if (callc != null && !VerifyAccess.isSamePackage(callerClass, callc))
-            throw new IllegalArgumentException("cannot set bootstrap method on "+callerClass);
-        MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
-    }
-
-    /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
-     * Simplified version of {@code registerBootstrapMethod} for self-registration,
-     * to be called from a static initializer.
-     * @deprecated Use @{@link BootstrapMethod} annotations instead.
-     */
-    public static
-    void registerBootstrapMethod(Class<?> runtime, String name) {
-        Class callerClass = Reflection.getCallerClass(2);
-        registerBootstrapMethodLookup(callerClass, runtime, name);
-    }
-
-    /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
-     * Simplified version of {@code registerBootstrapMethod} for self-registration,
-     * @deprecated Use @{@link BootstrapMethod} annotations instead.
-     */
-    public static
-    void registerBootstrapMethod(String name) {
-        Class callerClass = Reflection.getCallerClass(2);
-        registerBootstrapMethodLookup(callerClass, callerClass, name);
-    }
-
-    private static
-    void registerBootstrapMethodLookup(Class<?> callerClass, Class<?> runtime, String name) {
-        Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
-        MethodHandle bootstrapMethod;
-        try {
-            bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
-        } catch (ReflectiveOperationException ex) {
-            throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
-        }
-        MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
-    }
-
-    private static final MethodType BOOTSTRAP_METHOD_TYPE
-            = MethodType.methodType(CallSite.class,
-                                    Class.class, String.class, MethodType.class);
-
-    /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
-     * Invalidate all <code>invokedynamic</code> call sites everywhere.
-     * @deprecated Use {@linkplain MutableCallSite#setTarget call site target setting},
-     * {@link MutableCallSite#syncAll call site update pushing},
-     * and {@link SwitchPoint#guardWithTest target switching} instead.
-     */
-    public static
-    Object invalidateAll() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * <em>METHOD WILL BE REMOVED FOR PFD:</em>
-     * Invalidate all {@code invokedynamic} call sites in the bytecodes
-     * of any methods of the given class.
-     * @deprecated Use {@linkplain MutableCallSite#setTarget call site target setting},
-     * {@link MutableCallSite#syncAll call site update pushing},
-     * and {@link SwitchPoint#guardWithTest target switching} instead.
-     */
-    public static
-    Object invalidateCallerClass(Class<?> callerClass) {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/jdk/src/share/classes/java/dyn/MethodHandle.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1009 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.dyn;
-
-//import sun.dyn.*;
-
-import sun.dyn.Access;
-import sun.dyn.MethodHandleImpl;
-
-import static java.dyn.MethodHandles.invokers;  // package-private API
-import static sun.dyn.MemberName.newIllegalArgumentException;  // utility
-
-/**
- * A method handle is a typed, directly executable reference to an underlying method,
- * constructor, field, or similar low-level operation, with optional
- * transformations of arguments or return values.
- * These transformations are quite general, and include such patterns as
- * {@linkplain #asType conversion},
- * {@linkplain #bindTo insertion},
- * {@linkplain java.dyn.MethodHandles#dropArguments deletion},
- * and {@linkplain java.dyn.MethodHandles#filterArguments substitution}.
- * <p>
- * <em>Note: The super-class of MethodHandle is Object.
- *     Any other super-class visible in the Reference Implementation
- *     will be removed before the Proposed Final Draft.
- *     Also, the final version will not include any public or
- *     protected constructors.</em>
- *
- * <h3>Method handle contents</h3>
- * Method handles are dynamically and strongly typed according to type descriptor.
- * They are not distinguished by the name or defining class of their underlying methods.
- * A method handle must be invoked using type descriptor which matches
- * the method handle's own {@linkplain #type method type}.
- * <p>
- * Every method handle reports its type via the {@link #type type} accessor.
- * This type descriptor is a {@link java.dyn.MethodType MethodType} object,
- * whose structure is a series of classes, one of which is
- * the return type of the method (or {@code void.class} if none).
- * <p>
- * A method handle's type controls the types of invocations it accepts,
- * and the kinds of transformations that apply to it.
- * <p>
- * A method handle contains a pair of special invoker methods
- * called {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.
- * Both invoker methods provide direct access to the method handle's
- * underlying method, constructor, field, or other operation,
- * as modified by transformations of arguments and return values.
- * Both invokers accept calls which exactly match the method handle's own type.
- * The {@code invokeGeneric} invoker also accepts a range of other call types.
- * <p>
- * Method handles are immutable and have no visible state.
- * Of course, they can be bound to underlying methods or data which exhibit state.
- * With respect to the Java Memory Model, any method handle will behave
- * as if all of its (internal) fields are final variables.  This means that any method
- * handle made visible to the application will always be fully formed.
- * This is true even if the method handle is published through a shared
- * variable in a data race.
- * <p>
- * Method handles cannot be subclassed by the user.
- * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
- * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
- * operation.  The programmer should not draw conclusions about a method handle
- * 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>
- * A Java method call expression naming {@code invokeExact} or {@code invokeGeneric}
- * can invoke a method handle from Java source code.
- * From the viewpoint of source code, these methods can take any arguments
- * and their result can be cast to any return type.
- * Formally this is accomplished by giving the invoker methods
- * {@code Object} return types and variable-arity {@code Object} arguments,
- * but they have an additional quality called <em>signature polymorphism</em>
- * which connects this freedom of invocation directly to the JVM execution stack.
- * <p>
- * As is usual with virtual methods, source-level calls to {@code invokeExact}
- * and {@code invokeGeneric} compile to an {@code invokevirtual} instruction.
- * More unusually, the compiler must record the actual argument types,
- * and may not perform method invocation conversions on the arguments.
- * Instead, it must push them on the stack according to their own unconverted types.
- * The method handle object itself is pushed on the stack before the arguments.
- * The compiler then calls the method handle with a type descriptor which
- * describes the argument and return types.
- * <p>
- * To issue a complete type descriptor, the compiler must also determine
- * the return type.  This is based on a cast on the method invocation expression,
- * if there is one, or else {@code Object} if the invocation is an expression
- * or else {@code void} if the invocation is a statement.
- * The cast may be to a primitive type (but not {@code void}).
- * <p>
- * As a corner case, an uncasted {@code null} argument is given
- * a type descriptor of {@code java.lang.Void}.
- * 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>
- * 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.
- * This is true of calls to {@code invokeExact} and {@code invokeGeneric}.
- * In this case, the type descriptor emitted by the compiler is checked for
- * correct syntax and names it contains are resolved.
- * Thus, an {@code invokevirtual} instruction which invokes
- * a method handle will always link, as long
- * as the type descriptor is syntactically well-formed
- * and the types exist.
- * <p>
- * When the {@code invokevirtual} is executed after linking,
- * the receiving method handle's type is first checked by the JVM
- * to ensure that it matches the descriptor.
- * If the type match fails, it means that the method which the
- * caller is invoking is not present on the individual
- * method handle being invoked.
- * <p>
- * In the case of {@code invokeExact}, the type descriptor of the invocation
- * (after resolving symbolic type names) must exactly match the method type
- * of the receiving method handle.
- * In the case of {@code invokeGeneric}, the resolved type descriptor
- * must be a valid argument to the receiver's {@link #asType asType} method.
- * Thus, {@code invokeGeneric} is more permissive than {@code invokeExact}.
- * <p>
- * After type matching, a call to {@code invokeExact} directly
- * and immediately invoke the method handle's underlying method
- * (or other behavior, as the case may be).
- * <p>
- * A call to {@code invokeGeneric} works the same as a call to
- * {@code invokeExact}, if the type descriptor specified by the caller
- * exactly matches the method handle's own type.
- * If there is a type mismatch, {@code invokeGeneric} attempts
- * to adjust the type of the receiving method handle,
- * as if by a call to {@link #asType asType},
- * to obtain an exactly invokable method handle {@code M2}.
- * This allows a more powerful negotiation of method type
- * between caller and callee.
- * <p>
- * (Note: The adjusted method handle {@code M2} is not directly observable,
- * and implementations are therefore not required to materialize it.)
- *
- * <h3>Invocation checking</h3>
- * 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
- * by a failed call to {@code asType} (in the case of {@code invokeGeneric}).
- * <p>
- * Thus, a method type mismatch which might show up as a linkage error
- * in a statically typed program can show up as
- * a dynamic {@code WrongMethodTypeException}
- * in a program which uses method handles.
- * <p>
- * Because method types contain "live" {@code Class} objects,
- * method type matching takes into account both types names and class loaders.
- * Thus, even if a method handle {@code M} is created in one
- * class loader {@code L1} and used in another {@code L2},
- * method handle calls are type-safe, because the caller's type
- * descriptor, as resolved in {@code L2},
- * is matched against the original callee method's type descriptor,
- * as resolved in {@code L1}.
- * The resolution in {@code L1} happens when {@code M} is created
- * and its type is assigned, while the resolution in {@code L2} happens
- * when the {@code invokevirtual} instruction is linked.
- * <p>
- * Apart from the checking of type descriptors,
- * a method handle's capability to call its underlying method is unrestricted.
- * If a method handle is formed on a non-public method by a class
- * that has access to that method, the resulting handle can be used
- * in any place by any caller who receives a reference to it.
- * <p>
- * Unlike with the Core Reflection API, where access is checked every time
- * a reflective method is invoked,
- * method handle access checking is performed
- * <a href="MethodHandles.Lookup.html#access">when the method handle is created</a>.
- * In the case of {@code ldc} (see below), access checking is performed as part of linking
- * the constant pool entry underlying the constant method handle.
- * <p>
- * Thus, handles to non-public methods, or to methods in non-public classes,
- * should generally be kept secret.
- * They should not be passed to untrusted code unless their use from
- * the untrusted code would be harmless.
- *
- * <h3>Method handle creation</h3>
- * 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
- * {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup}
- * For example, a static method handle can be obtained
- * from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}.
- * There are also conversion methods from Core Reflection API objects,
- * such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}.
- * <p>
- * Like classes and strings, method handles that correspond to accessible
- * fields, methods, and constructors can also be represented directly
- * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
- * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
- * refers directly to an associated {@code CONSTANT_Methodref},
- * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
- * constant pool entry.
- * (For more details on method handle constants,
- * see the <a href="package-summary.html#mhcon">package summary</a>.)
- * <p>
- * Method handles produced by lookups or constant loads from methods or
- * constructors with the variable arity modifier bit ({@code 0x0080})
- * have a corresponding variable arity, as if they were defined with
- * the help of {@link #asVarargsCollector asVarargsCollector}.
- * <p>
- * A method reference may refer either to a static or non-static method.
- * In the non-static case, the method handle type includes an explicit
- * receiver argument, prepended before any other arguments.
- * In the method handle's type, the initial receiver argument is typed
- * according to the class under which the method was initially requested.
- * (E.g., if a non-static method handle is obtained via {@code ldc},
- * the type of the receiver is the class named in the constant pool entry.)
- * <p>
- * When a method handle to a virtual method is invoked, the method is
- * always looked up in the receiver (that is, the first argument).
- * <p>
- * A non-virtual method handle to a specific virtual method implementation
- * can also be created.  These do not perform virtual lookup based on
- * receiver type.  Such a method handle simulates the effect of
- * an {@code invokespecial} instruction to the same method.
- *
- * <h3>Usage examples</h3>
- * Here are some examples of usage:
- * <p><blockquote><pre>
-Object x, y; String s; int i;
-MethodType mt; MethodHandle mh;
-MethodHandles.Lookup lookup = MethodHandles.lookup();
-// mt is (char,char)String
-mt = MethodType.methodType(String.class, char.class, char.class);
-mh = lookup.findVirtual(String.class, "replace", mt);
-s = (String) mh.invokeExact("daddy",'d','n');
-// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
-assert(s.equals("nanny"));
-// weakly typed invocation (using MHs.invoke)
-s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
-assert(s.equals("savvy"));
-// mt is (Object[])List
-mt = MethodType.methodType(java.util.List.class, Object[].class);
-mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
-assert(mh.isVarargsCollector());
-x = mh.invokeGeneric("one", "two");
-// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
-assert(x.equals(java.util.Arrays.asList("one","two")));
-// mt is (Object,Object,Object)Object
-mt = MethodType.genericMethodType(3);
-mh = mh.asType(mt);
-x = mh.invokeExact((Object)1, (Object)2, (Object)3);
-// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-assert(x.equals(java.util.Arrays.asList(1,2,3)));
-// mt is { =&gt; int}
-mt = MethodType.methodType(int.class);
-mh = lookup.findVirtual(java.util.List.class, "size", mt);
-i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
-// invokeExact(Ljava/util/List;)I
-assert(i == 3);
-mt = MethodType.methodType(void.class, String.class);
-mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
-mh.invokeExact(System.out, "Hello, world.");
-// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
- * </pre></blockquote>
- * Each of the above calls to {@code invokeExact} or {@code invokeGeneric}
- * generates a single invokevirtual instruction with
- * the type descriptor indicated in the following comment.
- *
- * <h3>Exceptions</h3>
- * The methods {@code invokeExact} and {@code invokeGeneric} are declared
- * to throw {@link java.lang.Throwable Throwable},
- * which is to say that there is no static restriction on what a method handle
- * can throw.  Since the JVM does not distinguish between checked
- * and unchecked exceptions (other than by their class, of course),
- * there is no particular effect on bytecode shape from ascribing
- * checked exceptions to method handle invocations.  But in Java source
- * code, methods which perform method handle calls must either explicitly
- * throw {@code java.lang.Throwable Throwable}, or else must catch all
- * 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>
- * The unusual compilation and linkage behavior of
- * {@code invokeExact} and {@code invokeGeneric}
- * is referenced by the term <em>signature polymorphism</em>.
- * A signature polymorphic method is one which can operate with
- * any of a wide range of call signatures and return types.
- * In order to make this work, both the Java compiler and the JVM must
- * give special treatment to signature polymorphic methods.
- * <p>
- * In source code, a call to a signature polymorphic method will
- * compile, regardless of the requested type descriptor.
- * As usual, the Java compiler emits an {@code invokevirtual}
- * instruction with the given type descriptor against the named method.
- * The unusual part is that the type descriptor is derived from
- * the actual argument and return types, not from the method declaration.
- * <p>
- * When the JVM processes bytecode containing signature polymorphic calls,
- * it will successfully link any such call, regardless of its type descriptor.
- * (In order to retain type safety, the JVM will guard such calls with suitable
- * dynamic type checks, as described elsewhere.)
- * <p>
- * Bytecode generators, including the compiler back end, are required to emit
- * untransformed type descriptors for these methods.
- * Tools which determine symbolic linkage are required to accept such
- * untransformed descriptors, without reporting linkage errors.
- * <p>
- * For the sake of tools (but not as a programming API), the signature polymorphic
- * methods are marked with a private yet standard annotation,
- * {@code @java.dyn.MethodHandle.PolymorphicSignature}.
- * The annotation's retention is {@code RUNTIME}, so that all tools can see it.
- *
- * <h3>Formal rules for processing signature polymorphic methods</h3>
- * <p>
- * The following methods (and no others) are signature polymorphic:
- * <ul>
- * <li>{@link java.dyn.MethodHandle#invokeExact   MethodHandle.invokeExact}
- * <li>{@link java.dyn.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
- * </ul>
- * <p>
- * A signature polymorphic method will be declared with the following properties:
- * <ul>
- * <li>It must be native.
- * <li>It must take a single varargs parameter of the form {@code Object...}.
- * <li>It must produce a return value of type {@code Object}.
- * <li>It must be contained within the {@code java.dyn} package.
- * </ul>
- * Because of these requirements, a signature polymorphic method is able to accept
- * any number and type of actual arguments, and can, with a cast, produce a value of any type.
- * However, the JVM will treat these declaration features as a documentation convention,
- * rather than a description of the actual structure of the methods as executed.
- * <p>
- * When a call to a signature polymorphic method is compiled, the associated linkage information for
- * its arguments is not array of {@code Object} (as for other similar varargs methods)
- * but rather the erasure of the static types of all the arguments.
- * <p>
- * In an argument position of a method invocation on a signature polymorphic method,
- * a null literal has type {@code java.lang.Void}, unless cast to a reference type.
- * (Note: This typing rule allows the null type to have its own encoding in linkage information
- * distinct from other types.
- * <p>
- * The linkage information for the return type is derived from a context-dependent target typing convention.
- * The return type for a signature polymorphic method invocation is determined as follows:
- * <ul>
- * <li>If the method invocation expression is an expression statement, the method is {@code void}.
- * <li>Otherwise, if the method invocation expression is the immediate operand of a cast,
- * the return type is the erasure of the cast type.
- * <li>Otherwise, the return type is the method's nominal return type, {@code Object}.
- * </ul>
- * (Programmers are encouraged to use explicit casts unless it is clear that a signature polymorphic
- * call will be used as a plain {@code Object} expression.)
- * <p>
- * The linkage information for argument and return types is stored in the descriptor for the
- * compiled (bytecode) call site. As for any invocation instruction, the arguments and return value
- * will be passed directly on the JVM stack, in accordance with the descriptor,
- * and without implicit boxing or unboxing.
- *
- * <h3>Interoperation between method handles and the Core Reflection API</h3>
- * Using factory methods in the {@link java.dyn.MethodHandles.Lookup Lookup} API,
- * any class member represented by a Core Reflection API object
- * can be converted to a behaviorally equivalent method handle.
- * For example, a reflective {@link java.lang.reflect.Method Method} can
- * be converted to a method handle using
- * {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}.
- * The resulting method handles generally provide more direct and efficient
- * access to the underlying class members.
- * <p>
- * As a special case,
- * when the Core Reflection API is used to view the signature polymorphic
- * methods {@code invokeExact} or {@code invokeGeneric} in this class,
- * they appear as single, non-polymorphic native methods.
- * Calls to these native methods do not result in method handle invocations.
- * Since {@code invokevirtual} instructions can natively
- * invoke method handles under any type descriptor, this reflective view conflicts
- * with the normal presentation via bytecodes.
- * Thus, these two native methods, as viewed by
- * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
- * are placeholders only.
- * If invoked via {@link java.lang.reflect.Method#invoke Method.invoke},
- * they will throw {@code UnsupportedOperationException}.
- * <p>
- * In order to obtain an invoker method for a particular type descriptor,
- * use {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker},
- * or {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}.
- * The {@link java.dyn.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
- * API is also able to return a method handle
- * to call {@code invokeExact} or {@code invokeGeneric},
- * for any specified type descriptor .
- *
- * <h3>Interoperation between method handles and Java generics</h3>
- * 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
- * will constructed from the erasure of the source-level type.
- * When a method handle is invoked, the types of its arguments
- * or the return value cast type may be generic types or type instances.
- * If this occurs, the compiler will replace those
- * types by their erasures when when it constructs the type descriptor
- * for the {@code invokevirtual} instruction.
- * <p>
- * Method handles do not represent
- * their function-like types in terms of Java parameterized (generic) types,
- * because there are three mismatches between function-like types and parameterized
- * Java types.
- * <ul>
- * <li>Method types range over all possible arities,
- * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
- * Generics are not variadic, and so cannot represent this.</li>
- * <li>Method types can specify arguments of primitive types,
- * which Java generic types cannot range over.</li>
- * <li>Higher order functions over method handles (combinators) are
- * often generic across a wide range of function types, including
- * those of multiple arities.  It is impossible to represent such
- * genericity with a Java type parameter.</li>
- * </ul>
- *
- * @see MethodType
- * @see MethodHandles
- * @author John Rose, JSR 292 EG
- */
-public abstract class MethodHandle
-        // Note: This is an implementation inheritance hack, and will be removed
-        // with a JVM change which moves the required hidden state onto this class.
-        extends MethodHandleImpl
-{
-    private static Access IMPL_TOKEN = Access.getToken();
-    static { MethodHandleImpl.initStatics(); }
-
-    // interface MethodHandle<R throws X extends Exception,A...>
-    // { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }
-
-    /**
-     * Internal marker interface which distinguishes (to the Java compiler)
-     * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
-     */
-    @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
-    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
-    @interface PolymorphicSignature { }
-
-    private MethodType type;
-
-    /**
-     * Report the type of this method handle.
-     * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
-     * @return the method handle type
-     */
-    public MethodType type() {
-        return type;
-    }
-
-    /**
-     * <em>CONSTRUCTOR WILL BE REMOVED FOR PFD:</em>
-     * Temporary constructor in early versions of the Reference Implementation.
-     * Method handle inheritance (if any) will be contained completely within
-     * the {@code java.dyn} package.
-     */
-    // The constructor for MethodHandle may only be called by privileged code.
-    // Subclasses may be in other packages, but must possess
-    // a token which they obtained from MH with a security check.
-    // @param token non-null object which proves access permission
-    // @param type type (permanently assigned) of the new method handle
-    protected MethodHandle(Access token, MethodType type) {
-        super(token);
-        Access.check(token);
-        this.type = type;
-    }
-
-    private void initType(MethodType type) {
-        type.getClass();  // elicit NPE
-        if (this.type != null)  throw new InternalError();
-        this.type = type;
-    }
-
-    static {
-        // This hack allows the implementation package special access to
-        // the internals of MethodHandle.  In particular, the MTImpl has all sorts
-        // of cached information useful to the implementation code.
-        MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
-            public void initType(MethodHandle mh, MethodType type) { mh.initType(type); }
-        });
-    }
-
-    /**
-     * Invoke the method handle, allowing any caller type descriptor, but requiring an exact type match.
-     * The type descriptor at the call site of {@code invokeExact} must
-     * exactly match this method handle's {@link #type type}.
-     * No conversions are allowed on arguments or return values.
-     * <p>
-     * When this method is observed via the Core Reflection API,
-     * it will appear as a single native method, taking an object array and returning an object.
-     * If this native method is invoked directly via
-     * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
-     * or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect},
-     * it will throw an {@code UnsupportedOperationException}.
-     * @throws WrongMethodTypeException if the target's type is not identical with the caller's type descriptor
-     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
-     */
-    public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
-
-    /**
-     * Invoke the method handle, allowing any caller type descriptor,
-     * and optionally performing conversions on arguments and return values.
-     * <p>
-     * If the call site type descriptor exactly matches this method handle's {@link #type type},
-     * the call proceeds as if by {@link #invokeExact invokeExact}.
-     * <p>
-     * Otherwise, the call proceeds as if this method handle were first
-     * adjusted by calling {@link #asType asType} to adjust this method handle
-     * to the required type, and then the call proceeds as if by
-     * {@link #invokeExact invokeExact} on the adjusted method handle.
-     * <p>
-     * There is no guarantee that the {@code asType} call is actually made.
-     * If the JVM can predict the results of making the call, it may perform
-     * adaptations directly on the caller's arguments,
-     * and call the target method handle according to its own exact type.
-     * <p>
-     * The type descriptor at the call site of {@code invokeGeneric} must
-     * be a valid argument to the receivers {@code asType} method.
-     * In particular, the caller must specify the same argument arity
-     * as the callee's type,
-     * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
-     * <p>
-     * When this method is observed via the Core Reflection API,
-     * it will appear as a single native method, taking an object array and returning an object.
-     * If this native method is invoked directly via
-     * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
-     * or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect},
-     * it will throw an {@code UnsupportedOperationException}.
-     * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's 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
-     */
-    public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable;
-
-    /**
-     * Perform a varargs invocation, passing the arguments in the given array
-     * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
-     * which mentions only the type {@code Object}, and whose arity is the length
-     * of the argument array.
-     * <p>
-     * Specifically, execution proceeds as if by the following steps,
-     * although the methods are not guaranteed to be called if the JVM
-     * can predict their effects.
-     * <ul>
-     * <li>Determine the length of the argument array as {@code N}.
-     *     For a null reference, {@code N=0}. </li>
-     * <li>Determine the generic type {@code TN} of {@code N} arguments as
-     *     as {@code TN=MethodType.genericMethodType(N)}.</li>
-     * <li>Force the original target method handle {@code MH0} to the
-     *     required type, as {@code MH1 = MH0.asType(TN)}. </li>
-     * <li>Spread the array into {@code N} separate arguments {@code A0, ...}. </li>
-     * <li>Invoke the type-adjusted method handle on the unpacked arguments:
-     *     MH1.invokeExact(A0, ...). </li>
-     * <li>Take the return value as an {@code Object} reference. </li>
-     * </ul>
-     * <p>
-     * Because of the action of the {@code asType} step, the following argument
-     * conversions are applied as necessary:
-     * <ul>
-     * <li>reference casting
-     * <li>unboxing
-     * <li>widening primitive conversions
-     * </ul>
-     * <p>
-     * The result returned by the call is boxed if it is a primitive,
-     * or forced to null if the return type is void.
-     * <p>
-     * This call is equivalent to the following code:
-     * <p><blockquote><pre>
-     * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
-     * Object result = invoker.invokeExact(this, arguments);
-     * </pre></blockquote>
-     * <p>
-     * Unlike the signature polymorphic methods {@code invokeExact} and {@code invokeGeneric},
-     * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
-     * It can therefore be used as a bridge between native or reflective code and method handles.
-     *
-     * @param arguments the arguments to pass to the target
-     * @return the result returned by the target
-     * @throws ClassCastException if an argument cannot be converted by reference casting
-     * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
-     * @throws Throwable anything thrown by the target method invocation
-     * @see MethodHandles#spreadInvoker
-     */
-    public Object invokeWithArguments(Object... arguments) throws Throwable {
-        int argc = arguments == null ? 0 : arguments.length;
-        MethodType type = type();
-        if (type.parameterCount() != argc) {
-            // simulate invokeGeneric
-            return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
-        }
-        if (argc <= 10) {
-            MethodHandle invoker = invokers(type).genericInvoker();
-            switch (argc) {
-                case 0:  return invoker.invokeExact(this);
-                case 1:  return invoker.invokeExact(this,
-                                    arguments[0]);
-                case 2:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1]);
-                case 3:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2]);
-                case 4:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3]);
-                case 5:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3], arguments[4]);
-                case 6:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3], arguments[4], arguments[5]);
-                case 7:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3], arguments[4], arguments[5],
-                                    arguments[6]);
-                case 8:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3], arguments[4], arguments[5],
-                                    arguments[6], arguments[7]);
-                case 9:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3], arguments[4], arguments[5],
-                                    arguments[6], arguments[7], arguments[8]);
-                case 10:  return invoker.invokeExact(this,
-                                    arguments[0], arguments[1], arguments[2],
-                                    arguments[3], arguments[4], arguments[5],
-                                    arguments[6], arguments[7], arguments[8],
-                                    arguments[9]);
-            }
-        }
-
-        // more than ten arguments get boxed in a varargs list:
-        MethodHandle invoker = invokers(type).spreadInvoker(0);
-        return invoker.invokeExact(this, arguments);
-    }
-    /** Equivalent to {@code invokeWithArguments(arguments.toArray())}. */
-    public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
-        return invokeWithArguments(arguments.toArray());
-    }
-
-    /**
-     * Produce an adapter method handle which adapts the type of the
-     * current method handle to a new type
-     * The resulting method handle is guaranteed to report a type
-     * which is equal to the desired new type.
-     * <p>
-     * If the original type and new type are equal, returns {@code this}.
-     * <p>
-     * This method provides the crucial behavioral difference between
-     * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.  The two methods
-     * perform the same steps when the caller's type descriptor is identical
-     * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric}
-     * also calls {@code asType} (or some internal equivalent) in order
-     * to match up the caller's and callee's types.
-     * <p>
-     * This method is equivalent to {@link MethodHandles#convertArguments convertArguments},
-     * except for variable arity method handles produced by {@link #asVarargsCollector asVarargsCollector}.
-     *
-     * @param newType the expected type of the new method handle
-     * @return a method handle which delegates to {@code this} after performing
-     *           any necessary argument conversions, and arranges for any
-     *           necessary return value conversions
-     * @throws WrongMethodTypeException if the conversion cannot be made
-     * @see MethodHandles#convertArguments
-     */
-    public MethodHandle asType(MethodType newType) {
-        return MethodHandles.convertArguments(this, newType);
-    }
-
-    /**
-     * Make an adapter which accepts a trailing array argument
-     * and spreads its elements as positional arguments.
-     * The new method handle adapts, as its <i>target</i>,
-     * the current method handle.  The type of the adapter will be
-     * the same as the type of the target, except that the final
-     * {@code arrayLength} parameters of the target's type are replaced
-     * by a single array parameter of type {@code arrayType}.
-     * <p>
-     * If the array element type differs from any of the corresponding
-     * argument types on the original target,
-     * the original target is adapted to take the array elements directly,
-     * as if by a call to {@link #asType asType}.
-     * <p>
-     * When called, the adapter replaces a trailing array argument
-     * by the array's elements, each as its own argument to the target.
-     * (The order of the arguments is preserved.)
-     * They are converted pairwise by casting and/or unboxing
-     * to the types of the trailing parameters of the target.
-     * Finally the target is called.
-     * What the target eventually returns is returned unchanged by the adapter.
-     * <p>
-     * Before calling the target, the adapter verifies that the array
-     * contains exactly enough elements to provide a correct argument count
-     * to the target method handle.
-     * (The array may also be null when zero elements are required.)
-     * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
-     * @param arrayLength the number of arguments to spread from an incoming array argument
-     * @return a new method handle which spreads its final array argument,
-     *         before calling the original method handle
-     * @throws IllegalArgumentException if {@code arrayType} is not an array type
-     * @throws IllegalArgumentException if target does not have at least
-     *         {@code arrayLength} parameter types
-     * @throws WrongMethodTypeException if the implied {@code asType} call fails
-     * @see #asCollector
-     */
-    public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
-        Class<?> arrayElement = arrayType.getComponentType();
-        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
-        MethodType oldType = type();
-        int nargs = oldType.parameterCount();
-        if (nargs < arrayLength)  throw newIllegalArgumentException("bad spread array length");
-        int keepPosArgs = nargs - arrayLength;
-        MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
-        newType = newType.insertParameterTypes(keepPosArgs, arrayType);
-        return MethodHandles.spreadArguments(this, newType);
-    }
-
-    /**
-     * Make an adapter which accepts a given number of trailing
-     * positional arguments and collects them into an array argument.
-     * The new method handle adapts, as its <i>target</i>,
-     * the current method handle.  The type of the adapter will be
-     * the same as the type of the target, except that a single trailing
-     * parameter (usually of type {@code arrayType}) is replaced by
-     * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
-     * <p>
-     * If the array type differs from the final argument type on the original target,
-     * the original target is adapted to take the array type directly,
-     * as if by a call to {@link #asType asType}.
-     * <p>
-     * When called, the adapter replaces its trailing {@code arrayLength}
-     * arguments by a single new array of type {@code arrayType}, whose elements
-     * comprise (in order) the replaced arguments.
-     * Finally the target is called.
-     * What the target eventually returns is returned unchanged by the adapter.
-     * <p>
-     * (The array may also be a shared constant when {@code arrayLength} is zero.)
-     * <p>
-     * (<em>Note:</em> The {@code arrayType} is often identical to the last
-     * parameter type of the original target.
-     * It is an explicit argument for symmetry with {@code asSpreader}, and also
-     * to allow the target to use a simple {@code Object} as its last parameter type.)
-     * <p>
-     * In order to create a collecting adapter which is not restricted to a particular
-     * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
-     * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
-     * @param arrayLength the number of arguments to collect into a new array argument
-     * @return a new method handle which collects some trailing argument
-     *         into an array, before calling the original method handle
-     * @throws IllegalArgumentException if {@code arrayType} is not an array type
-     *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
-     *         or {@code arrayLength} is not a legal array size
-     * @throws WrongMethodTypeException if the implied {@code asType} call fails
-     * @see #asSpreader
-     * @see #asVarargsCollector
-     */
-    public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
-        Class<?> arrayElement = arrayType.getComponentType();
-        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
-        MethodType oldType = type();
-        int nargs = oldType.parameterCount();
-        if (nargs == 0)  throw newIllegalArgumentException("no trailing argument");
-        MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
-        newType = newType.insertParameterTypes(nargs-1,
-                    java.util.Collections.<Class<?>>nCopies(arrayLength, arrayElement));
-        return MethodHandles.collectArguments(this, newType);
-    }
-
-    /**
-     * Make a <em>variable arity</em> adapter which is able to accept
-     * any number of trailing positional arguments and collect them
-     * into an array argument.
-     * <p>
-     * The type and behavior of the adapter will be the same as
-     * the type and behavior of the target, except that certain
-     * {@code invokeGeneric} and {@code asType} requests can lead to
-     * trailing positional arguments being collected into target's
-     * trailing parameter.
-     * Also, the last parameter type of the adapter will be
-     * {@code arrayType}, even if the target has a different
-     * last parameter type.
-     * <p>
-     * When called with {@link #invokeExact invokeExact}, the adapter invokes
-     * the target with no argument changes.
-     * (<em>Note:</em> This behavior is different from a
-     * {@linkplain #asCollector fixed arity collector},
-     * since it accepts a whole array of indeterminate length,
-     * rather than a fixed number of arguments.)
-     * <p>
-     * When called with {@link #invokeGeneric invokeGeneric}, if the caller
-     * type is the same as the adapter, the adapter invokes the target as with
-     * {@code invokeExact}.
-     * (This is the normal behavior for {@code invokeGeneric} when types match.)
-     * <p>
-     * Otherwise, if the caller and adapter arity are the same, and the
-     * trailing parameter type of the caller is a reference type identical to
-     * or assignable to the trailing parameter type of the adapter,
-     * the arguments and return values are converted pairwise,
-     * as if by {@link MethodHandles#convertArguments convertArguments}.
-     * (This is also normal behavior for {@code invokeGeneric} in such a case.)
-     * <p>
-     * Otherwise, the arities differ, or the adapter's trailing parameter
-     * type is not assignable from the corresponding caller type.
-     * In this case, the adapter replaces all trailing arguments from
-     * the original trailing argument position onward, by
-     * a new array of type {@code arrayType}, whose elements
-     * comprise (in order) the replaced arguments.
-     * <p>
-     * The caller type must provides as least enough arguments,
-     * and of the correct type, to satisfy the target's requirement for
-     * positional arguments before the trailing array argument.
-     * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
-     * where {@code N} is the arity of the target.
-     * Also, there must exist conversions from the incoming arguments
-     * to the target's arguments.
-     * As with other uses of {@code invokeGeneric}, if these basic
-     * requirements are not fulfilled, a {@code WrongMethodTypeException}
-     * may be thrown.
-     * <p>
-     * In all cases, what the target eventually returns is returned unchanged by the adapter.
-     * <p>
-     * In the final case, it is exactly as if the target method handle were
-     * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
-     * to the arity required by the caller type.
-     * (As with {@code asCollector}, if the array length is zero,
-     * a shared constant may be used instead of a new array.
-     * If the implied call to {@code asCollector} would throw
-     * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
-     * the call to the variable arity adapter must throw
-     * {@code WrongMethodTypeException}.)
-     * <p>
-     * The behavior of {@link #asType asType} is also specialized for
-     * variable arity adapters, to maintain the invariant that
-     * {@code invokeGeneric} is always equivalent to an {@code asType}
-     * call to adjust the target type, followed by {@code invokeExact}.
-     * Therefore, a variable arity adapter responds
-     * to an {@code asType} request by building a fixed arity collector,
-     * if and only if the adapter and requested type differ either
-     * in arity or trailing argument type.
-     * The resulting fixed arity collector has its type further adjusted
-     * (if necessary) to the requested type by pairwise conversion,
-     * as if by another application of {@code asType}.
-     * <p>
-     * When a method handle is obtained by executing an {@code ldc} instruction
-     * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
-     * as a variable arity method (with the modifier bit {@code 0x0080}),
-     * the method handle will accept multiple arities, as if the method handle
-     * constant were created by means of a call to {@code asVarargsCollector}.
-     * <p>
-     * In order to create a collecting adapter which collects a predetermined
-     * number of arguments, and whose type reflects this predetermined number,
-     * use {@link #asCollector asCollector} instead.
-     * <p>
-     * No method handle transformations produce new method handles with
-     * variable arity, unless they are documented as doing so.
-     * Therefore, besides {@code asVarargsCollector},
-     * all methods in {@code MethodHandle} and {@code MethodHandles}
-     * will return a method handle with fixed arity,
-     * except in the cases where they are specified to return their original
-     * operand (e.g., {@code asType} of the method handle's own type).
-     * <p>
-     * Calling {@code asVarargsCollector} on a method handle which is already
-     * of variable arity will produce a method handle with the same type and behavior.
-     * It may (or may not) return the original variable arity method handle.
-     * <p>
-     * Here is an example, of a list-making variable arity method handle:
-     * <blockquote><pre>
-MethodHandle asList = publicLookup()
-  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
-  .asVarargsCollector(Object[].class);
-assertEquals("[]", asList.invokeGeneric().toString());
-assertEquals("[1]", asList.invokeGeneric(1).toString());
-assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString());
-Object[] argv = { "three", "thee", "tee" };
-assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString());
-List ls = (List) asList.invokeGeneric((Object)argv);
-assertEquals(1, ls.size());
-assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
-     * </pre></blockquote>
-     * <p style="font-size:smaller;">
-     * <em>Discussion:</em>
-     * These rules are designed as a dynamically-typed variation
-     * of the Java rules for variable arity methods.
-     * In both cases, callers to a variable arity method or method handle
-     * can either pass zero or more positional arguments, or else pass
-     * pre-collected arrays of any length.  Users should be aware of the
-     * special role of the final argument, and of the effect of a
-     * type match on that final argument, which determines whether
-     * or not a single trailing argument is interpreted as a whole
-     * array or a single element of an array to be collected.
-     * Note that the dynamic type of the trailing argument has no
-     * effect on this decision, only a comparison between the static
-     * type descriptor of the call site and the type of the method handle.)
-     * <p style="font-size:smaller;">
-     * As a result of the previously stated rules, the variable arity behavior
-     * of a method handle may be suppressed, by binding it to the exact invoker
-     * of its own type, as follows:
-     * <blockquote><pre>
-MethodHandle vamh = publicLookup()
-  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
-  .asVarargsCollector(Object[].class);
-MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh);
-assert(vamh.type().equals(mh.type()));
-assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString());
-boolean failed = false;
-try { mh.invokeGeneric(1,2,3); }
-catch (WrongMethodTypeException ex) { failed = true; }
-assert(failed);
-     * </pre></blockquote>
-     * This transformation has no behavioral effect if the method handle is
-     * not of variable arity.
-     *
-     * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
-     * @return a new method handle which can collect any number of trailing arguments
-     *         into an array, before calling the original method handle
-     * @throws IllegalArgumentException if {@code arrayType} is not an array type
-     *         or {@code arrayType} is not assignable to this method handle's trailing parameter type
-     * @see #asCollector
-     * @see #isVarargsCollector
-     */
-    public MethodHandle asVarargsCollector(Class<?> arrayType) {
-        Class<?> arrayElement = arrayType.getComponentType();
-        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
-        return MethodHandles.asVarargsCollector(this, arrayType);
-    }
-
-    /**
-     * Determine if this method handle
-     * supports {@linkplain #asVarargsCollector variable arity} calls.
-     * Such method handles arise from the following sources:
-     * <ul>
-     * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
-     * <li>a call to a {@linkplain java.dyn.MethodHandles.Lookup lookup method}
-     *     which resolves to a variable arity Java method or constructor
-     * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
-     *     which resolves to a variable arity Java method or constructor
-     * </ul>
-     * @return true if this method handle accepts more than one arity of {@code invokeGeneric} calls
-     * @see #asVarargsCollector
-     */
-    public boolean isVarargsCollector() {
-        return false;
-    }
-
-    /**
-     * Bind a value {@code x} to the first argument of a method handle, without invoking it.
-     * The new method handle adapts, as its <i>target</i>,
-     * to the current method handle.
-     * The type of the bound handle will be
-     * the same as the type of the target, except that a single leading
-     * reference parameter will be omitted.
-     * <p>
-     * When called, the bound handle inserts the given value {@code x}
-     * as a new leading argument to the target.  The other arguments are
-     * also passed unchanged.
-     * What the target eventually returns is returned unchanged by the bound handle.
-     * <p>
-     * The reference {@code x} must be convertible to the first parameter
-     * type of the target.
-     * @param x  the value to bind to the first argument of the target
-     * @return a new method handle which collects some trailing argument
-     *         into an array, before calling the original method handle
-     * @throws IllegalArgumentException if the target does not have a
-     *         leading parameter type that is a reference type
-     * @throws ClassCastException if {@code x} cannot be converted
-     *         to the leading parameter type of the target
-     * @see MethodHandles#insertArguments
-     */
-    public MethodHandle bindTo(Object x) {
-        return MethodHandles.insertArguments(this, 0, x);
-    }
-
-    /**
-     * Returns a string representation of the method handle,
-     * starting with the string {@code "MethodHandle"} and
-     * ending with the string representation of the method handle's type.
-     * In other words, this method returns a string equal to the value of:
-     * <blockquote><pre>
-     * "MethodHandle" + type().toString()
-     * </pre></blockquote>
-     * <p>
-     * Note:  Future releases of this API may add further information
-     * to the string representation.
-     * Therefore, the present syntax should not be parsed by applications.
-     *
-     * @return a string representation of the method handle
-     */
-    @Override
-    public String toString() {
-        return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/MethodHandles.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2339 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.dyn;
-
-import java.lang.reflect.*;
-import sun.dyn.Access;
-import sun.dyn.MemberName;
-import sun.dyn.MethodHandleImpl;
-import sun.dyn.WrapperInstance;
-import sun.dyn.util.ValueConversions;
-import sun.dyn.util.VerifyAccess;
-import sun.dyn.util.Wrapper;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-import sun.dyn.Invokers;
-import sun.dyn.MethodTypeImpl;
-import sun.reflect.Reflection;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-import static sun.dyn.MemberName.newNoAccessException;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * method handles. They fall into several categories:
- * <ul>
- * <li>Lookup methods which help create method handles for methods and fields.
- * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
- * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
- * <li>Wrapper methods which can convert between method handles and other function-like "SAM types".
- * </ul>
- * <p>
- * @author John Rose, JSR 292 EG
- */
-public class MethodHandles {
-
-    private MethodHandles() { }  // do not instantiate
-
-    private static final Access IMPL_TOKEN = Access.getToken();
-    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
-    static { MethodHandleImpl.initStatics(); }
-    // See IMPL_LOOKUP below.
-
-    //// Method handle creation from ordinary methods.
-
-    /**
-     * Return a {@link Lookup lookup object} on the caller,
-     * which has the capability to access any method handle that the caller has access to,
-     * 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.
-     */
-    public static Lookup lookup() {
-        return new Lookup();
-    }
-
-    /**
-     * Return a {@link Lookup lookup object} which is trusted minimally.
-     * It can only be used to create method handles to
-     * publicly accessible fields and methods.
-     * <p>
-     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
-     * of this lookup object will be {@link java.lang.Object}.
-     * <p>
-     * The lookup class can be changed to any other class {@code C} using an expression of the form
-     * {@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.
-     */
-    public static Lookup publicLookup() {
-        return Lookup.PUBLIC_LOOKUP;
-    }
-
-    /**
-     * A <em>lookup object</em> is a factory for creating method handles,
-     * when the creation requires access checking.
-     * Method handles do not perform
-     * access checks when they are called, but rather when they are created.
-     * Therefore, method handle access
-     * restrictions must be enforced when a method handle is created.
-     * The caller class against which those restrictions are enforced
-     * is known as the {@linkplain #lookupClass lookup class}.
-     * <p>
-     * A lookup class which needs to create method handles will call
-     * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
-     * When the {@code Lookup} factory object is created, the identity of the lookup class is
-     * determined, and securely stored in the {@code Lookup} object.
-     * The lookup class (or its delegates) may then use factory methods
-     * 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>
-     * 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>
-     * <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.dyn.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
-     *     <td>FT f;</td><td>(T) this.f;</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
-     *     <td>static<br>FT f;</td><td>(T) C.f;</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
-     *     <td>FT f;</td><td>this.f = x;</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
-     *     <td>static<br>FT f;</td><td>C.f = arg;</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
-     *     <td>T m(A*);</td><td>(T) this.m(arg*);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
-     *     <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
-     *     <td>T m(A*);</td><td>(T) super.m(arg*);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
-     *     <td>C(A*);</td><td>(T) new C(arg*);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
-     *     <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
-     *     <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
-     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
-     *     <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
-     * </tr>
-     * <tr>
-     *     <td>{@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
-     *     <td>(static)?<br>T m(A*);</td><td>(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}
-     * and the sequence of argument types {@code A*}.
-     * 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.
-     * The name {@code arg} stands for all the other method handle arguments.
-     * In the code examples for the Core Reflection API, the name {@code thisOrNull}
-     * stands for a null reference if the accessed method or field is static,
-     * and {@code this} otherwise.
-     * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
-     * for reflective objects corresponding to the given members.
-     * <p>
-     * The equivalence between looked-up method handles and underlying
-     * class members can break down in a few ways:
-     * <ul>
-     * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
-     * the lookup can still succeed, even when there is no equivalent
-     * Java expression or bytecoded constant.
-     * <li>Likewise, if {@code T} or {@code MT}
-     * is not symbolically accessible from the lookup class's loader,
-     * the lookup can still succeed.
-     * For example, lookups for {@code MethodHandle.invokeExact} and
-     * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
-     * <li>If there is a security manager installed, it can forbid the lookup
-     * on various grounds (<a href="#secmgr">see below</a>).
-     * By contrast, the {@code ldc} instruction is not subject to
-     * security manager checks.
-     * </ul>
-     *
-     * <h3><a name="access"></a>Access checking</h3>
-     * 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
-     * {@link java.lang.reflect.Method#invoke Method.invoke}
-     * performs access checking against every caller, on every call.
-     * <p>
-     * All access checks start from a {@code Lookup} object, which
-     * compares its recorded lookup class against all requests to
-     * create method handles.
-     * A single {@code Lookup} object can be used to create any number
-     * of access-checked method handles, all checked against a single
-     * lookup class.
-     * <p>
-     * A {@code Lookup} object can be shared with other trusted code,
-     * such as a metaobject protocol.
-     * A shared {@code Lookup} object delegates the capability
-     * to create method handles on private members of the lookup class.
-     * Even if privileged code uses the {@code Lookup} object,
-     * the access checking is confined to the privileges of the
-     * original lookup class.
-     * <p>
-     * A lookup can fail, because
-     * the containing class is not accessible to the lookup class, or
-     * because the desired class member is missing, or because the
-     * desired class member is not accessible to the lookup class.
-     * In any of these cases, a {@code ReflectiveOperationException} will be
-     * thrown from the attempted lookup.  The exact class will be one of
-     * the following:
-     * <ul>
-     * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
-     * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
-     * <li>IllegalAccessException &mdash; if the member exists but an access check fails
-     * </ul>
-     * <p>
-     * In general, the conditions under which a method handle may be
-     * looked up for a method {@code M} are exactly equivalent to the conditions
-     * under which the lookup class could have compiled and resolved a call to {@code M}.
-     * And the effect of invoking the method handle resulting from the lookup
-     * is exactly equivalent to executing the compiled and resolved call to {@code M}.
-     * The same point is true of fields and constructors.
-     * <p>
-     * In some cases, access between nested classes is obtained by the Java compiler by creating
-     * an wrapper method to access a private method of another class
-     * in the same top-level declaration.
-     * For example, a nested class {@code C.D}
-     * can access private members within other related classes such as
-     * {@code C}, {@code C.D.E}, or {@code C.B},
-     * but the Java compiler may need to generate wrapper methods in
-     * those related classes.  In such cases, a {@code Lookup} object on
-     * {@code C.E} would be unable to those private members.
-     * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
-     * which can transform a lookup on {@code C.E} into one on any of those other
-     * classes, without special elevation of privilege.
-     * <p>
-     * Although bytecode instructions can only refer to classes in
-     * a related class loader, this API can search for methods in any
-     * class, as long as a reference to its {@code Class} object is
-     * available.  Such cross-loader references are also possible with the
-     * Core Reflection API, and are impossible to bytecode instructions
-     * such as {@code invokestatic} or {@code getfield}.
-     * There is a {@linkplain java.lang.SecurityManager security manager API}
-     * to allow applications to check such cross-loader references.
-     * These checks apply to both the {@code MethodHandles.Lookup} API
-     * and the Core Reflection API
-     * (as found on {@link java.lang.Class Class}).
-     * <p>
-     * Access checks only apply to named and reflected methods,
-     * constructors, and fields.
-     * Other method handle creation methods, such as
-     * {@link #convertArguments MethodHandles.convertArguments},
-     * do not require any access checks, and are done
-     * with static methods of {@link MethodHandles},
-     * independently of any {@code Lookup} object.
-     *
-     * <h3>Security manager interactions</h3>
-     * <a name="secmgr"></a>
-     * If a security manager is present, member lookups are subject to
-     * additional checks.
-     * From one to four calls are made to the security manager.
-     * Any of these calls can refuse access by throwing a
-     * {@link java.lang.SecurityException SecurityException}.
-     * Define {@code smgr} as the security manager,
-     * {@code refc} as the containing class in which the member
-     * is being sought, and {@code defc} as the class in which the
-     * member is actually defined.
-     * The calls are made according to the following rules:
-     * <ul>
-     * <li>In all cases, {@link SecurityManager#checkMemberAccess
-     *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
-     * <li>If the class loader of the lookup class is not
-     *     the same as or an ancestor of the class loader of {@code refc},
-     *     then {@link SecurityManager#checkPackageAccess
-     *     smgr.checkPackageAccess(refcPkg)} is called,
-     *     where {@code refcPkg} is the package of {@code refc}.
-     * <li>If the retrieved member is not public,
-     *     {@link SecurityManager#checkMemberAccess
-     *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
-     *     (Note that {@code defc} might be the same as {@code refc}.)
-     * <li>If the retrieved member is not public,
-     *     and if {@code defc} and {@code refc} are in different class loaders,
-     *     and if the class loader of the lookup class is not
-     *     the same as or an ancestor of the class loader of {@code defc},
-     *     then {@link SecurityManager#checkPackageAccess
-     *     smgr.checkPackageAccess(defcPkg)} is called,
-     *     where {@code defcPkg} is the package of {@code defc}.
-     * </ul>
-     * In all cases, the requesting class presented to the security
-     * manager will be the lookup class from the current {@code Lookup} object.
-     */
-    public static final
-    class Lookup {
-        /** The class on behalf of whom the lookup is being performed. */
-        private final Class<?> lookupClass;
-
-        /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
-        private final int allowedModes;
-
-        /** A single-bit mask representing {@code public} access,
-         *  which may contribute to the result of {@link #lookupModes lookupModes}.
-         *  The value, {@code 0x01}, happens to be the same as the value of the
-         *  {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
-         */
-        public static final int PUBLIC = Modifier.PUBLIC;
-
-        /** A single-bit mask representing {@code private} access,
-         *  which may contribute to the result of {@link #lookupModes lookupModes}.
-         *  The value, {@code 0x02}, happens to be the same as the value of the
-         *  {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
-         */
-        public static final int PRIVATE = Modifier.PRIVATE;
-
-        /** A single-bit mask representing {@code protected} access,
-         *  which may contribute to the result of {@link #lookupModes lookupModes}.
-         *  The value, {@code 0x04}, happens to be the same as the value of the
-         *  {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
-         */
-        public static final int PROTECTED = Modifier.PROTECTED;
-
-        /** A single-bit mask representing {@code package} access (default access),
-         *  which may contribute to the result of {@link #lookupModes lookupModes}.
-         *  The value is {@code 0x08}, which does not correspond meaningfully to
-         *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
-         */
-        public static final int PACKAGE = Modifier.STATIC;
-
-        private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
-        private static final int TRUSTED   = -1;
-
-        private static int fixmods(int mods) {
-            mods &= (ALL_MODES - PACKAGE);
-            return (mods != 0) ? mods : PACKAGE;
-        }
-
-        /** Tells which class is performing the lookup.  It is this class against
-         *  which checks are performed for visibility and access permissions.
-         *  <p>
-         *  The class implies a maximum level of access permission,
-         *  but the permissions may be additionally limited by the bitmask
-         *  {@link #lookupModes lookupModes}, which controls whether non-public members
-         *  can be accessed.
-         */
-        public Class<?> lookupClass() {
-            return lookupClass;
-        }
-
-        // This is just for calling out to MethodHandleImpl.
-        private Class<?> lookupClassOrNull() {
-            return (allowedModes == TRUSTED) ? null : lookupClass;
-        }
-
-        /** Tells which access-protection classes of members this lookup object can produce.
-         *  The result is a bit-mask of the bits
-         *  {@linkplain #PUBLIC PUBLIC (0x01)},
-         *  {@linkplain #PRIVATE PRIVATE (0x02)},
-         *  {@linkplain #PROTECTED PROTECTED (0x04)},
-         *  and {@linkplain #PACKAGE PACKAGE (0x08)}.
-         *  <p>
-         *  A freshly-created lookup object
-         *  on the {@linkplain java.dyn.MethodHandles#lookup() caller's class}
-         *  has all possible bits set, since the caller class can access all its own members.
-         *  A lookup object on a new lookup class
-         *  {@linkplain java.dyn.MethodHandles.Lookup#in created from a previous lookup object}
-         *  may have some mode bits set to zero.
-         *  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.
-         */
-        public int lookupModes() {
-            return allowedModes & ALL_MODES;
-        }
-
-        /** Embody the current class (the lookupClass) as a lookup class
-         * for method handle creation.
-         * Must be called by from a method in this package,
-         * which in turn is called by a method not in this package.
-         * <p>
-         * Also, don't make it private, lest javac interpose
-         * an access$N method.
-         */
-        Lookup() {
-            this(getCallerClassAtEntryPoint(), ALL_MODES);
-            // make sure we haven't accidentally picked up a privileged class:
-            checkUnprivilegedlookupClass(lookupClass);
-        }
-
-        Lookup(Access token, Class<?> lookupClass) {
-            this(lookupClass, ALL_MODES);
-            Access.check(token);
-        }
-
-        private Lookup(Class<?> lookupClass, int allowedModes) {
-            this.lookupClass = lookupClass;
-            this.allowedModes = allowedModes;
-        }
-
-        /**
-         * Creates a lookup on the specified new lookup class.
-         * The resulting object will report the specified
-         * class as its own {@link #lookupClass lookupClass}.
-         * <p>
-         * However, the resulting {@code Lookup} object is guaranteed
-         * to have no more access capabilities than the original.
-         * In particular, access capabilities can be lost as follows:<ul>
-         * <li>If the new lookup class differs from the old one,
-         * protected members will not be accessible by virtue of inheritance.
-         * (Protected members may continue to be accessible because of package sharing.)
-         * <li>If the new lookup class is in a different package
-         * than the old one, protected and default (package) members will not be accessible.
-         * <li>If the new lookup class is not within the same package member
-         * as the old one, private members will not be accessible.
-         * <li>If the new lookup class is not accessible to the old lookup class,
-         * then no members, not even public members, will be accessible.
-         * (In all other cases, public members will continue to be accessible.)
-         * </ul>
-         *
-         * @param requestedLookupClass the desired lookup class for the new lookup object
-         * @return a lookup object which reports the desired lookup class
-         * @throws NullPointerException if the argument is null
-         */
-        public Lookup in(Class<?> requestedLookupClass) {
-            requestedLookupClass.getClass();  // null check
-            if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
-                return new Lookup(requestedLookupClass, ALL_MODES);
-            if (requestedLookupClass == this.lookupClass)
-                return this;  // keep same capabilities
-            int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
-            if ((newModes & PACKAGE) != 0
-                && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
-                newModes &= ~(PACKAGE|PRIVATE);
-            }
-            // Allow nestmate lookups to be created without special privilege:
-            if ((newModes & PRIVATE) != 0
-                && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
-                newModes &= ~PRIVATE;
-            }
-            if (newModes == PUBLIC
-                && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass)) {
-                // The requested class it not accessible from the lookup class.
-                // No permissions.
-                newModes = 0;
-            }
-            checkUnprivilegedlookupClass(requestedLookupClass);
-            return new Lookup(requestedLookupClass, newModes);
-        }
-
-        // Make sure outer class is initialized first.
-        static { IMPL_TOKEN.getClass(); }
-
-        /** Version of lookup which is trusted minimally.
-         *  It can only be used to create method handles to
-         *  publicly accessible members.
-         */
-        static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
-
-        /** Package-private version of lookup which is trusted. */
-        static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
-        static { MethodHandleImpl.initLookup(IMPL_TOKEN, IMPL_LOOKUP); }
-
-        private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
-            String name = lookupClass.getName();
-            if (name.startsWith("java.dyn.") || name.startsWith("sun.dyn."))
-                throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
-        }
-
-        /**
-         * Displays the name of the class from which lookups are to be made.
-         * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
-         * If there are restrictions on the access permitted to this lookup,
-         * this is indicated by adding a suffix to the class name, consisting
-         * of a slash and a keyword.  The keyword represents the strongest
-         * allowed access, and is chosen as follows:
-         * <ul>
-         * <li>If no access is allowed, the suffix is "/noaccess".
-         * <li>If only public access is allowed, the suffix is "/public".
-         * <li>If only public and package access are allowed, the suffix is "/package".
-         * <li>If only public, package, and private access are allowed, the suffix is "/private".
-         * </ul>
-         * If none of the above cases apply, it is the case that full
-         * access (public, package, private, and protected) is allowed.
-         * In this case, no suffix is added.
-         * This is true only of an object obtained originally from
-         * {@link java.dyn.MethodHandles#lookup MethodHandles.lookup}.
-         * Objects created by {@link java.dyn.MethodHandles.Lookup#in Lookup.in}
-         * always have restricted access, and will display a suffix.
-         * <p>
-         * (It may seem strange that protected access should be
-         * stronger than private access.  Viewed independently from
-         * package access, protected access is the first to be lost,
-         * because it requires a direct subclass relationship between
-         * caller and callee.)
-         * @see #in
-         */
-        @Override
-        public String toString() {
-            String cname = lookupClass.getName();
-            switch (allowedModes) {
-            case 0:  // no privileges
-                return cname + "/noaccess";
-            case PUBLIC:
-                return cname + "/public";
-            case PUBLIC|PACKAGE:
-                return cname + "/package";
-            case ALL_MODES & ~PROTECTED:
-                return cname + "/private";
-            case ALL_MODES:
-                return cname;
-            case TRUSTED:
-                return "/trusted";  // internal only; not exported
-            default:  // Should not happen, but it's a bitfield...
-                cname = cname + "/" + Integer.toHexString(allowedModes);
-                assert(false) : cname;
-                return cname;
-            }
-        }
-
-        // call this from an entry point method in Lookup with extraFrames=0.
-        private static Class<?> getCallerClassAtEntryPoint() {
-            final int CALLER_DEPTH = 4;
-            // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
-            // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
-            // Note:  This should be the only use of getCallerClass in this file.
-            assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
-            return Reflection.getCallerClass(CALLER_DEPTH);
-        }
-
-        /**
-         * Produces a method handle for a static method.
-         * The type of the method handle will be that of the method.
-         * (Since static methods do not take receivers, there is no
-         * additional receiver argument inserted into the method handle type,
-         * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
-         * The method and all its argument types must be accessible to the lookup class.
-         * If the method's class has not yet been initialized, that is done
-         * immediately, before the method handle is returned.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the method's variable arity modifier bit ({@code 0x0080}) is set.
-         * @param refc the class from which the method is accessed
-         * @param name the name of the method
-         * @param type the type of the method
-         * @return the desired method handle
-         * @throws NoSuchMethodException if the method does not exist
-         * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public
-        MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            MemberName method = resolveOrFail(refc, name, type, true);
-            checkMethod(refc, method, true);
-            return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
-        }
-
-        /**
-         * Produces a method handle for a virtual method.
-         * The type of the method handle will be that of the method,
-         * with the receiver type (usually {@code refc}) prepended.
-         * The method and all its argument types must be accessible to the lookup class.
-         * <p>
-         * When called, the handle will treat the first argument as a receiver
-         * and dispatch on the receiver's type to determine which method
-         * implementation to enter.
-         * (The dispatching action is identical with that performed by an
-         * {@code invokevirtual} or {@code invokeinterface} instruction.)
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the method's variable arity modifier bit ({@code 0x0080}) is set.
-         * <p>
-         * Because of the general equivalence between {@code invokevirtual}
-         * instructions and method handles produced by {@code findVirtual},
-         * if the class is {@code MethodHandle} and the name string is
-         * {@code invokeExact} or {@code invokeGeneric}, the resulting
-         * method handle is equivalent to one produced by
-         * {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
-         * {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}
-         * with the same {@code type} argument.
-         *
-         * @param refc the class or interface from which the method is accessed
-         * @param name the name of the method
-         * @param type the type of the method, with the receiver argument omitted
-         * @return the desired method handle
-         * @throws NoSuchMethodException if the method does not exist
-         * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            MemberName method = resolveOrFail(refc, name, type, false);
-            checkMethod(refc, method, false);
-            MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
-            return restrictProtectedReceiver(method, mh);
-        }
-
-        /**
-         * Produces a method handle which creates an object and initializes it, using
-         * the constructor of the specified type.
-         * The parameter types of the method handle will be those of the constructor,
-         * while the return type will be a reference to the constructor's class.
-         * The constructor and all its argument types must be accessible to the lookup class.
-         * If the constructor's class has not yet been initialized, that is done
-         * immediately, before the method handle is returned.
-         * <p>
-         * Note:  The requested type must have a return type of {@code void}.
-         * This is consistent with the JVM's treatment of constructor type descriptors.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
-         * @param refc the class or interface from which the method is accessed
-         * @param type the type of the method, with the receiver argument omitted, and a void return type
-         * @return the desired method handle
-         * @throws NoSuchMethodException if the constructor does not exist
-         * @throws IllegalAccessException if access checking fails
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            String name = "<init>";
-            MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
-            assert(ctor.isConstructor());
-            checkAccess(refc, ctor);
-            MethodHandle rawMH = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
-            MethodHandle allocMH = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawMH);
-            return fixVarargs(allocMH, rawMH);
-        }
-
-        /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
-        private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
-            boolean va1 = mh.isVarargsCollector();
-            boolean va2 = matchMH.isVarargsCollector();
-            if (va1 == va2) {
-                return mh;
-            } else if (va2) {
-                MethodType type = mh.type();
-                int arity = type.parameterCount();
-                return mh.asVarargsCollector(type.parameterType(arity-1));
-            } else {
-                throw new InternalError("already varargs, but template is not: "+mh);
-            }
-        }
-
-        /**
-         * Produces an early-bound method handle for a virtual method,
-         * as if called from an {@code invokespecial}
-         * instruction from {@code caller}.
-         * The type of the method handle will be that of the method,
-         * with a suitably restricted receiver type (such as {@code caller}) prepended.
-         * The method and all its argument types must be accessible
-         * to the caller.
-         * <p>
-         * When called, the handle will treat the first argument as a receiver,
-         * but will not dispatch on the receiver's type.
-         * (This direct invocation action is identical with that performed by an
-         * {@code invokespecial} instruction.)
-         * <p>
-         * If the explicitly specified caller class is not identical with the
-         * lookup class, or if this lookup object does not have private access
-         * privileges, the access fails.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the method's variable arity modifier bit ({@code 0x0080}) is set.
-         * @param refc the class or interface from which the method is accessed
-         * @param name the name of the method (which must not be "&lt;init&gt;")
-         * @param type the type of the method, with the receiver argument omitted
-         * @param specialCaller the proposed calling class to perform the {@code invokespecial}
-         * @return the desired method handle
-         * @throws NoSuchMethodException if the method does not exist
-         * @throws IllegalAccessException if access checking fails
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
-                                        Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
-            checkSpecialCaller(specialCaller);
-            MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
-            checkMethod(refc, method, false);
-            MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, specialCaller);
-            return restrictReceiver(method, mh, specialCaller);
-        }
-
-        /**
-         * Produces a method handle giving read access to a non-static field.
-         * The type of the method handle will have a return type of the field's
-         * value type.
-         * The method handle's single argument will be the instance containing
-         * the field.
-         * Access checking is performed immediately on behalf of the lookup class.
-         * @param refc the class or interface from which the method is accessed
-         * @param name the field's name
-         * @param type the field's type
-         * @return a method handle which can load values from the field
-         * @throws NoSuchFieldException if the field does not exist
-         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            return makeAccessor(refc, name, type, false, false);
-        }
-
-        /**
-         * Produces a method handle giving write access to a non-static field.
-         * The type of the method handle will have a void return type.
-         * The method handle will take two arguments, the instance containing
-         * the field, and the value to be stored.
-         * The second argument will be of the field's value type.
-         * Access checking is performed immediately on behalf of the lookup class.
-         * @param refc the class or interface from which the method is accessed
-         * @param name the field's name
-         * @param type the field's type
-         * @return a method handle which can store values into the field
-         * @throws NoSuchFieldException if the field does not exist
-         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            return makeAccessor(refc, name, type, false, true);
-        }
-
-        /**
-         * Produces a method handle giving read access to a static field.
-         * The type of the method handle will have a return type of the field's
-         * value type.
-         * The method handle will take no arguments.
-         * Access checking is performed immediately on behalf of the lookup class.
-         * @param refc the class or interface from which the method is accessed
-         * @param name the field's name
-         * @param type the field's type
-         * @return a method handle which can load values from the field
-         * @throws NoSuchFieldException if the field does not exist
-         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            return makeAccessor(refc, name, type, true, false);
-        }
-
-        /**
-         * Produces a method handle giving write access to a static field.
-         * The type of the method handle will have a void return type.
-         * The method handle will take a single
-         * argument, of the field's value type, the value to be stored.
-         * Access checking is performed immediately on behalf of the lookup class.
-         * @param refc the class or interface from which the method is accessed
-         * @param name the field's name
-         * @param type the field's type
-         * @return a method handle which can store values into the field
-         * @throws NoSuchFieldException if the field does not exist
-         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            return makeAccessor(refc, name, type, true, true);
-        }
-
-        /**
-         * Produces an early-bound method handle for a non-static method.
-         * The receiver must have a supertype {@code defc} in which a method
-         * of the given name and type is accessible to the lookup class.
-         * The method and all its argument types must be accessible to the lookup class.
-         * The type of the method handle will be that of the method,
-         * without any insertion of an additional receiver parameter.
-         * The given receiver will be bound into the method handle,
-         * so that every call to the method handle will invoke the
-         * requested method on the given receiver.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the method's variable arity modifier bit ({@code 0x0080}) is set
-         * <em>and</em> the trailing array argument is not the only argument.
-         * (If the trailing array argument is the only argument,
-         * the given receiver value will be bound to it.)
-         * <p>
-         * This is equivalent to the following code:
-         * <blockquote><pre>
-MethodHandle mh0 = {@link #findVirtual findVirtual}(defc, name, type);
-MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
-MethodType mt1 = mh1.type();
-if (mh0.isVarargsCollector() && mt1.parameterCount() > 0) {
-  mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
-return mh1;
-         * </pre></blockquote>
-         * where {@code defc} is either {@code receiver.getClass()} or a super
-         * type of that class, in which the requested method is accessible
-         * to the lookup class.
-         * (Note that {@code bindTo} does not preserve variable arity.)
-         * @param receiver the object from which the method is accessed
-         * @param name the name of the method
-         * @param type the type of the method, with the receiver argument omitted
-         * @return the desired method handle
-         * @throws NoSuchMethodException if the method does not exist
-         * @throws IllegalAccessException if access checking fails
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            Class<? extends Object> refc = receiver.getClass(); // may get NPE
-            MemberName method = resolveOrFail(refc, name, type, false);
-            checkMethod(refc, method, false);
-            MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
-            MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver);
-            if (bmh == null)
-                throw newNoAccessException(method, this);
-            if (dmh.type().parameterCount() == 0)
-                return dmh;  // bound the trailing parameter; no varargs possible
-            return fixVarargs(bmh, dmh);
-        }
-
-        /**
-         * Make a direct method handle to <i>m</i>, if the lookup class has permission.
-         * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
-         * If <i>m</i> is virtual, overriding is respected on every call.
-         * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
-         * The type of the method handle will be that of the method,
-         * with the receiver type prepended (but only if it is non-static).
-         * If the method's {@code accessible} flag is not set,
-         * access checking is performed immediately on behalf of the lookup class.
-         * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the method's variable arity modifier bit ({@code 0x0080}) is set.
-         * @param m the reflected method
-         * @return a method handle which can invoke the reflected method
-         * @throws IllegalAccessException if access checking fails
-         * @throws NullPointerException if the argument is null
-         */
-        public MethodHandle unreflect(Method m) throws IllegalAccessException {
-            MemberName method = new MemberName(m);
-            assert(method.isMethod());
-            if (!m.isAccessible())  checkMethod(method.getDeclaringClass(), method, method.isStatic());
-            MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
-            if (!m.isAccessible())  mh = restrictProtectedReceiver(method, mh);
-            return mh;
-        }
-
-        /**
-         * Produces a method handle for a reflected method.
-         * It will bypass checks for overriding methods on the receiver,
-         * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
-         * The type of the method handle will be that of the method,
-         * with the special caller type prepended (and <em>not</em> the receiver of the method).
-         * If the method's {@code accessible} flag is not set,
-         * access checking is performed immediately on behalf of the lookup class,
-         * as if {@code invokespecial} instruction were being linked.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the method's variable arity modifier bit ({@code 0x0080}) is set.
-         * @param m the reflected method
-         * @param specialCaller the class nominally calling the method
-         * @return a method handle which can invoke the reflected method
-         * @throws IllegalAccessException if access checking fails
-         * @throws NullPointerException if any argument is null
-         */
-        public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
-            checkSpecialCaller(specialCaller);
-            MemberName method = new MemberName(m);
-            assert(method.isMethod());
-            // ignore m.isAccessible:  this is a new kind of access
-            checkMethod(m.getDeclaringClass(), method, false);
-            MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
-            return restrictReceiver(method, mh, specialCaller);
-        }
-
-        /**
-         * Produces a method handle for a reflected constructor.
-         * The type of the method handle will be that of the constructor,
-         * with the return type changed to the declaring class.
-         * The method handle will perform a {@code newInstance} operation,
-         * creating a new instance of the constructor's class on the
-         * arguments passed to the method handle.
-         * <p>
-         * If the constructor's {@code accessible} flag is not set,
-         * access checking is performed immediately on behalf of the lookup class.
-         * <p>
-         * The returned method handle will have
-         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
-         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
-         * @param c the reflected constructor
-         * @return a method handle which can invoke the reflected constructor
-         * @throws IllegalAccessException if access checking fails
-         * @throws NullPointerException if the argument is null
-         */
-        public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
-            MemberName ctor = new MemberName(c);
-            assert(ctor.isConstructor());
-            if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor);
-            MethodHandle rawCtor = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
-            MethodHandle allocator = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawCtor);
-            return fixVarargs(allocator, rawCtor);
-        }
-
-        /**
-         * Produces a method handle giving read access to a reflected field.
-         * The type of the method handle will have a return type of the field's
-         * value type.
-         * If the field is static, the method handle will take no arguments.
-         * Otherwise, its single argument will be the instance containing
-         * the field.
-         * If the method's {@code accessible} flag is not set,
-         * access checking is performed immediately on behalf of the lookup class.
-         * @param f the reflected field
-         * @return a method handle which can load values from the reflected field
-         * @throws IllegalAccessException if access checking fails
-         * @throws NullPointerException if the argument is null
-         */
-        public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
-            return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false);
-        }
-
-        /**
-         * Produces a method handle giving write access to a reflected field.
-         * The type of the method handle will have a void return type.
-         * If the field is static, the method handle will take a single
-         * argument, of the field's value type, the value to be stored.
-         * Otherwise, the two arguments will be the instance containing
-         * the field, and the value to be stored.
-         * If the method's {@code accessible} flag is not set,
-         * access checking is performed immediately on behalf of the lookup class.
-         * @param f the reflected field
-         * @return a method handle which can store values into the reflected field
-         * @throws IllegalAccessException if access checking fails
-         * @throws NullPointerException if the argument is null
-         */
-        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
-            return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true);
-        }
-
-        /// Helper methods, all package-private.
-
-        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
-            checkSymbolicClass(refc);  // do this before attempting to resolve
-            name.getClass(); type.getClass();  // NPE
-            int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
-                                            NoSuchFieldException.class);
-        }
-
-        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
-            checkSymbolicClass(refc);  // do this before attempting to resolve
-            name.getClass(); type.getClass();  // NPE
-            int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
-                                            NoSuchMethodException.class);
-        }
-
-        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
-                                 boolean searchSupers, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
-            checkSymbolicClass(refc);  // do this before attempting to resolve
-            name.getClass(); type.getClass();  // NPE
-            int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
-                                            NoSuchMethodException.class);
-        }
-
-        void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
-            Class<?> caller = lookupClassOrNull();
-            if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
-                throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), this);
-        }
-
-        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
-            String message;
-            if (m.isConstructor())
-                message = "expected a method, not a constructor";
-            else if (!m.isMethod())
-                message = "expected a method";
-            else if (wantStatic != m.isStatic())
-                message = wantStatic ? "expected a static method" : "expected a non-static method";
-            else
-                { checkAccess(refc, m); return; }
-            throw newNoAccessException(message, m, this);
-        }
-
-        void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
-            int allowedModes = this.allowedModes;
-            if (allowedModes == TRUSTED)  return;
-            int mods = m.getModifiers();
-            if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
-                return;  // common case
-            int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
-            if ((requestedModes & allowedModes) != 0
-                && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
-                                                   mods, lookupClass()))
-                return;
-            if (((requestedModes & ~allowedModes) & PROTECTED) != 0
-                && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
-                // Protected members can also be checked as if they were package-private.
-                return;
-            throw newNoAccessException(accessFailedMessage(refc, m), m, this);
-        }
-
-        String accessFailedMessage(Class<?> refc, MemberName m) {
-            Class<?> defc = m.getDeclaringClass();
-            int mods = m.getModifiers();
-            // check the class first:
-            boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
-                               (defc == refc ||
-                                Modifier.isPublic(refc.getModifiers())));
-            if (!classOK && (allowedModes & PACKAGE) != 0) {
-                classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) &&
-                           (defc == refc ||
-                            VerifyAccess.isClassAccessible(refc, lookupClass())));
-            }
-            if (!classOK)
-                return "class is not public";
-            if (Modifier.isPublic(mods))
-                return "access to public member failed";  // (how?)
-            if (Modifier.isPrivate(mods))
-                return "member is private";
-            if (Modifier.isProtected(mods))
-                return "member is protected";
-            return "member is private to package";
-        }
-
-        private static final boolean ALLOW_NESTMATE_ACCESS = false;
-
-        void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
-            if (allowedModes == TRUSTED)  return;
-            if ((allowedModes & PRIVATE) == 0
-                || (specialCaller != lookupClass()
-                    && !(ALLOW_NESTMATE_ACCESS &&
-                         VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
-                throw newNoAccessException("no private access for invokespecial",
-                                           new MemberName(specialCaller), this);
-        }
-
-        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
-            // The accessing class only has the right to use a protected member
-            // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
-            if (!method.isProtected() || method.isStatic()
-                || allowedModes == TRUSTED
-                || method.getDeclaringClass() == lookupClass()
-                || (ALLOW_NESTMATE_ACCESS &&
-                    VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
-                return mh;
-            else
-                return restrictReceiver(method, mh, lookupClass());
-        }
-        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
-            assert(!method.isStatic());
-            Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
-            if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
-                throw newNoAccessException("caller class must be a subclass below the method", method, caller);
-            }
-            MethodType rawType = mh.type();
-            if (rawType.parameterType(0) == caller)  return mh;
-            MethodType narrowType = rawType.changeParameterType(0, caller);
-            MethodHandle narrowMH = MethodHandleImpl.convertArguments(IMPL_TOKEN, mh, narrowType, rawType, null);
-            return fixVarargs(narrowMH, mh);
-        }
-
-        MethodHandle makeAccessor(Class<?> refc, String name, Class<?> type,
-                                  boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, isStatic);
-            if (isStatic != field.isStatic())
-                throw newNoAccessException(isStatic
-                                           ? "expected a static field"
-                                           : "expected a non-static field",
-                                           field, this);
-            return makeAccessor(refc, field, false, isSetter);
-        }
-
-        MethodHandle makeAccessor(Class<?> refc, MemberName field,
-                                  boolean trusted, boolean isSetter) throws IllegalAccessException {
-            assert(field.isField());
-            if (trusted)
-                return MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
-            checkAccess(refc, field);
-            MethodHandle mh = MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
-            return restrictProtectedReceiver(field, mh);
-        }
-    }
-
-    /**
-     * Produces a method handle giving read access to elements of an array.
-     * The type of the method handle will have a return type of the array's
-     * element type.  Its first argument will be the array type,
-     * and the second will be {@code int}.
-     * @param arrayClass an array type
-     * @return a method handle which can load values from the given array type
-     * @throws NullPointerException if the argument is null
-     * @throws  IllegalArgumentException if arrayClass is not an array type
-     */
-    public static
-    MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
-        return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, false);
-    }
-
-    /**
-     * Produces a method handle giving write access to elements of an array.
-     * 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.
-     * @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
-     */
-    public static
-    MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
-        return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, true);
-    }
-
-    /// method handle invocation (reflective style)
-
-    /**
-     * Produces a method handle which will invoke any method handle of the
-     * given {@code type} on a standard set of {@code Object} type arguments
-     * and a single trailing {@code Object[]} array.
-     * The resulting invoker will be a method handle with the following
-     * arguments:
-     * <ul>
-     * <li>a single {@code MethodHandle} target
-     * <li>zero or more {@code Object} values (counted by {@code objectArgCount})
-     * <li>an {@code Object[]} array containing more arguments
-     * </ul>
-     * <p>
-     * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
-     * the indicated {@code type}.
-     * That is, if the target is exactly of the given {@code type}, it will behave
-     * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
-     * is used to convert the target to the required {@code type}.
-     * <p>
-     * The type of the returned invoker will not be the given {@code type}, but rather
-     * will have all parameter and return types replaced by {@code Object}, except for
-     * the last parameter type, which will be the array type {@code Object[]}.
-     * <p>
-     * Before invoking its target, the invoker will spread the varargs array, apply
-     * reference casts as necessary, and unbox and widen primitive arguments.
-     * The return value of the invoker will be an {@code Object} reference,
-     * boxing a primitive value if the original type returns a primitive,
-     * and always null if the original type returns void.
-     * <p>
-     * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
-MethodHandle invoker = MethodHandles.genericInvoker(type);
-int spreadArgCount = type.parameterCount - objectArgCount;
-invoker = invoker.asSpreader(Object[].class, spreadArgCount);
-return invoker;
-     * </pre></blockquote>
-     * <p>
-     * This method throws no reflective or security exceptions.
-     * @param type the desired target type
-     * @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
-     * @return a method handle suitable for invoking any method handle of the given type
-     */
-    static public
-    MethodHandle spreadInvoker(MethodType type, int objectArgCount) {
-        if (objectArgCount < 0 || objectArgCount > type.parameterCount())
-            throw new IllegalArgumentException("bad argument count "+objectArgCount);
-        return invokers(type).spreadInvoker(objectArgCount);
-    }
-
-    /**
-     * Produces a special <em>invoker method handle</em> which can be used to
-     * invoke any method handle of the given type, as if by {@code invokeExact}.
-     * The resulting invoker will have a type which is
-     * exactly equal to the desired type, except that it will accept
-     * an additional leading argument of type {@code MethodHandle}.
-     * <p>
-     * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
-     * </pre></blockquote>
-     *
-     * <p style="font-size:smaller;">
-     * <em>Discussion:</em>
-     * Invoker method handles can be useful when working with variable method handles
-     * of unknown types.
-     * For example, to emulate an {@code invokeExact} call to a variable method
-     * handle {@code M}, extract its type {@code T},
-     * look up the invoker method {@code X} for {@code T},
-     * and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
-     * (It would not work to call {@code X.invokeExact}, since the type {@code T}
-     * is unknown.)
-     * If spreading, collecting, or other argument transformations are required,
-     * they can be applied once to the invoker {@code X} and reused on many {@code M}
-     * method handle values, as long as they are compatible with the type of {@code X}.
-     * <p>
-     * <em>(Note:  The invoker method is not available via the Core Reflection API.
-     * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
-     * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
-     * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
-     * <p>
-     * This method throws no reflective or security exceptions.
-     * @param type the desired target type
-     * @return a method handle suitable for invoking any method handle of the given type
-     */
-    static public
-    MethodHandle exactInvoker(MethodType type) {
-        return invokers(type).exactInvoker();
-    }
-
-    /**
-     * Produces a special <em>invoker method handle</em> which can be used to
-     * invoke any method handle of the given type, as if by {@code invokeGeneric}.
-     * The resulting invoker will have a type which is
-     * exactly equal to the desired type, except that it will accept
-     * an additional leading argument of type {@code MethodHandle}.
-     * <p>
-     * Before invoking its target, the invoker will apply reference casts as
-     * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
-     * The return value of the invoker will be an {@code Object} reference,
-     * boxing a primitive value if the original type returns a primitive,
-     * and always null if the original type returns void.
-     * <p>
-     * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
-     * </pre></blockquote>
-     * <p>
-     * This method throws no reflective or security exceptions.
-     * @param type the desired target type
-     * @return a method handle suitable for invoking any method handle convertible to the given type
-     */
-    static public
-    MethodHandle genericInvoker(MethodType type) {
-        return invokers(type).genericInvoker();
-    }
-
-    static Invokers invokers(MethodType type) {
-        return MethodTypeImpl.invokers(IMPL_TOKEN, type);
-    }
-
-    /**
-     * Perform value checking, exactly as if for an adapted method handle.
-     * It is assumed that the given value is either null, of type T0,
-     * or (if T0 is primitive) of the wrapper type corresponding to T0.
-     * The following checks and conversions are made:
-     * <ul>
-     * <li>If T0 and T1 are references, then a cast to T1 is applied.
-     *     (The types do not need to be related in any particular way.)
-     * <li>If T0 and T1 are primitives, then a widening or narrowing
-     *     conversion is applied, if one exists.
-     * <li>If T0 is a primitive and T1 a reference, and
-     *     T0 has a wrapper type TW, a boxing conversion to TW is applied,
-     *     possibly followed by a reference conversion.
-     *     T1 must be TW or a supertype.
-     * <li>If T0 is a reference and T1 a primitive, and
-     *     T1 has a wrapper type TW, an unboxing conversion is applied,
-     *     possibly preceded by a reference conversion.
-     *     T0 must be TW or a supertype.
-     * <li>If T1 is void, the return value is discarded
-     * <li>If T0 is void and T1 a reference, a null value is introduced.
-     * <li>If T0 is void and T1 a primitive, a zero value is introduced.
-     * </ul>
-     * If the value is discarded, null will be returned.
-     * @param valueType
-     * @param value
-     * @return the value, converted if necessary
-     * @throws java.lang.ClassCastException if a cast fails
-     */
-    static
-    <T0, T1> T1 checkValue(Class<T0> t0, Class<T1> t1, Object value)
-       throws ClassCastException
-    {
-        if (t0 == t1) {
-            // no conversion needed; just reassert the same type
-            if (t0.isPrimitive())
-                return Wrapper.asPrimitiveType(t1).cast(value);
-            else
-                return Wrapper.OBJECT.convert(value, t1);
-        }
-        boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
-        if (!prim0) {
-            // check contract with caller
-            Wrapper.OBJECT.convert(value, t0);
-            if (!prim1) {
-                return Wrapper.OBJECT.convert(value, t1);
-            }
-            // convert reference to primitive by unboxing
-            Wrapper w1 = Wrapper.forPrimitiveType(t1);
-            return w1.convert(value, t1);
-        }
-        // check contract with caller:
-        Wrapper.asWrapperType(t0).cast(value);
-        Wrapper w1 = Wrapper.forPrimitiveType(t1);
-        return w1.convert(value, t1);
-    }
-
-    static
-    Object checkValue(Class<?> T1, Object value)
-       throws ClassCastException
-    {
-        Class<?> T0;
-        if (value == null)
-            T0 = Object.class;
-        else
-            T0 = value.getClass();
-        return checkValue(T0, T1, value);
-    }
-
-    /// method handle modification (creation from other method handles)
-
-    /**
-     * Produces a method handle which adapts the type of the
-     * given method handle to a new type by pairwise argument conversion.
-     * The original type and new type must have the same number of arguments.
-     * The resulting method handle is guaranteed to report a type
-     * which is equal to the desired new type.
-     * <p>
-     * If the original type and new type are equal, returns target.
-     * <p>
-     * The following conversions are applied as needed both to
-     * arguments and return types.  Let T0 and T1 be the differing
-     * new and old parameter types (or old and new return types)
-     * for corresponding values passed by the new and old method types.
-     * Given those types T0, T1, one of the following conversions is applied
-     * if possible:
-     * <ul>
-     * <li>If T0 and T1 are references, then a cast to T1 is applied.
-     *     (The types do not need to be related in any particular way.)
-     * <li>If T0 and T1 are primitives, then a Java method invocation
-     *     conversion (JLS 5.3) is applied, if one exists.
-     * <li>If T0 is a primitive and T1 a reference, a boxing
-     *     conversion is applied if one exists, possibly followed by
-     *     a reference conversion to a superclass.
-     *     T1 must be a wrapper class or a supertype of one.
-     * <li>If T0 is a reference and T1 a primitive, an unboxing
-     *     conversion will be applied at runtime, possibly followed
-     *     by a Java method invocation conversion (JLS 5.3)
-     *     on the primitive value.  (These are the widening conversions.)
-     *     T0 must be a wrapper class or a supertype of one.
-     *     (In the case where T0 is Object, these are the conversions
-     *     allowed by java.lang.reflect.Method.invoke.)
-     * <li>If the return type T1 is void, any returned value is discarded
-     * <li>If the return type T0 is void and T1 a reference, a null value is introduced.
-     * <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
-     * </ul>
-     * @param target the method handle to invoke after arguments are retyped
-     * @param newType the expected type of the new method handle
-     * @return a method handle which delegates to {@code target} after performing
-     *           any necessary argument conversions, and arranges for any
-     *           necessary return value conversions
-     * @throws NullPointerException if either argument is null
-     * @throws WrongMethodTypeException if the conversion cannot be made
-     * @see MethodHandle#asType
-     * @see MethodHandles#explicitCastArguments
-     */
-    public static
-    MethodHandle convertArguments(MethodHandle target, MethodType newType) {
-        MethodType oldType = target.type();
-        if (oldType.equals(newType))
-            return target;
-        MethodHandle res = null;
-        try {
-            res = MethodHandleImpl.convertArguments(IMPL_TOKEN, target,
-                                                    newType, oldType, null);
-        } catch (IllegalArgumentException ex) {
-        }
-        if (res == null)
-            throw new WrongMethodTypeException("cannot convert to "+newType+": "+target);
-        return res;
-    }
-
-    /**
-     * Produces a method handle which adapts the type of the
-     * given method handle to a new type by pairwise argument conversion.
-     * The original type and new type must have the same number of arguments.
-     * The resulting method handle is guaranteed to report a type
-     * which is equal to the desired new type.
-     * <p>
-     * If the original type and new type are equal, returns target.
-     * <p>
-     * The same conversions are allowed as for {@link #convertArguments convertArguments},
-     * and some additional conversions are also applied if those conversions fail.
-     * Given types T0, T1, one of the following conversions is applied
-     * in addition, if the conversions specified for {@code convertArguments}
-     * would be insufficient:
-     * <ul>
-     * <li>If T0 and T1 are references, and T1 is an interface type,
-     *     then the value of type T0 is passed as a T1 without a cast.
-     *     (This treatment of interfaces follows the usage of the bytecode verifier.)
-     * <li>If T0 and T1 are primitives and one is boolean,
-     *     the boolean is treated as a one-bit unsigned integer.
-     *     (This treatment follows the usage of the bytecode verifier.)
-     *     A conversion from another primitive type behaves as if
-     *     it first converts to byte, and then masks all but the low bit.
-     * <li>If a primitive value would be converted by {@code convertArguments}
-     *     using Java method invocation conversion (JLS 5.3),
-     *     Java casting conversion (JLS 5.5) may be used also.
-     *     This allows primitives to be narrowed as well as widened.
-     * </ul>
-     * @param target the method handle to invoke after arguments are retyped
-     * @param newType the expected type of the new method handle
-     * @return a method handle which delegates to {@code target} after performing
-     *           any necessary argument conversions, and arranges for any
-     *           necessary return value conversions
-     * @throws NullPointerException if either argument is null
-     * @throws WrongMethodTypeException if the conversion cannot be made
-     * @see MethodHandle#asType
-     * @see MethodHandles#convertArguments
-     */
-    public static
-    MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
-        return convertArguments(target, newType);  // FIXME!
-    }
-
-    /*
-      FIXME: Reconcile javadoc with 10/22/2010 EG notes on conversion:
-
-      Both converters arrange for their method handles to convert arguments
-      and return values.  The conversion rules are the same for arguments
-      and return values, and depend only on source and target types, S and
-      T.  The conversions allowed by castConvertArguments are a strict
-      superset of those performed by convertArguments.
-
-      In all cases, if S and T are references, a simple checkcast is done.
-      If neither S nor T is a primitive, no attempt is made to unbox and
-      box.  A failed conversion throws ClassCastException.
-
-      If T is void, the value is dropped.
-
-      For compatibility with reflection, if S is void and T is a reference,
-      a null value is produced.
-
-      For compatibility with reflection, if S is a reference and T is a
-      primitive, S is first unboxed and then undergoes primitive conversion.
-      In the case of 'convertArguments', only assignment conversion is
-      performed (no narrowing primitive conversion).
-
-      If S is a primitive, S is boxed, and then the above rules are applied.
-      If S and T are both primitives, the boxing will be undetectable; only
-      the primitive conversions will be apparent to the user.  The key point
-      is that if S is a primitive type, the implementation may box it and
-      treat is as Object, without loss of information, or it may use a "fast
-      path" which does not use boxing.
-
-      Notwithstanding the rules above, for compatibility with the verifier,
-      if T is an interface, it is treated as if it were Object.  [KEEP THIS?]
-
-      Also, for compatibility with the verifier, a boolean may be undergo
-      widening or narrowing conversion to any other primitive type.  [KEEP THIS?]
-    */
-
-    /**
-     * Produces a method handle which adapts the calling sequence of the
-     * given method handle to a new type, by reordering the arguments.
-     * The resulting method handle is guaranteed to report a type
-     * which is equal to the desired new type.
-     * <p>
-     * The given array controls the reordering.
-     * Call {@code #I} the number of incoming parameters (the value
-     * {@code newType.parameterCount()}, and call {@code #O} the number
-     * of outgoing parameters (the value {@code target.type().parameterCount()}).
-     * Then the length of the reordering array must be {@code #O},
-     * and each element must be a non-negative number less than {@code #I}.
-     * For every {@code N} less than {@code #O}, the {@code N}-th
-     * outgoing argument will be taken from the {@code I}-th incoming
-     * argument, where {@code I} is {@code reorder[N]}.
-     * <p>
-     * No argument or return value conversions are applied.
-     * The type of each incoming argument, as determined by {@code newType},
-     * must be identical to the type of the corresponding outgoing argument
-     * or arguments in the target method handle.
-     * The return type of {@code newType} must be identical to the return
-     * type of the original target.
-     * <p>
-     * The reordering array need not specify an actual permutation.
-     * An incoming argument will be duplicated if its index appears
-     * more than once in the array, and an incoming argument will be dropped
-     * if its index does not appear in the array.
-     * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
-     * incoming arguments which are not mentioned in the reordering array
-     * are may be any type, as determined only by {@code newType}.
-     * <blockquote><pre>
-MethodType intfn1 = MethodType.methodType(int.class, int.class);
-MethodType intfn2 = MethodType.methodType(int.class, int.class, int.class);
-MethodHandle sub = ... {int x, int y => x-y} ...;
-assert(sub.type().equals(intfn2));
-MethodHandle sub1 = MethodHandles.permuteArguments(sub, intfn2, 0, 1);
-MethodHandle rsub = MethodHandles.permuteArguments(sub, intfn2, 1, 0);
-assert((int)rsub.invokeExact(1, 100) == 99);
-MethodHandle add = ... {int x, int y => x+y} ...;
-assert(add.type().equals(intfn2));
-MethodHandle twice = MethodHandles.permuteArguments(add, intfn1, 0, 0);
-assert(twice.type().equals(intfn1));
-assert((int)twice.invokeExact(21) == 42);
-     * </pre></blockquote>
-     * @param target the method handle to invoke after arguments are reordered
-     * @param newType the expected type of the new method handle
-     * @param reorder a string which controls the reordering
-     * @return a method handle which delegates to {@code target} after it
-     *           drops unused arguments and moves and/or duplicates the other arguments
-     * @throws NullPointerException if any argument is null
-     */
-    public static
-    MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
-        MethodType oldType = target.type();
-        checkReorder(reorder, newType, oldType);
-        return MethodHandleImpl.convertArguments(IMPL_TOKEN, target,
-                                                 newType, oldType,
-                                                 reorder);
-    }
-
-    private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
-        if (reorder.length == oldType.parameterCount()) {
-            int limit = newType.parameterCount();
-            boolean bad = false;
-            for (int i : reorder) {
-                if (i < 0 || i >= limit) {
-                    bad = true; break;
-                }
-            }
-            if (!bad)  return;
-        }
-        throw newIllegalArgumentException("bad reorder array");
-    }
-
-    /**
-     * Equivalent to the following code:
-     * <p><blockquote><pre>
-     * int spreadPos = newType.parameterCount() - 1;
-     * Class&lt;?&gt; spreadType = newType.parameterType(spreadPos);
-     * int spreadCount = target.type().parameterCount() - spreadPos;
-     * MethodHandle adapter = target.asSpreader(spreadType, spreadCount);
-     * adapter = adapter.asType(newType);
-     * return adapter;
-     * </pre></blockquote>
-     * @param target the method handle to invoke after argument spreading
-     * @param newType the expected type of the new method handle
-     * @return a method handle which spreads its final argument,
-     *         before calling the original method handle
-     */
-    /*non-public*/ static
-    MethodHandle spreadArguments(MethodHandle target, MethodType newType) {
-        MethodType oldType = target.type();
-        int inargs  = newType.parameterCount();
-        int outargs = oldType.parameterCount();
-        int spreadPos = inargs - 1;
-        int numSpread = (outargs - spreadPos);
-        MethodHandle res = null;
-        if (spreadPos >= 0 && numSpread >= 0) {
-            res = MethodHandleImpl.spreadArguments(IMPL_TOKEN, target, newType, spreadPos);
-        }
-        if (res == null) {
-            throw newIllegalArgumentException("cannot spread "+newType+" to " +oldType);
-        }
-        return res;
-    }
-
-    /**
-     * Equivalent to the following code:
-     * <p><blockquote><pre>
-     * int collectPos = target.type().parameterCount() - 1;
-     * Class&lt;?&gt; collectType = target.type().parameterType(collectPos);
-     * if (!collectType.isArray())  collectType = Object[].class;
-     * int collectCount = newType.parameterCount() - collectPos;
-     * MethodHandle adapter = target.asCollector(collectType, collectCount);
-     * adapter = adapter.asType(newType);
-     * return adapter;
-     * </pre></blockquote>
-     * @param target the method handle to invoke after argument collection
-     * @param newType the expected type of the new method handle
-     * @return a method handle which collects some trailing argument
-     *         into an array, before calling the original method handle
-     */
-    /*non-public*/ static
-    MethodHandle collectArguments(MethodHandle target, MethodType newType) {
-        MethodType oldType = target.type();
-        int inargs  = newType.parameterCount();
-        int outargs = oldType.parameterCount();
-        int collectPos = outargs - 1;
-        int numCollect = (inargs - collectPos);
-        if (collectPos < 0 || numCollect < 0)
-            throw newIllegalArgumentException("wrong number of arguments");
-        MethodHandle res = MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos, null);
-        if (res == null) {
-            throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
-        }
-        return res;
-    }
-
-    /**
-     * Produces a method handle of the requested return type which returns the given
-     * constant value every time it is invoked.
-     * <p>
-     * Before the method handle is returned, the passed-in value is converted to the requested type.
-     * If the requested type is primitive, widening primitive conversions are attempted,
-     * else reference conversions are attempted.
-     * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)},
-     * unless the type is {@code void}, in which case it is {@code identity(type)}.
-     * @param type the return type of the desired method handle
-     * @param value the value to return
-     * @return a method handle of the given return type and no arguments, which always returns the given value
-     * @throws NullPointerException if the {@code type} argument is null
-     * @throws ClassCastException if the value cannot be converted to the required return type
-     * @throws IllegalArgumentException if the given type is {@code void.class}
-     */
-    public static
-    MethodHandle constant(Class<?> type, Object value) {
-        if (type.isPrimitive()) {
-            if (type == void.class)
-                throw newIllegalArgumentException("void type");
-            Wrapper w = Wrapper.forPrimitiveType(type);
-            return identity(type).bindTo(w.convert(value, type));
-        } else {
-            return identity(type).bindTo(type.cast(value));
-        }
-    }
-
-    /**
-     * Produces a method handle which returns its sole argument when invoked.
-     * <p>The identity function for {@code void} takes no arguments and returns no values.
-     * @param type the type of the sole parameter and return value of the desired method handle
-     * @return a unary method handle which accepts and returns the given type
-     * @throws NullPointerException if the argument is null
-     * @throws IllegalArgumentException if the given type is {@code void.class}
-     */
-    public static
-    MethodHandle identity(Class<?> type) {
-        if (type == void.class)
-            throw newIllegalArgumentException("void type");
-        return ValueConversions.identity(type);
-    }
-
-    /**
-     * Produces a method handle which calls the original method handle {@code target},
-     * after inserting the given argument(s) at the given position.
-     * The formal parameters to {@code target} which will be supplied by those
-     * arguments are called <em>bound parameters</em>, because the new method
-     * will contain bindings for those parameters take from {@code values}.
-     * The type of the new method handle will drop the types for the bound
-     * parameters from the original target type, since the new method handle
-     * will no longer require those arguments to be supplied by its callers.
-     * <p>
-     * Each given argument object must match the corresponding bound parameter type.
-     * If a bound parameter type is a primitive, the argument object
-     * must be a wrapper, and will be unboxed to produce the primitive value.
-     * <p>
-     * The  <i>pos</i> may range between zero and <i>N</i> (inclusively),
-     * where <i>N</i> is the number of argument types in resulting method handle
-     * (after bound parameter types are dropped).
-     * @param target the method handle to invoke after the argument is inserted
-     * @param pos where to insert the argument (zero for the first)
-     * @param values the series of arguments to insert
-     * @return a method handle which inserts an additional argument,
-     *         before calling the original method handle
-     * @throws NullPointerException if the {@code target} argument or the {@code values} array is null
-     * @see MethodHandle#bindTo
-     */
-    public static
-    MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
-        int insCount = values.length;
-        MethodType oldType = target.type();
-        ArrayList<Class<?>> ptypes =
-                new ArrayList<Class<?>>(oldType.parameterList());
-        int outargs = oldType.parameterCount();
-        int inargs  = outargs - insCount;
-        if (inargs < 0)
-            throw newIllegalArgumentException("too many values to insert");
-        if (pos < 0 || pos > inargs)
-            throw newIllegalArgumentException("no argument type to append");
-        MethodHandle result = target;
-        for (int i = 0; i < insCount; i++) {
-            Object value = values[i];
-            Class<?> valueType = oldType.parameterType(pos+i);
-            value = checkValue(valueType, value);
-            if (pos == 0 && !valueType.isPrimitive()) {
-                // At least for now, make bound method handles a special case.
-                MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, result, value);
-                if (bmh != null) {
-                    result = bmh;
-                    continue;
-                }
-                // else fall through to general adapter machinery
-            }
-            result = MethodHandleImpl.bindArgument(IMPL_TOKEN, result, pos, value);
-        }
-        return result;
-    }
-
-    /**
-     * Produces a method handle which calls the original method handle,
-     * after dropping the given argument(s) at the given position.
-     * The type of the new method handle will insert the given argument
-     * type(s), at that position, into the original handle's type.
-     * <p>
-     * The <i>pos</i> may range between zero and <i>N</i>,
-     * where <i>N</i> is the number of argument types in <i>target</i>,
-     * meaning to drop the first or last argument (respectively),
-     * or an argument somewhere in between.
-     * <p>
-     * <b>Example:</b>
-     * <p><blockquote><pre>
-import static java.dyn.MethodHandles.*;
-import static java.dyn.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
-  "concat", methodType(String.class, String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodHandle d0 = dropArguments(cat, 0, String.class);
-assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
-MethodHandle d1 = dropArguments(cat, 1, String.class);
-assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
-MethodHandle d2 = dropArguments(cat, 2, String.class);
-assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
-MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
-assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
-     * </pre></blockquote>
-     * @param target the method handle to invoke after the arguments are dropped
-     * @param valueTypes the type(s) of the argument(s) to drop
-     * @param pos position of first argument to drop (zero for the leftmost)
-     * @return a method handle which drops arguments of the given types,
-     *         before calling the original method handle
-     * @throws NullPointerException if the {@code target} argument is null,
-     *                              or if the {@code valueTypes} list or any of its elements is null
-     * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
-     */
-    public static
-    MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
-        if (valueTypes.size() == 0)  return target;
-        MethodType oldType = target.type();
-        int outargs = oldType.parameterCount();
-        int inargs  = outargs + valueTypes.size();
-        if (pos < 0 || pos >= inargs)
-            throw newIllegalArgumentException("no argument type to remove");
-        ArrayList<Class<?>> ptypes =
-                new ArrayList<Class<?>>(oldType.parameterList());
-        ptypes.addAll(pos, valueTypes);
-        MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
-        return MethodHandleImpl.dropArguments(IMPL_TOKEN, target, newType, pos);
-    }
-
-    /**
-     * Produces a method handle which calls the original method handle,
-     * after dropping the given argument(s) at the given position.
-     * The type of the new method handle will insert the given argument
-     * type(s), at that position, into the original handle's type.
-     * This method is equivalent to the following code:
-     * <code>
-     * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
-     * </code>
-     * @param target the method handle to invoke after the arguments are dropped
-     * @param valueTypes the type(s) of the argument(s) to drop
-     * @param pos position of first argument to drop (zero for the leftmost)
-     * @return a method handle which drops arguments of the given types,
-     *         before calling the original method handle
-     * @throws NullPointerException if the {@code target} argument is null,
-     *                              or if the {@code valueTypes} array or any of its elements is null
-     * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
-     */
-    public static
-    MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
-        return dropArguments(target, pos, Arrays.asList(valueTypes));
-    }
-
-    /**
-     * Adapt a target method handle {@code target} by pre-processing
-     * one or more of its arguments, each with its own unary filter function,
-     * and then calling the target with each pre-processed argument
-     * replaced by the result of its corresponding filter function.
-     * <p>
-     * The pre-processing is performed by one or more method handles,
-     * specified in the elements of the {@code filters} array.
-     * Null arguments in the array are ignored, and the corresponding arguments left unchanged.
-     * (If there are no non-null elements in the array, the original target is returned.)
-     * Each filter is applied to the corresponding argument of the adapter.
-     * <p>
-     * If a filter {@code F} applies to the {@code N}th argument of
-     * the method handle, then {@code F} must be a method handle which
-     * takes exactly one argument.  The type of {@code F}'s sole argument
-     * replaces the corresponding argument type of the target
-     * in the resulting adapted method handle.
-     * The return type of {@code F} must be identical to the corresponding
-     * parameter type of the target.
-     * <p>
-     * It is an error if there are elements of {@code filters}
-     * which do not correspond to argument positions in the target.
-     * <b>Example:</b>
-     * <p><blockquote><pre>
-import static java.dyn.MethodHandles.*;
-import static java.dyn.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
-  "concat", methodType(String.class, String.class));
-MethodHandle upcase = lookup().findVirtual(String.class,
-  "toUpperCase", methodType(String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodHandle f0 = filterArguments(cat, 0, upcase);
-assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
-MethodHandle f1 = filterArguments(cat, 1, upcase);
-assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
-MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
-assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
-     * </pre></blockquote>
-     *
-     * @param target the method handle to invoke after arguments are filtered
-     * @param pos the position of the first argument to filter
-     * @param filters method handles to call initially on filtered arguments
-     * @return method handle which incorporates the specified argument filtering logic
-     * @throws NullPointerException if the {@code target} argument is null
-     *                              or if the {@code filters} array is null
-     * @throws IllegalArgumentException if a non-null element of {@code filters}
-     *          does not match a corresponding argument type of {@code target} as described above,
-     *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
-     */
-    public static
-    MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
-        MethodType targetType = target.type();
-        MethodHandle adapter = target;
-        MethodType adapterType = targetType;
-        int maxPos = targetType.parameterCount();
-        if (pos + filters.length > maxPos)
-            throw newIllegalArgumentException("too many filters");
-        int curPos = pos-1;  // pre-incremented
-        for (MethodHandle filter : filters) {
-            curPos += 1;
-            if (filter == null)  continue;  // ignore null elements of filters
-            MethodType filterType = filter.type();
-            if (filterType.parameterCount() != 1
-                || filterType.returnType() != targetType.parameterType(curPos))
-                throw newIllegalArgumentException("target and filter types do not match");
-            adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
-            adapter = MethodHandleImpl.filterArgument(IMPL_TOKEN, adapter, curPos, filter);
-        }
-        MethodType midType = adapter.type();
-        if (midType != adapterType)
-            adapter = MethodHandleImpl.convertArguments(IMPL_TOKEN, adapter, adapterType, midType, null);
-        return adapter;
-    }
-
-    /**
-     * Adapt a target method handle {@code target} by post-processing
-     * its return value with a unary filter function.
-     * <p>
-     * If a filter {@code F} applies to the return value of
-     * the target method handle, then {@code F} must be a method handle which
-     * takes exactly one argument.  The return type of {@code F}
-     * replaces the return type of the target
-     * in the resulting adapted method handle.
-     * The argument type of {@code F} must be identical to the
-     * return type of the target.
-     * <b>Example:</b>
-     * <p><blockquote><pre>
-import static java.dyn.MethodHandles.*;
-import static java.dyn.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
-  "concat", methodType(String.class, String.class));
-MethodHandle length = lookup().findVirtual(String.class,
-  "length", methodType(int.class));
-System.out.println((String) cat.invokeExact("x", "y")); // xy
-MethodHandle f0 = filterReturnValue(cat, length);
-System.out.println((int) f0.invokeExact("x", "y")); // 2
-     * </pre></blockquote>
-     * @param target the method handle to invoke before filtering the return value
-     * @param filter method handle to call on the return value
-     * @return method handle which incorporates the specified return value filtering logic
-     * @throws NullPointerException if either argument is null
-     * @throws IllegalArgumentException if {@code filter}
-     *          does not match the return type of {@code target} as described above
-     */
-    public static
-    MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
-        MethodType targetType = target.type();
-        MethodType filterType = filter.type();
-        if (filterType.parameterCount() != 1
-            || filterType.parameterType(0) != targetType.returnType())
-            throw newIllegalArgumentException("target and filter types do not match");
-        // result = fold( lambda(retval, arg...) { filter(retval) },
-        //                lambda(        arg...) { target(arg...) } )
-        // FIXME: Too many nodes here.
-        MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
-        return foldArguments(returner, target);
-    }
-
-    /**
-     * Adapt a target method handle {@code target} by pre-processing
-     * some of its arguments, and then calling the target with
-     * the result of the pre-processing, plus all original arguments.
-     * <p>
-     * The pre-processing is performed by a second method handle, the {@code combiner}.
-     * The first {@code N} arguments passed to the adapter,
-     * are copied to the combiner, which then produces a result.
-     * (Here, {@code N} is defined as the parameter count of the adapter.)
-     * After this, control passes to the {@code target}, with both the result
-     * of the combiner, and all the original incoming arguments.
-     * <p>
-     * The first argument type of the target must be identical with the
-     * return type of the combiner.
-     * The resulting adapter is the same type as the target, except that the
-     * initial argument type of the target is dropped.
-     * <p>
-     * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
-     * that either the {@code combiner} or {@code target} does not wish to receive.
-     * If some of the incoming arguments are destined only for the combiner,
-     * consider using {@link MethodHandle#asCollector asCollector} instead, since those
-     * arguments will not need to be live on the stack on entry to the
-     * target.)
-     * <p>
-     * The first argument of the target must be identical with the
-     * return value of the combiner.
-     * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
-     * // there are N arguments in the A sequence
-     * T target(V, A[N]..., B...);
-     * V combiner(A...);
-     * T adapter(A... a, B... b) {
-     *   V v = combiner(a...);
-     *   return target(v, a..., b...);
-     * }
-     * </pre></blockquote>
-     * @param target the method handle to invoke after arguments are combined
-     * @param combiner method handle to call initially on the incoming arguments
-     * @return method handle which incorporates the specified argument folding logic
-     * @throws NullPointerException if either argument is null
-     * @throws IllegalArgumentException if the first argument type of
-     *          {@code target} is not the same as {@code combiner}'s return type,
-     *          or if the following argument types of {@code target}
-     *          are not identical with the argument types of {@code combiner}
-     */
-    public static
-    MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
-        MethodType targetType = target.type();
-        MethodType combinerType = combiner.type();
-        int foldArgs = combinerType.parameterCount();
-        boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
-        if (ok && !combinerType.parameterList().equals(targetType.parameterList().subList(1, foldArgs+1)))
-            ok = false;
-        if (ok && !combinerType.returnType().equals(targetType.parameterType(0)))
-            ok = false;
-        if (!ok)
-            throw misMatchedTypes("target and combiner types", targetType, combinerType);
-        MethodType newType = targetType.dropParameterTypes(0, 1);
-        return MethodHandleImpl.foldArguments(IMPL_TOKEN, target, newType, combiner);
-    }
-
-    /**
-     * Make a method handle which adapts a target method handle,
-     * by guarding it with a test, a boolean-valued method handle.
-     * If the guard fails, a fallback handle is called instead.
-     * All three method handles must have the same corresponding
-     * argument and return types, except that the return type
-     * of the test must be boolean, and the test is allowed
-     * to have fewer arguments than the other two method handles.
-     * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
-     * boolean test(A...);
-     * T target(A...,B...);
-     * T fallback(A...,B...);
-     * T adapter(A... a,B... b) {
-     *   if (test(a...))
-     *     return target(a..., b...);
-     *   else
-     *     return fallback(a..., b...);
-     * }
-     * </pre></blockquote>
-     * Note that the test arguments ({@code a...} in the pseudocode) cannot
-     * be modified by execution of the test, and so are passed unchanged
-     * from the caller to the target or fallback as appropriate.
-     * @param test method handle used for test, must return boolean
-     * @param target method handle to call if test passes
-     * @param fallback method handle to call if test fails
-     * @return method handle which incorporates the specified if/then/else logic
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if {@code test} does not return boolean,
-     *          or if all three method types do not match (with the return
-     *          type of {@code test} changed to match that of {@code target}).
-     */
-    public static
-    MethodHandle guardWithTest(MethodHandle test,
-                               MethodHandle target,
-                               MethodHandle fallback) {
-        MethodType gtype = test.type();
-        MethodType ttype = target.type();
-        MethodType ftype = fallback.type();
-        if (!ttype.equals(ftype))
-            throw misMatchedTypes("target and fallback types", ttype, ftype);
-        if (gtype.returnType() != boolean.class)
-            throw newIllegalArgumentException("guard type is not a predicate "+gtype);
-        List<Class<?>> targs = ttype.parameterList();
-        List<Class<?>> gargs = gtype.parameterList();
-        if (!targs.equals(gargs)) {
-            int gpc = gargs.size(), tpc = targs.size();
-            if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
-                throw misMatchedTypes("target and test types", ttype, gtype);
-            test = dropArguments(test, gpc, targs.subList(gpc, tpc));
-            gtype = test.type();
-        }
-        return MethodHandleImpl.makeGuardWithTest(IMPL_TOKEN, test, target, fallback);
-    }
-
-    static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
-        return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
-    }
-
-    /**
-     * Make a method handle which adapts a target method handle,
-     * by running it inside an exception handler.
-     * If the target returns normally, the adapter returns that value.
-     * If an exception matching the specified type is thrown, the fallback
-     * handle is called instead on the exception, plus the original arguments.
-     * <p>
-     * The target and handler must have the same corresponding
-     * argument and return types, except that handler may omit trailing arguments
-     * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
-     * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
-     * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
-     * T target(A..., B...);
-     * T handler(ExType, A...);
-     * T adapter(A... a, B... b) {
-     *   try {
-     *     return target(a..., b...);
-     *   } catch (ExType ex) {
-     *     return handler(ex, a...);
-     *   }
-     * }
-     * </pre></blockquote>
-     * Note that the saved arguments ({@code a...} in the pseudocode) cannot
-     * be modified by execution of the target, and so are passed unchanged
-     * from the caller to the handler, if the handler is invoked.
-     * <p>
-     * The target and handler must return the same type, even if the handler
-     * always throws.  (This might happen, for instance, because the handler
-     * is simulating a {@code finally} clause).
-     * To create such a throwing handler, compose the handler creation logic
-     * with {@link #throwException throwException},
-     * in order to create a method handle of the correct return type.
-     * @param target method handle to call
-     * @param exType the type of exception which the handler will catch
-     * @param handler method handle to call if a matching exception is thrown
-     * @return method handle which incorporates the specified try/catch logic
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if {@code handler} does not accept
-     *          the given exception type, or if the method handle types do
-     *          not match in their return types and their
-     *          corresponding parameters
-     */
-    public static
-    MethodHandle catchException(MethodHandle target,
-                                Class<? extends Throwable> exType,
-                                MethodHandle handler) {
-        MethodType ttype = target.type();
-        MethodType htype = handler.type();
-        if (htype.parameterCount() < 1 ||
-            !htype.parameterType(0).isAssignableFrom(exType))
-            throw newIllegalArgumentException("handler does not accept exception type "+exType);
-        if (htype.returnType() != ttype.returnType())
-            throw misMatchedTypes("target and handler return types", ttype, htype);
-        List<Class<?>> targs = ttype.parameterList();
-        List<Class<?>> hargs = htype.parameterList();
-        hargs = hargs.subList(1, hargs.size());  // omit leading parameter from handler
-        if (!targs.equals(hargs)) {
-            int hpc = hargs.size(), tpc = targs.size();
-            if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
-                throw misMatchedTypes("target and handler types", ttype, htype);
-            handler = dropArguments(handler, hpc, hargs.subList(hpc, tpc));
-            htype = handler.type();
-        }
-        return MethodHandleImpl.makeGuardWithCatch(IMPL_TOKEN, target, exType, handler);
-    }
-
-    /**
-     * Produces a method handle which will throw exceptions of the given {@code exType}.
-     * The method handle will accept a single argument of {@code exType},
-     * and immediately throw it as an exception.
-     * 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.
-     * @return method handle which can throw the given exceptions
-     * @throws NullPointerException if either argument is null
-     */
-    public static
-    MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
-        return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
-    }
-
-    /**
-     * Produces an instance of the given "SAM" interface which redirects
-     * its calls to the given method handle.
-     * <p>
-     * A SAM interface is an interface which declares a single abstract method.
-     * When determining the unique abstract method of a SAM interface,
-     * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
-     * are disregarded.  For example, {@link java.util.Comparator} is a SAM interface,
-     * even though it re-declares the {@code Object.equals} method.
-     * Also, if the SAM interface has a supertype,
-     * the SAM interface may override an inherited method.
-     * Any such overrides are respected, and the method handle will be accessible
-     * by either the inherited method or the SAM method.
-     * In particular, a {@linkplain java.lang.reflect.Method#isBridge bridge method}
-     * may be created if the methods have different return types.
-     * <p>
-     * The type must be public.  No additional access checks are performed.
-     * <p>
-     * The resulting instance of the required SAM type will respond to
-     * invocation of the SAM type's single abstract method by calling
-     * the given {@code target} on the incoming arguments,
-     * and returning or throwing whatever the {@code target}
-     * returns or throws.  The invocation will be as if by
-     * {@code target.invokeGeneric}.
-     * The target's type will be checked before the SAM
-     * instance is created, as if by a call to {@code asType},
-     * which may result in a {@code WrongMethodTypeException}.
-     * <p>
-     * The wrapper instance will implement the requested SAM interface
-     * and its super-types, but no other SAM types.
-     * This means that the SAM instance will not unexpectedly
-     * pass an {@code instanceof} test for any unrequested type.
-     * <p style="font-size:smaller;">
-     * <em>Implementation Note:</em>
-     * Therefore, each SAM instance must implement a unique SAM type.
-     * Implementations may not bundle together
-     * multiple SAM types onto single implementation classes
-     * in the style of {@link java.awt.AWTEventMulticaster}.
-     * <p>
-     * The method handle may throw an <em>undeclared exception</em>,
-     * which means any checked exception (or other checked throwable)
-     * not declared by the SAM type's single abstract method.
-     * If this happens, the throwable will be wrapped in an instance of
-     * {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
-     * and thrown in that wrapped form.
-     * <p>
-     * Like {@link java.lang.Integer#valueOf Integer.valueOf},
-     * {@code asInstance} is a factory method whose results are defined
-     * by their behavior.
-     * It is not guaranteed to return a new instance for every call.
-     * <p>
-     * Future versions of this API may accept additional types,
-     * such as abstract classes with single abstract methods.
-     * Future versions of this API may also equip wrapper instances
-     * with one or more additional public "marker" interfaces.
-     *
-     * @param target the method handle to invoke from the wrapper
-     * @param samType the desired type of the wrapper, a SAM type
-     * @return a correctly-typed wrapper for the given {@code target}
-     * @throws NullPointerException if either argument is null
-     * @throws IllegalArgumentException if the {@code samType} is not a
-     *         valid argument to this method
-     * @throws WrongMethodTypeException if the {@code target} cannot
-     *         be converted to the type required by the SAM type
-     */
-    // Other notes to implementors:
-    // <p>
-    // No stable mapping is promised between the SAM type and
-    // the implementation class C.  Over time, several implementation
-    // classes might be used for the same SAM type.
-    // <p>
-    // If the implementation is able
-    // to prove that a wrapper of the required SAM type
-    // has already been created for a given
-    // method handle, or for another method handle with the
-    // same behavior, the implementation may return that wrapper in place of
-    // a new wrapper.
-    // <p>
-    // This method is designed to apply to common use cases
-    // where a single method handle must interoperate with
-    // an interface that implements a function-like
-    // API.  Additional variations, such as SAM classes with
-    // private constructors, or interfaces with multiple but related
-    // entry points, must be covered by hand-written or automatically
-    // generated adapter classes.
-    //
-    public static
-    <T> T asInstance(final MethodHandle target, final Class<T> samType) {
-        // POC implementation only; violates the above contract several ways
-        final Method sam = getSamMethod(samType);
-        if (sam == null)
-            throw new IllegalArgumentException("not a SAM type: "+samType.getName());
-        MethodType samMT = MethodType.methodType(sam.getReturnType(), sam.getParameterTypes());
-        MethodHandle checkTarget = target.asType(samMT);  // make throw WMT
-        checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
-        final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, samMT.parameterCount());
-        return samType.cast(Proxy.newProxyInstance(
-                samType.getClassLoader(),
-                new Class[]{ samType, WrapperInstance.class },
-                new InvocationHandler() {
-                    private Object getArg(String name) {
-                        if ((Object)name == "getWrapperInstanceTarget")  return target;
-                        if ((Object)name == "getWrapperInstanceType")    return samType;
-                        throw new AssertionError();
-                    }
-                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                        if (method.getDeclaringClass() == WrapperInstance.class)
-                            return getArg(method.getName());
-                        if (method.equals(sam))
-                            return vaTarget.invokeExact(args);
-                        if (isObjectMethod(method))
-                            return callObjectMethod(this, method, args);
-                        throw new InternalError();
-                    }
-                }));
-    }
-
-    /**
-     * Determine if the given object was produced by a call to {@link #asInstance asInstance}.
-     * @param x any reference
-     * @return true if the reference is not null and points to an object produced by {@code asInstance}
-     */
-    public static
-    boolean isWrapperInstance(Object x) {
-        return x instanceof WrapperInstance;
-    }
-
-    private static WrapperInstance asWrapperInstance(Object x) {
-        try {
-            if (x != null)
-                return (WrapperInstance) x;
-        } catch (ClassCastException ex) {
-        }
-        throw new IllegalArgumentException("not a wrapper instance");
-    }
-
-    /**
-     * Produces or recovers a target method handle which is behaviorally
-     * equivalent to the SAM method of this wrapper instance.
-     * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
-     * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
-     * @param x any reference
-     * @return a method handle implementing the SAM method
-     * @throws IllegalArgumentException if the reference x is not to a wrapper instance
-     */
-    public static
-    MethodHandle wrapperInstanceTarget(Object x) {
-        return asWrapperInstance(x).getWrapperInstanceTarget();
-    }
-
-    /**
-     * Recover the SAM type for which this wrapper instance was created.
-     * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
-     * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
-     * @param x any reference
-     * @return the SAM type for which the wrapper was created
-     * @throws IllegalArgumentException if the reference x is not to a wrapper instance
-     */
-    public static
-    Class<?> wrapperInstanceType(Object x) {
-        return asWrapperInstance(x).getWrapperInstanceType();
-    }
-
-    private static
-    boolean isObjectMethod(Method m) {
-        switch (m.getName()) {
-        case "toString":
-            return (m.getReturnType() == String.class
-                    && m.getParameterTypes().length == 0);
-        case "hashCode":
-            return (m.getReturnType() == int.class
-                    && m.getParameterTypes().length == 0);
-        case "equals":
-            return (m.getReturnType() == boolean.class
-                    && m.getParameterTypes().length == 1
-                    && m.getParameterTypes()[0] == Object.class);
-        }
-        return false;
-    }
-
-    private static
-    Object callObjectMethod(Object self, Method m, Object[] args) {
-        assert(isObjectMethod(m)) : m;
-        switch (m.getName()) {
-        case "toString":
-            return self.getClass().getName() + "@" + Integer.toHexString(self.hashCode());
-        case "hashCode":
-            return System.identityHashCode(self);
-        case "equals":
-            return (self == args[0]);
-        }
-        return null;
-    }
-
-    private static
-    Method getSamMethod(Class<?> samType) {
-        Method sam = null;
-        for (Method m : samType.getMethods()) {
-            int mod = m.getModifiers();
-            if (Modifier.isAbstract(mod)) {
-                if (sam != null && !isObjectMethod(sam))
-                    return null;  // too many abstract methods
-                sam = m;
-            }
-        }
-        if (!samType.isInterface() && getSamConstructor(samType) == null)
-            return null;  // wrong kind of constructor
-        return sam;
-    }
-
-    private static
-    Constructor getSamConstructor(Class<?> samType) {
-        for (Constructor c : samType.getDeclaredConstructors()) {
-            if (c.getParameterTypes().length == 0) {
-                int mod = c.getModifiers();
-                if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
-                    return c;
-            }
-        }
-        return null;
-    }
-
-    /*non-public*/
-    static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) {
-        return MethodHandleImpl.asVarargsCollector(IMPL_TOKEN, target, arrayType);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/MethodType.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,865 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.dyn;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import sun.dyn.Access;
-import sun.dyn.Invokers;
-import sun.dyn.MethodHandleImpl;
-import sun.dyn.MethodTypeImpl;
-import sun.dyn.util.BytecodeDescriptor;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * A method type represents the arguments and return type accepted and
- * returned by a method handle, or the arguments and return type passed
- * and expected  by a method handle caller.  Method types must be properly
- * matched between a method handle and all its callers,
- * and the JVM's operations enforce this matching at, specifically
- * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
- * and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution
- * of {@code invokedynamic} instructions.
- * <p>
- * The structure is a return type accompanied by any number of parameter types.
- * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
- * (For ease of exposition, we treat {@code void} as if it were a type.
- * In fact, it denotes the absence of a return type.)
- * <p>
- * All instances of {@code MethodType} are immutable.
- * Two instances are completely interchangeable if they compare equal.
- * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
- * <p>
- * This type can be created only by factory methods.
- * All factory methods may cache values, though caching is not guaranteed.
- * Some factory methods are static, while others are virtual methods which
- * modify precursor method types, e.g., by changing a selected parameter.
- * <p>
- * Factory methods which operate on groups of parameter types
- * are systematically presented in two versions, so that both Java arrays and
- * Java lists can be used to work with groups of parameter types.
- * The query methods {@code parameterArray} and {@code parameterList}
- * also provide a choice between arrays and lists.
- * <p>
- * {@code MethodType} objects are sometimes derived from bytecode instructions
- * such as {@code invokedynamic}, specifically from the type descriptor strings associated
- * with the instructions in a class file's constant pool.
- * <p>
- * Like classes and strings, method types can also be represented directly
- * in a class file's constant pool as constants.
- * A method type may be loaded by an {@code ldc} instruction which refers
- * to a suitable {@code CONSTANT_MethodType} constant pool entry.
- * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
- * For more details, see the <a href="package-summary.html#mtcon">package summary</a>.
- * <p>
- * When the JVM materializes a {@code MethodType} from a descriptor string,
- * all classes named in the descriptor must be accessible, and will be loaded.
- * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
- * This loading may occur at any time before the {@code MethodType} object is first derived.
- * @author John Rose, JSR 292 EG
- */
-public final
-class MethodType implements java.io.Serializable {
-    private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
-
-    // The rtype and ptypes fields define the structural identity of the method type:
-    private final Class<?>   rtype;
-    private final Class<?>[] ptypes;
-
-    // The remaining fields are caches of various sorts:
-    private MethodTypeForm form; // erased form, plus cached data about primitives
-    private MethodType wrapAlt;  // alternative wrapped/unwrapped version
-    private Invokers invokers;   // cache of handy higher-order adapters
-
-    private static final Access IMPL_TOKEN = Access.getToken();
-
-    // share a cache with a friend in this package
-    Invokers getInvokers() { return invokers; }
-    void setInvokers(Invokers inv) { invokers = inv; }
-
-    static {
-        // This hack allows the implementation package special access to
-        // the internals of MethodType.  In particular, the MTImpl has all sorts
-        // of cached information useful to the implementation code.
-        MethodTypeImpl.setMethodTypeFriend(IMPL_TOKEN, new MethodTypeImpl.MethodTypeFriend() {
-            public Class<?>[] ptypes(MethodType mt)        { return mt.ptypes; }
-            public MethodTypeImpl form(MethodType mt)      { return mt.form; }
-            public void setForm(MethodType mt, MethodTypeImpl form) {
-                assert(mt.form == null);
-                mt.form = (MethodTypeForm) form;
-            }
-            public MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
-                return MethodType.makeImpl(rtype, ptypes, trusted);
-            }
-            public MethodTypeImpl newMethodTypeForm(MethodType mt) {
-                return new MethodTypeForm(mt);
-            }
-            public Invokers getInvokers(MethodType mt)    { return mt.invokers; }
-            public void setInvokers(MethodType mt, Invokers inv) { mt.invokers = inv; }
-        });
-    }
-
-    /**
-     * Check the given parameters for validity and store them into the final fields.
-     */
-    private MethodType(Class<?> rtype, Class<?>[] ptypes) {
-        checkRtype(rtype);
-        checkPtypes(ptypes);
-        this.rtype = rtype;
-        this.ptypes = ptypes;
-    }
-
-    private static void checkRtype(Class<?> rtype) {
-        rtype.equals(rtype);  // null check
-    }
-    private static int checkPtype(Class<?> ptype) {
-        ptype.getClass();  //NPE
-        if (ptype == void.class)
-            throw newIllegalArgumentException("parameter type cannot be void");
-        if (ptype == double.class || ptype == long.class)  return 1;
-        return 0;
-    }
-    /** Return number of extra slots (count of long/double args). */
-    private static int checkPtypes(Class<?>[] ptypes) {
-        int slots = 0;
-        for (Class<?> ptype : ptypes) {
-            slots += checkPtype(ptype);
-        }
-        checkSlotCount(ptypes.length + slots);
-        return slots;
-    }
-    private static void checkSlotCount(int count) {
-        if ((count & 0xFF) != count)
-            throw newIllegalArgumentException("bad parameter count "+count);
-    }
-    private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
-        if (num instanceof Integer)  num = "bad index: "+num;
-        return new IndexOutOfBoundsException(num.toString());
-    }
-
-    static final HashMap<MethodType,MethodType> internTable
-            = new HashMap<MethodType, MethodType>();
-
-    static final Class<?>[] NO_PTYPES = {};
-
-    /**
-     * Find or create an instance of the given method type.
-     * @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}
-     */
-    public static
-    MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
-        return makeImpl(rtype, ptypes, false);
-    }
-
-    /**
-     * Finds or creates a method type with the given components.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @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}
-     */
-    public static
-    MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
-        boolean notrust = false;  // random List impl. could return evil ptypes array
-        return makeImpl(rtype, ptypes.toArray(NO_PTYPES), notrust);
-    }
-
-    /**
-     * 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.
-     * @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}
-     */
-    public static
-    MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
-        Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
-        ptypes1[0] = ptype0;
-        System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
-        return makeImpl(rtype, ptypes1, true);
-    }
-
-    /**
-     * 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.
-     * @return a method type with the given return value
-     * @throws NullPointerException if {@code rtype} is null
-     */
-    public static
-    MethodType methodType(Class<?> rtype) {
-        return makeImpl(rtype, NO_PTYPES, true);
-    }
-
-    /**
-     * 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.
-     * @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}
-     */
-    public static
-    MethodType methodType(Class<?> rtype, Class<?> ptype0) {
-        return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
-    }
-
-    /**
-     * 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 same parameter types as {@code ptypes},
-     * and the specified return type.
-     * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
-     */
-    public static
-    MethodType methodType(Class<?> rtype, MethodType ptypes) {
-        return makeImpl(rtype, ptypes.ptypes, true);
-    }
-
-    /**
-     * Sole factory method to find or create an interned method type.
-     * @param rtype desired return type
-     * @param ptypes desired parameter types
-     * @param trusted whether the ptypes can be used without cloning
-     * @return the unique method type of the desired structure
-     */
-    private static
-    MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
-        if (ptypes == null || ptypes.length == 0) {
-            ptypes = NO_PTYPES; trusted = true;
-        }
-        MethodType mt1 = new MethodType(rtype, ptypes);
-        MethodType mt0;
-        synchronized (internTable) {
-            mt0 = internTable.get(mt1);
-            if (mt0 != null)
-                return mt0;
-        }
-        if (!trusted)
-            // defensively copy the array passed in by the user
-            mt1 = new MethodType(rtype, ptypes.clone());
-        // promote the object to the Real Thing, and reprobe
-        MethodTypeImpl.initForm(IMPL_TOKEN, mt1);
-        synchronized (internTable) {
-            mt0 = internTable.get(mt1);
-            if (mt0 != null)
-                return mt0;
-            internTable.put(mt1, mt1);
-        }
-        return mt1;
-    }
-
-    // Entry point from JVM.  TODO: Change the name & signature.
-    private static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes,
-            boolean ignore1, boolean ignore2) {
-        return makeImpl(rtype, ptypes, true);
-    }
-
-    private static final MethodType[] objectOnlyTypes = new MethodType[20];
-
-    /**
-     * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * All parameters and the return type will be {@code Object},
-     * except the final varargs parameter if any, which will be {@code Object[]}.
-     * @param objectArgCount number of parameters (excluding the varargs parameter if any)
-     * @param varargs whether there will be a varargs parameter, of type {@code Object[]}
-     * @return a totally generic method type, given only its count of parameters and varargs
-     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
-     * @see #genericMethodType(int)
-     */
-    public static
-    MethodType genericMethodType(int objectArgCount, boolean varargs) {
-        MethodType mt;
-        checkSlotCount(objectArgCount);
-        int ivarargs = (!varargs ? 0 : 1);
-        int ootIndex = objectArgCount*2 + ivarargs;
-        if (ootIndex < objectOnlyTypes.length) {
-            mt = objectOnlyTypes[ootIndex];
-            if (mt != null)  return mt;
-        }
-        Class<?>[] ptypes = new Class<?>[objectArgCount + ivarargs];
-        Arrays.fill(ptypes, Object.class);
-        if (ivarargs != 0)  ptypes[objectArgCount] = Object[].class;
-        mt = makeImpl(Object.class, ptypes, true);
-        if (ootIndex < objectOnlyTypes.length) {
-            objectOnlyTypes[ootIndex] = mt;     // cache it here also!
-        }
-        return mt;
-    }
-
-    /**
-     * Finds or creates a method type whose components are all {@code Object}.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * All parameters and the return type will be Object.
-     * @param objectArgCount number of parameters
-     * @return a totally generic method type, given only its count of parameters
-     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
-     * @see #genericMethodType(int, boolean)
-     */
-    public static
-    MethodType genericMethodType(int objectArgCount) {
-        return genericMethodType(objectArgCount, false);
-    }
-
-    /**
-     * Finds or creates a method type with a single different parameter type.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param num    the index (zero-based) of the parameter type to change
-     * @param nptype a new parameter type to replace the old one with
-     * @return the same type, except with the selected parameter changed
-     * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
-     * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
-     * @throws NullPointerException if {@code nptype} is null
-     */
-    public MethodType changeParameterType(int num, Class<?> nptype) {
-        if (parameterType(num) == nptype)  return this;
-        checkPtype(nptype);
-        Class<?>[] nptypes = ptypes.clone();
-        nptypes[num] = nptype;
-        return makeImpl(rtype, nptypes, true);
-    }
-
-    /**
-     * Finds or creates a method type with additional parameter types.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param num    the position (zero-based) of the inserted parameter type(s)
-     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
-     * @return the same type, except with the selected parameter(s) inserted
-     * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
-     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
-     *                                  or if the resulting method type would have more than 255 parameter slots
-     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
-     */
-    public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
-        int len = ptypes.length;
-        if (num < 0 || num > len)
-            throw newIndexOutOfBoundsException(num);
-        int ins = checkPtypes(ptypesToInsert);
-        checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
-        int ilen = ptypesToInsert.length;
-        if (ilen == 0)  return this;
-        Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
-        System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
-        System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
-        return makeImpl(rtype, nptypes, true);
-    }
-
-    /**
-     * Finds or creates a method type with additional parameter types.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
-     * @return the same type, except with the selected parameter(s) appended
-     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
-     *                                  or if the resulting method type would have more than 255 parameter slots
-     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
-     */
-    public MethodType appendParameterTypes(Class<?>... ptypesToInsert) {
-        return insertParameterTypes(parameterCount(), ptypesToInsert);
-    }
-
-    /**
-     * Finds or creates a method type with additional parameter types.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param num    the position (zero-based) of the inserted parameter type(s)
-     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
-     * @return the same type, except with the selected parameter(s) inserted
-     * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
-     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
-     *                                  or if the resulting method type would have more than 255 parameter slots
-     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
-     */
-    public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
-        return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
-    }
-
-    /**
-     * Finds or creates a method type with additional parameter types.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
-     * @return the same type, except with the selected parameter(s) appended
-     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
-     *                                  or if the resulting method type would have more than 255 parameter slots
-     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
-     */
-    public MethodType appendParameterTypes(List<Class<?>> ptypesToInsert) {
-        return insertParameterTypes(parameterCount(), ptypesToInsert);
-    }
-
-    /**
-     * Finds or creates a method type with some parameter types omitted.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param start  the index (zero-based) of the first parameter type to remove
-     * @param end    the index (greater than {@code start}) of the first parameter type after not to remove
-     * @return the same type, except with the selected parameter(s) removed
-     * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
-     *                                  or if {@code end} is negative or greater than {@code parameterCount()}
-     *                                  or if {@code start} is greater than {@code end}
-     */
-    public MethodType dropParameterTypes(int start, int end) {
-        int len = ptypes.length;
-        if (!(0 <= start && start <= end && end <= len))
-            throw newIndexOutOfBoundsException("start="+start+" end="+end);
-        if (start == end)  return this;
-        Class<?>[] nptypes;
-        if (start == 0) {
-            if (end == len) {
-                // drop all parameters
-                nptypes = NO_PTYPES;
-            } else {
-                // drop initial parameter(s)
-                nptypes = Arrays.copyOfRange(ptypes, end, len);
-            }
-        } else {
-            if (end == len) {
-                // drop trailing parameter(s)
-                nptypes = Arrays.copyOfRange(ptypes, 0, start);
-            } else {
-                int tail = len - end;
-                nptypes = Arrays.copyOfRange(ptypes, 0, start + tail);
-                System.arraycopy(ptypes, end, nptypes, start, tail);
-            }
-        }
-        return makeImpl(rtype, nptypes, true);
-    }
-
-    /**
-     * Finds or creates a method type with a different return type.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * @param nrtype a return parameter type to replace the old one with
-     * @return the same type, except with the return type change
-     * @throws NullPointerException if {@code nrtype} is null
-     */
-    public MethodType changeReturnType(Class<?> nrtype) {
-        if (returnType() == nrtype)  return this;
-        return makeImpl(nrtype, ptypes, true);
-    }
-
-    /**
-     * Reports if this type contains a primitive argument or return value.
-     * The return type {@code void} counts as a primitive.
-     * @return true if any of the types are primitives
-     */
-    public boolean hasPrimitives() {
-        return form.hasPrimitives();
-    }
-
-    /**
-     * Reports if this type contains a wrapper argument or return value.
-     * Wrappers are types which box primitive values, such as {@link Integer}.
-     * The reference type {@code java.lang.Void} counts as a wrapper.
-     * @return true if any of the types are wrappers
-     */
-    public boolean hasWrappers() {
-        return unwrap() != this;
-    }
-
-    /**
-     * Erases all reference types to {@code Object}.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * All primitive types (including {@code void}) will remain unchanged.
-     * @return a version of the original type with all reference types replaced
-     */
-    public MethodType erase() {
-        return form.erasedType();
-    }
-
-    /**
-     * Converts all types, both reference and primitive, to {@code Object}.
-     * Convenience method for {@link #genericMethodType(int) genericMethodType}.
-     * The expression {@code type.wrap().erase()} produces the same value
-     * as {@code type.generic()}.
-     * @return a version of the original type with all types replaced
-     */
-    public MethodType generic() {
-        return genericMethodType(parameterCount());
-    }
-
-    /**
-     * Converts all primitive types to their corresponding wrapper types.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * All reference types (including wrapper types) will remain unchanged.
-     * A {@code void} return type is changed to the type {@code java.lang.Void}.
-     * The expression {@code type.wrap().erase()} produces the same value
-     * as {@code type.generic()}.
-     * @return a version of the original type with all primitive types replaced
-     */
-    public MethodType wrap() {
-        return hasPrimitives() ? wrapWithPrims(this) : this;
-    }
-
-    /**
-     * Convert all wrapper types to their corresponding primitive types.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * All primitive types (including {@code void}) will remain unchanged.
-     * A return type of {@code java.lang.Void} is changed to {@code void}.
-     * @return a version of the original type with all wrapper types replaced
-     */
-    public MethodType unwrap() {
-        MethodType noprims = !hasPrimitives() ? this : wrapWithPrims(this);
-        return unwrapWithNoPrims(noprims);
-    }
-
-    private static MethodType wrapWithPrims(MethodType pt) {
-        assert(pt.hasPrimitives());
-        MethodType wt = pt.wrapAlt;
-        if (wt == null) {
-            // fill in lazily
-            wt = MethodTypeImpl.canonicalize(pt, MethodTypeImpl.WRAP, MethodTypeImpl.WRAP);
-            assert(wt != null);
-            pt.wrapAlt = wt;
-        }
-        return wt;
-    }
-
-    private static MethodType unwrapWithNoPrims(MethodType wt) {
-        assert(!wt.hasPrimitives());
-        MethodType uwt = wt.wrapAlt;
-        if (uwt == null) {
-            // fill in lazily
-            uwt = MethodTypeImpl.canonicalize(wt, MethodTypeImpl.UNWRAP, MethodTypeImpl.UNWRAP);
-            if (uwt == null)
-                uwt = wt;    // type has no wrappers or prims at all
-            wt.wrapAlt = uwt;
-        }
-        return uwt;
-    }
-
-    /**
-     * Returns the parameter type at the specified index, within this method type.
-     * @param num the index (zero-based) of the desired parameter type
-     * @return the selected parameter type
-     * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
-     */
-    public Class<?> parameterType(int num) {
-        return ptypes[num];
-    }
-    /**
-     * Returns the number of parameter types in this method type.
-     * @return the number of parameter types
-     */
-    public int parameterCount() {
-        return ptypes.length;
-    }
-    /**
-     * Returns the return type of this method type.
-     * @return the return type
-     */
-    public Class<?> returnType() {
-        return rtype;
-    }
-
-    /**
-     * Presents the parameter types as a list (a convenience method).
-     * The list will be immutable.
-     * @return the parameter types (as an immutable list)
-     */
-    public List<Class<?>> parameterList() {
-        return Collections.unmodifiableList(Arrays.asList(ptypes));
-    }
-
-    /**
-     * Presents the parameter types as an array (a convenience method).
-     * Changes to the array will not result in changes to the type.
-     * @return the parameter types (as a fresh copy if necessary)
-     */
-    public Class<?>[] parameterArray() {
-        return ptypes.clone();
-    }
-
-    /**
-     * Compares the specified object with this type for equality.
-     * That is, it returns <tt>true</tt> if and only if the specified object
-     * is also a method type with exactly the same parameters and return type.
-     * @param x object to compare
-     * @see Object#equals(Object)
-     */
-    @Override
-    public boolean equals(Object x) {
-        return this == x || x instanceof MethodType && equals((MethodType)x);
-    }
-
-    private boolean equals(MethodType that) {
-        return this.rtype == that.rtype
-            && Arrays.equals(this.ptypes, that.ptypes);
-    }
-
-    /**
-     * Returns the hash code value for this method type.
-     * It is defined to be the same as the hashcode of a List
-     * whose elements are the return type followed by the
-     * parameter types.
-     * @return the hash code value for this method type
-     * @see Object#hashCode()
-     * @see #equals(Object)
-     * @see List#hashCode()
-     */
-    @Override
-    public int hashCode() {
-      int hashCode = 31 + rtype.hashCode();
-      for (Class<?> ptype : ptypes)
-          hashCode = 31*hashCode + ptype.hashCode();
-      return hashCode;
-    }
-
-    /**
-     * Returns a string representation of the method type,
-     * of the form {@code "(PT0,PT1...)RT"}.
-     * The string representation of a method type is a
-     * parenthesis enclosed, comma separated list of type names,
-     * followed immediately by the return type.
-     * <p>
-     * Each type is represented by its
-     * {@link java.lang.Class#getSimpleName simple name}.
-     */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("(");
-        for (int i = 0; i < ptypes.length; i++) {
-            if (i > 0)  sb.append(",");
-            sb.append(ptypes[i].getSimpleName());
-        }
-        sb.append(")");
-        sb.append(rtype.getSimpleName());
-        return sb.toString();
-    }
-
-    /// Queries which have to do with the bytecode architecture
-
-    /** Reports the number of JVM stack slots required to invoke a method
-     * of this type.  Note that (for historic reasons) the JVM requires
-     * a second stack slot to pass long and double arguments.
-     * So this method returns {@link #parameterCount() parameterCount} plus the
-     * number of long and double parameters (if any).
-     * <p>
-     * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and invokedynamic.
-     * @return the number of JVM stack slots for this type's parameters
-     * @deprecated Will be removed for PFD.
-     */
-    public int parameterSlotCount() {
-        return form.parameterSlotCount();
-    }
-
-    /** Reports the number of JVM stack slots which carry all parameters including and after
-     * the given position, which must be in the range of 0 to
-     * {@code parameterCount} inclusive.  Successive parameters are
-     * more shallowly stacked, and parameters are indexed in the bytecodes
-     * according to their trailing edge.  Thus, to obtain the depth
-     * in the outgoing call stack of parameter {@code N}, obtain
-     * the {@code parameterSlotDepth} of its trailing edge
-     * at position {@code N+1}.
-     * <p>
-     * Parameters of type {@code long} and {@code double} occupy
-     * two stack slots (for historical reasons) and all others occupy one.
-     * Therefore, the number returned is the number of arguments
-     * <em>including</em> and <em>after</em> the given parameter,
-     * <em>plus</em> the number of long or double arguments
-     * at or after after the argument for the given parameter.
-     * <p>
-     * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and invokedynamic.
-     * @param num an index (zero-based, inclusive) within the parameter types
-     * @return the index of the (shallowest) JVM stack slot transmitting the
-     *         given parameter
-     * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
-     * @deprecated Will be removed for PFD.
-     */
-    public int parameterSlotDepth(int num) {
-        if (num < 0 || num > ptypes.length)
-            parameterType(num);  // force a range check
-        return form.parameterToArgSlot(num-1);
-    }
-
-    /** Reports the number of JVM stack slots required to receive a return value
-     * from a method of this type.
-     * If the {@link #returnType() return type} is void, it will be zero,
-     * else if the return type is long or double, it will be two, else one.
-     * <p>
-     * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and invokedynamic.
-     * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
-     * @deprecated Will be removed for PFD.
-     */
-    public int returnSlotCount() {
-        return form.returnSlotCount();
-    }
-
-    /**
-     * Find or create an instance of a method type, given the spelling of its bytecode descriptor.
-     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
-     * Any class or interface name embedded in the descriptor string
-     * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
-     * on the given loader (or if it is null, on the system class loader).
-     * <p>
-     * Note that it is possible to encounter method types which cannot be
-     * constructed by this method, because their component types are
-     * not all reachable from a common class loader.
-     * <p>
-     * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and {@code invokedynamic}.
-     * @param descriptor a bytecode-level type descriptor string "(T...)T"
-     * @param loader the class loader in which to look up the types
-     * @return a method type matching the bytecode-level type descriptor
-     * @throws IllegalArgumentException if the string is not well-formed
-     * @throws TypeNotPresentException if a named type cannot be found
-     */
-    public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
-        throws IllegalArgumentException, TypeNotPresentException
-    {
-        List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
-        Class<?> rtype = types.remove(types.size() - 1);
-        Class<?>[] ptypes = types.toArray(NO_PTYPES);
-        return makeImpl(rtype, ptypes, true);
-    }
-
-    /**
-     * Produces a bytecode descriptor representation of the method type.
-     * <p>
-     * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
-     * Two distinct classes which share a common name but have different class loaders
-     * will appear identical when viewed within descriptor strings.
-     * <p>
-     * This method is included for the benfit of applications that must
-     * generate bytecodes that process method handles and {@code invokedynamic}.
-     * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
-     * because the latter requires a suitable class loader argument.
-     * @return the bytecode type descriptor representation
-     */
-    public String toMethodDescriptorString() {
-        return BytecodeDescriptor.unparse(this);
-    }
-
-    /// Serialization.
-
-    /**
-     * There are no serializable fields for {@code MethodType}.
-     */
-    private static final java.io.ObjectStreamField[] serialPersistentFields = { };
-
-    /**
-     * Save the {@code MethodType} instance to a stream.
-     *
-     * @serialData
-     * For portability, the serialized format does not refer to named fields.
-     * Instead, the return type and parameter type arrays are written directly
-     * from the {@code writeObject} method, using two calls to {@code s.writeObject}
-     * as follows:
-     * <blockquote><pre>
-s.writeObject(this.returnType());
-s.writeObject(this.parameterArray());
-     * </pre></blockquote>
-     * <p>
-     * The deserialized field values are checked as if they were
-     * 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
-     */
-    private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-        s.defaultWriteObject();  // requires serialPersistentFields to be an empty array
-        s.writeObject(returnType());
-        s.writeObject(parameterArray());
-    }
-
-    /**
-     * Reconstitute the {@code MethodType} instance from a stream (that is,
-     * deserialize it).
-     * This instance is a scratch object with bogus final fields.
-     * 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
-     * @see #MethodType()
-     * @see #readResolve
-     * @see #writeObject
-     */
-    private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
-        s.defaultReadObject();  // requires serialPersistentFields to be an empty array
-
-        Class<?>   returnType     = (Class<?>)   s.readObject();
-        Class<?>[] parameterArray = (Class<?>[]) s.readObject();
-
-        // Probably this object will never escape, but let's check
-        // the field values now, just to be sure.
-        checkRtype(returnType);
-        checkPtypes(parameterArray);
-
-        parameterArray = parameterArray.clone();  // make sure it is unshared
-        MethodType_init(returnType, parameterArray);
-    }
-
-    /**
-     * For serialization only.
-     * Sets the final fields to null, pending {@code Unsafe.putObject}.
-     */
-    private MethodType() {
-        this.rtype = null;
-        this.ptypes = null;
-    }
-    private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
-        // In order to communicate these values to readResolve, we must
-        // store them into the implementation-specific final fields.
-        checkRtype(rtype);
-        checkPtypes(ptypes);
-        unsafe.putObject(this, rtypeOffset, rtype);
-        unsafe.putObject(this, ptypesOffset, ptypes);
-    }
-
-    // Support for resetting final fields while deserializing
-    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
-    private static final long rtypeOffset, ptypesOffset;
-    static {
-        try {
-            rtypeOffset = unsafe.objectFieldOffset
-                (MethodType.class.getDeclaredField("rtype"));
-            ptypesOffset = unsafe.objectFieldOffset
-                (MethodType.class.getDeclaredField("ptypes"));
-        } catch (Exception ex) {
-            throw new Error(ex);
-        }
-    }
-
-    /**
-     * Resolves and initializes a {@code MethodType} object
-     * after serialization.
-     * @return the fully initialized {@code MethodType} object
-     */
-    private Object readResolve() {
-        // Do not use a trusted path for deserialization:
-        //return makeImpl(rtype, ptypes, true);
-        // Verify all operands, and make sure ptypes is unshared:
-        return methodType(rtype, ptypes);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/MethodTypeForm.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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.dyn;
-
-/**
- * TO DO:  Temporary shim; remove after refactoring effects are complete in JVM.
- * @author John Rose
- */
-import sun.dyn.MethodTypeImpl;
-
-class MethodTypeForm extends MethodTypeImpl {
-
-    MethodTypeForm(MethodType erasedType) {
-        super(erasedType);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/MutableCallSite.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.dyn;
-
-import sun.dyn.*;
-import sun.dyn.empty.Empty;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * A {@code MutableCallSite} is a {@link CallSite} whose target variable
- * behaves like an ordinary field.
- * An {@code invokedynamic} instruction linked to a {@code MutableCallSite} delegates
- * all calls to the site's current target.
- * The {@linkplain CallSite#dynamicInvoker dynamic invoker} of a mutable call site
- * also delegates each call to the site's current target.
- * <p>
- * Here is an example of a mutable call site which introduces a
- * state variable into a method handle chain.
- * <blockquote><pre>
-MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
-MethodHandle MH_name = name.dynamicInvoker();
-MethodType MT_str2 = MethodType.methodType(String.class, String.class);
-MethodHandle MH_upcase = MethodHandles.lookup()
-    .findVirtual(String.class, "toUpperCase", MT_str2);
-MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
-name.setTarget(MethodHandles.constant(String.class, "Rocky"));
-assertEquals("ROCKY", (String) worker1.invokeExact());
-name.setTarget(MethodHandles.constant(String.class, "Fred"));
-assertEquals("FRED", (String) worker1.invokeExact());
-// (mutation can be continued indefinitely)
- * </pre></blockquote>
- * <p>
- * The same call site may be used in several places at once.
- * <blockquote><pre>
-MethodHandle MH_dear = MethodHandles.lookup()
-    .findVirtual(String.class, "concat", MT_str2).bindTo(", dear?");
-MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
-assertEquals("Fred, dear?", (String) worker2.invokeExact());
-name.setTarget(MethodHandles.constant(String.class, "Wilma"));
-assertEquals("WILMA", (String) worker1.invokeExact());
-assertEquals("Wilma, dear?", (String) worker2.invokeExact());
- * </pre></blockquote>
- * <p>
- * <em>Non-synchronization of target values:</em>
- * A write to a mutable call site's target does not force other threads
- * to become aware of the updated value.  Threads which do not perform
- * suitable synchronization actions relative to the updated call site
- * may cache the old target value and delay their use of the new target
- * value indefinitely.
- * (This is a normal consequence of the Java Memory Model as applied
- * to object fields.)
- * <p>
- * The {@link #syncAll syncAll} operation provides a way to force threads
- * to accept a new target value, even if there is no other synchronization.
- * <p>
- * For target values which will be frequently updated, consider using
- * a {@linkplain VolatileCallSite volatile call site} instead.
- * @author John Rose, JSR 292 EG
- */
-public class MutableCallSite extends CallSite {
-    /**
-     * Creates a blank call site object with the given method type.
-     * The initial target is set to a method handle of the given type
-     * which will throw an {@link IllegalStateException} if called.
-     * <p>
-     * The type of the call site is permanently set to the given type.
-     * <p>
-     * Before this {@code CallSite} object is returned from a bootstrap method,
-     * or invoked in some other manner,
-     * it is usually provided with a more useful target method,
-     * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
-     * @param type the method type that this call site will have
-     * @throws NullPointerException if the proposed type is null
-     */
-    public MutableCallSite(MethodType type) {
-        super(type);
-    }
-
-    /**
-     * Creates a call site object with an initial target method handle.
-     * The type of the call site is permanently set to the initial target's type.
-     * @param target the method handle that will be the initial target of the call site
-     * @throws NullPointerException if the proposed target is null
-     */
-    public MutableCallSite(MethodHandle target) {
-        super(target);
-    }
-
-    /**
-     * Returns the target method of the call site, which behaves
-     * like a normal field of the {@code MutableCallSite}.
-     * <p>
-     * The interactions of {@code getTarget} with memory are the same
-     * as of a read from an ordinary variable, such as an array element or a
-     * non-volatile, non-final field.
-     * <p>
-     * In particular, the current thread may choose to reuse the result
-     * of a previous read of the target from memory, and may fail to see
-     * a recent update to the target by another thread.
-     *
-     * @return the linkage state of this call site, a method handle which can change over time
-     * @see #setTarget
-     */
-    @Override public final MethodHandle getTarget() {
-        return target;
-    }
-
-    /**
-     * Updates the target method of this call site, as a normal variable.
-     * The type of the new target must agree with the type of the old target.
-     * <p>
-     * The interactions with memory are the same
-     * as of a write to an ordinary variable, such as an array element or a
-     * non-volatile, non-final field.
-     * <p>
-     * In particular, unrelated threads may fail to see the updated target
-     * until they perform a read from memory.
-     * Stronger guarantees can be created by putting appropriate operations
-     * into the bootstrap method and/or the target methods used
-     * at any given call site.
-     *
-     * @param newTarget the new target
-     * @throws NullPointerException if the proposed new target is null
-     * @throws WrongMethodTypeException if the proposed new target
-     *         has a method type that differs from the previous target
-     * @see #getTarget
-     */
-    @Override public void setTarget(MethodHandle newTarget) {
-        checkTargetChange(this.target, newTarget);
-        setTargetNormal(newTarget);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final MethodHandle dynamicInvoker() {
-        return makeDynamicInvoker();
-    }
-
-    /**
-     * Performs a synchronization operation on each call site in the given array,
-     * forcing all other threads to throw away any cached values previously
-     * loaded from the target of any of the call sites.
-     * <p>
-     * This operation does not reverse any calls that have already started
-     * on an old target value.
-     * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
-     * <p>
-     * The overall effect is to force all future readers of each call site's target
-     * to accept the most recently stored value.
-     * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
-     * Conversely, the {@code syncAll} call may block until all readers have
-     * (somehow) decached all previous versions of each call site's target.
-     * <p>
-     * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
-     * should generally be performed under some sort of mutual exclusion.
-     * Note that reader threads may observe an updated target as early
-     * as the {@code setTarget} call that install the value
-     * (and before the {@code syncAll} that confirms the value).
-     * On the other hand, reader threads may observe previous versions of
-     * the target until the {@code syncAll} call returns
-     * (and after the {@code setTarget} that attempts to convey the updated version).
-     * <p>
-     * This operation is likely to be expensive and should be used sparingly.
-     * If possible, it should be buffered for batch processing on sets of call sites.
-     * <p>
-     * If {@code sites} contains a null element,
-     * a {@code NullPointerException} will be raised.
-     * In this case, some non-null elements in the array may be
-     * processed before the method returns abnormally.
-     * Which elements these are (if any) is implementation-dependent.
-     *
-     * <h3>Java Memory Model details</h3>
-     * 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
-     * that may access one of the affected call sites.
-     * <p>
-     * The following effects are apparent, for each individual call site {@code S}:
-     * <ul>
-     * <li>A new volatile variable {@code V} is created, and written by the current thread.
-     *     As defined by the JMM, this write is a global synchronization event.
-     * <li>As is normal with thread-local ordering of write events,
-     *     every action already performed by the current thread is
-     *     taken to happen before the volatile write to {@code V}.
-     *     (In some implementations, this means that the current thread
-     *     performs a global release operation.)
-     * <li>Specifically, the write to the current target of {@code S} is
-     *     taken to happen before the volatile write to {@code V}.
-     * <li>The volatile write to {@code V} is placed
-     *     (in an implementation specific manner)
-     *     in the global synchronization order.
-     * <li>Consider an arbitrary thread {@code T} (other than the current thread).
-     *     If {@code T} executes a synchronization action {@code A}
-     *     after the volatile write to {@code V} (in the global synchronization order),
-     *     it is therefore required to see either the current target
-     *     of {@code S}, or a later write to that target,
-     *     if it executes a read on the target of {@code S}.
-     *     (This constraint is called "synchronization-order consistency".)
-     * <li>The JMM specifically allows optimizing compilers to elide
-     *     reads or writes of variables that are known to be useless.
-     *     Such elided reads and writes have no effect on the happens-before
-     *     relation.  Regardless of this fact, the volatile {@code V}
-     *     will not be elided, even though its written value is
-     *     indeterminate and its read value is not used.
-     * </ul>
-     * Because of the last point, the implementation behaves as if a
-     * volatile read of {@code V} were performed by {@code T}
-     * immediately after its action {@code A}.  In the local ordering
-     * of actions in {@code T}, this read happens before any future
-     * read of the target of {@code S}.  It is as if the
-     * implementation arbitrarily picked a read of {@code S}'s target
-     * by {@code T}, and forced a read of {@code V} to precede it,
-     * thereby ensuring communication of the new target value.
-     * <p>
-     * As long as the constraints of the Java Memory Model are obeyed,
-     * implementations may delay the completion of a {@code syncAll}
-     * operation while other threads ({@code T} above) continue to
-     * use previous values of {@code S}'s target.
-     * However, implementations are (as always) encouraged to avoid
-     * livelock, and to eventually require all threads to take account
-     * of the updated target.
-     *
-     * <p style="font-size:smaller;">
-     * <em>Discussion:</em>
-     * For performance reasons, {@code syncAll} is not a virtual method
-     * on a single call site, but rather applies to a set of call sites.
-     * Some implementations may incur a large fixed overhead cost
-     * for processing one or more synchronization operations,
-     * but a small incremental cost for each additional call site.
-     * In any case, this operation is likely to be costly, since
-     * other threads may have to be somehow interrupted
-     * in order to make them notice the updated target value.
-     * However, it may be observed that a single call to synchronize
-     * several sites has the same formal effect as many calls,
-     * each on just one of the sites.
-     *
-     * <p style="font-size:smaller;">
-     * <em>Implementation Note:</em>
-     * Simple implementations of {@code MutableCallSite} may use
-     * a volatile variable for the target of a mutable call site.
-     * In such an implementation, the {@code syncAll} method can be a no-op,
-     * and yet it will conform to the JMM behavior documented above.
-     *
-     * @param sites an array of call sites to be synchronized
-     * @throws NullPointerException if the {@code sites} array reference is null
-     *                              or the array contains a null
-     */
-    public static void syncAll(MutableCallSite[] sites) {
-        if (sites.length == 0)  return;
-        STORE_BARRIER.lazySet(0);
-        for (int i = 0; i < sites.length; i++) {
-            sites[i].getClass();  // trigger NPE on first null
-        }
-        // FIXME: NYI
-    }
-    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
-}
--- a/jdk/src/share/classes/java/dyn/SwitchPoint.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.dyn;
-
-/**
- * <p>
- * A {@code SwitchPoint} is an object which can publish state transitions to other threads.
- * A switch point is initially in the <em>valid</em> state, but may at any time be
- * changed to the <em>invalid</em> state.  Invalidation cannot be reversed.
- * A switch point can combine a <em>guarded pair</em> of method handles into a
- * <em>guarded delegator</em>.
- * The guarded delegator is a method handle which delegates to one of the old method handles.
- * The state of the switch point determines which of the two gets the delegation.
- * <p>
- * A single switch point may be used to control any number of method handles.
- * (Indirectly, therefore, it can control any number of call sites.)
- * This is done by using the single switch point as a factory for combining
- * any number of guarded method handle pairs into guarded delegators.
- * <p>
- * When a guarded delegator is created from a guarded pair, the pair
- * is wrapped in a new method handle {@code M},
- * which is permanently associated with the switch point that created it.
- * Each pair consists of a target {@code T} and a fallback {@code F}.
- * While the switch point is valid, invocations to {@code M} are delegated to {@code T}.
- * After it is invalidated, invocations are delegated to {@code F}.
- * <p>
- * Invalidation is global and immediate, as if the switch point contained a
- * volatile boolean variable consulted on every call to {@code M}.
- * The invalidation is also permanent, which means the switch point
- * can change state only once.
- * The switch point will always delegate to {@code F} after being invalidated.
- * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}.
- * <p>
- * Here is an example of a switch point in action:
- * <blockquote><pre>
-MethodType MT_str2 = MethodType.methodType(String.class, String.class);
-MethodHandle MH_strcat = MethodHandles.lookup()
-    .findVirtual(String.class, "concat", MT_str2);
-SwitchPoint spt = new SwitchPoint();
-// the following steps may be repeated to re-use the same switch point:
-MethodHandle worker1 = strcat;
-MethodHandle worker2 = MethodHandles.permuteArguments(strcat, MT_str2, 1, 0);
-MethodHandle worker = spt.guardWithTest(worker1, worker2);
-assertEquals("method", (String) worker.invokeExact("met", "hod"));
-SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
-assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
- * </pre></blockquote>
- * <p style="font-size:smaller;">
- * <em>Discussion:</em>
- * Switch points are useful without subclassing.  They may also be subclassed.
- * This may be useful in order to associate application-specific invalidation logic
- * with the switch point.
- * <p style="font-size:smaller;">
- * <em>Implementation Note:</em>
- * A switch point behaves as if implemented on top of {@link MutableCallSite},
- * approximately as follows:
- * <blockquote><pre>
-public class SwitchPoint {
-  private static final MethodHandle
-    K_true  = MethodHandles.constant(boolean.class, true),
-    K_false = MethodHandles.constant(boolean.class, false);
-  private final MutableCallSite mcs;
-  private final MethodHandle mcsInvoker;
-  public SwitchPoint() {
-    this.mcs = new MutableCallSite(K_true);
-    this.mcsInvoker = mcs.dynamicInvoker();
-  }
-  public MethodHandle guardWithTest(
-                MethodHandle target, MethodHandle fallback) {
-    // Note:  mcsInvoker is of type ()boolean.
-    // Target and fallback may take any arguments, but must have the same type.
-    return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
-  }
-  public static void invalidateAll(SwitchPoint[] spts) {
-    List&lt;MutableCallSite&gt; mcss = new ArrayList&lt;&gt;();
-    for (SwitchPoint spt : spts)  mcss.add(spt.mcs);
-    for (MutableCallSite mcs : mcss)  mcs.setTarget(K_false);
-    MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
-  }
-}
- * </pre></blockquote>
- * @author Remi Forax, JSR 292 EG
- */
-public class SwitchPoint {
-    private static final MethodHandle
-        K_true  = MethodHandles.constant(boolean.class, true),
-        K_false = MethodHandles.constant(boolean.class, false);
-
-    private final MutableCallSite mcs;
-    private final MethodHandle mcsInvoker;
-
-    /**
-     * Creates a new switch point.
-     */
-    public SwitchPoint() {
-        this.mcs = new MutableCallSite(K_true);
-        this.mcsInvoker = mcs.dynamicInvoker();
-    }
-
-    /**
-     * Returns a method handle which always delegates either to the target or the fallback.
-     * The method handle will delegate to the target exactly as long as the switch point is valid.
-     * After that, it will permanently delegate to the fallback.
-     * <p>
-     * The target and fallback must be of exactly the same method type,
-     * and the resulting combined method handle will also be of this type.
-     *
-     * @param target the method handle selected by the switch point as long as it is valid
-     * @param fallback the method handle selected by the switch point after it is invalidated
-     * @return a combined method handle which always calls either the target or fallback
-     * @throws NullPointerException if either argument is null
-     * @see MethodHandles#guardWithTest
-     */
-    public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) {
-        if (mcs.getTarget() == K_false)
-            return fallback;  // already invalid
-        return MethodHandles.guardWithTest(mcsInvoker, target, fallback);
-    }
-
-    /**
-     * Sets all of the given switch points into the invalid state.
-     * After this call executes, no thread will observe any of the
-     * switch points to be in a valid state.
-     * <p>
-     * This operation is likely to be expensive and should be used sparingly.
-     * If possible, it should be buffered for batch processing on sets of switch points.
-     * <p>
-     * If {@code switchPoints} contains a null element,
-     * a {@code NullPointerException} will be raised.
-     * In this case, some non-null elements in the array may be
-     * processed before the method returns abnormally.
-     * Which elements these are (if any) is implementation-dependent.
-     *
-     * <p style="font-size:smaller;">
-     * <em>Discussion:</em>
-     * For performance reasons, {@code invalidateAll} is not a virtual method
-     * on a single switch point, but rather applies to a set of switch points.
-     * Some implementations may incur a large fixed overhead cost
-     * for processing one or more invalidation operations,
-     * but a small incremental cost for each additional invalidation.
-     * In any case, this operation is likely to be costly, since
-     * other threads may have to be somehow interrupted
-     * in order to make them notice the updated switch point state.
-     * However, it may be observed that a single call to invalidate
-     * several switch points has the same formal effect as many calls,
-     * each on just one of the switch points.
-     *
-     * <p style="font-size:smaller;">
-     * <em>Implementation Note:</em>
-     * Simple implementations of {@code SwitchPoint} may use
-     * a private {@link MutableCallSite} to publish the state of a switch point.
-     * In such an implementation, the {@code invalidateAll} method can
-     * simply change the call site's target, and issue one call to
-     * {@linkplain MutableCallSite#syncAll synchronize} all the
-     * private call sites.
-     *
-     * @param switchPoints an array of call sites to be synchronized
-     * @throws NullPointerException if the {@code switchPoints} array reference is null
-     *                              or the array contains a null
-     */
-    public static void invalidateAll(SwitchPoint[] switchPoints) {
-        if (switchPoints.length == 0)  return;
-        MutableCallSite[] sites = new MutableCallSite[switchPoints.length];
-        for (int i = 0; i < switchPoints.length; i++) {
-            SwitchPoint spt = switchPoints[i];
-            if (spt == null)  break;  // MSC.syncAll will trigger a NPE
-            sites[i] = spt.mcs;
-            spt.mcs.setTarget(K_false);
-        }
-        MutableCallSite.syncAll(sites);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/VolatileCallSite.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.dyn;
-
-import java.util.List;
-
-/**
- * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
- * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
- * to its call site target immediately, even if the update occurs in another thread.
- * There may be a performance penalty for such tight coupling between threads.
- * <p>
- * Unlike {@code MutableCallSite}, there is no
- * {@linkplain MutableCallSite#syncAll syncAll operation} on volatile
- * call sites, since every write to a volatile variable is implicitly
- * synchronized with reader threads.
- * <p>
- * In other respects, a {@code VolatileCallSite} is interchangeable
- * with {@code MutableCallSite}.
- * @see MutableCallSite
- * @author John Rose, JSR 292 EG
- */
-public class VolatileCallSite extends CallSite {
-    /**
-     * Creates a call site with a volatile binding to its target.
-     * The initial target is set to a method handle
-     * of the given type which will throw an {@code IllegalStateException} if called.
-     * @param type the method type that this call site will have
-     * @throws NullPointerException if the proposed type is null
-     */
-    public VolatileCallSite(MethodType type) {
-        super(type);
-    }
-
-    /**
-     * Creates a call site with a volatile binding to its target.
-     * The target is set to the given value.
-     * @param target the method handle that will be the initial target of the call site
-     * @throws NullPointerException if the proposed target is null
-     */
-    public VolatileCallSite(MethodHandle target) {
-        super(target);
-    }
-
-    /**
-     * Returns the target method of the call site, which behaves
-     * like a {@code volatile} field of the {@code VolatileCallSite}.
-     * <p>
-     * The interactions of {@code getTarget} with memory are the same
-     * as of a read from a {@code volatile} field.
-     * <p>
-     * In particular, the current thread is required to issue a fresh
-     * read of the target from memory, and must not fail to see
-     * a recent update to the target by another thread.
-     *
-     * @return the linkage state of this call site, a method handle which can change over time
-     * @see #setTarget
-     */
-    @Override public final MethodHandle getTarget() {
-        return getTargetVolatile();
-    }
-
-    /**
-     * Updates the target method of this call site, as a volatile variable.
-     * The type of the new target must agree with the type of the old target.
-     * <p>
-     * The interactions with memory are the same as of a write to a volatile field.
-     * In particular, any threads is guaranteed to see the updated target
-     * the next time it calls {@code getTarget}.
-     * @param newTarget the new target
-     * @throws NullPointerException if the proposed new target is null
-     * @throws WrongMethodTypeException if the proposed new target
-     *         has a method type that differs from the previous target
-     * @see #getTarget
-     */
-    @Override public void setTarget(MethodHandle newTarget) {
-        checkTargetChange(getTargetVolatile(), newTarget);
-        setTargetVolatile(newTarget);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final MethodHandle dynamicInvoker() {
-        return makeDynamicInvoker();
-    }
-}
--- a/jdk/src/share/classes/java/dyn/WrongMethodTypeException.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.dyn;
-
-/**
- * Thrown to indicate that code has attempted to call a method handle
- * via the wrong method type.  As with the bytecode representation of
- * normal Java method calls, method handle calls are strongly typed
- * to a specific type descriptor associated with a call site.
- * <p>
- * This exception may also be thrown when two method handles are
- * composed, and the system detects that their types cannot be
- * matched up correctly.  This amounts to an early evaluation
- * of the type mismatch, at method handle construction time,
- * instead of when the mismatched method handle is called.
- *
- * @author John Rose, JSR 292 EG
- * @since 1.7
- */
-public class WrongMethodTypeException extends RuntimeException {
-    private static final long serialVersionUID = 292L;
-
-    /**
-     * Constructs a {@code WrongMethodTypeException} with no detail message.
-     */
-    public WrongMethodTypeException() {
-        super();
-    }
-
-    /**
-     * Constructs a {@code WrongMethodTypeException} with the specified
-     * detail message.
-     *
-     * @param s the detail message.
-     */
-    public WrongMethodTypeException(String s) {
-        super(s);
-    }
-}
--- a/jdk/src/share/classes/java/dyn/package-info.java	Sat Mar 26 00:10:12 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-/**
- * The {@code java.lang.invoke} package contains dynamic language support provided directly by
- * the Java core class libraries and virtual machine.
- *
- * <p style="font-size:smaller;">
- * <em>Historic Note:</em> In some early versions of Java SE 7,
- * the name of this package is {@code java.dyn}.
- * <p>
- * Certain types in this package have special relations to dynamic
- * language support in the virtual machine:
- * <ul>
- * <li>The class {@link java.dyn.MethodHandle MethodHandle} contains
- * <a href="MethodHandle.html#sigpoly">signature polymorphic methods</a>
- * which can be linked regardless of their type descriptor.
- * Normally, method linkage requires exact matching of type descriptors.
- * </li>
- *
- * <li>The JVM bytecode format supports immediate constants of
- * the classes {@link java.dyn.MethodHandle MethodHandle} and {@link java.dyn.MethodType MethodType}.
- * </li>
- * </ul>
- *
- * <h2><a name="jvm_mods"></a>Corresponding JVM bytecode format changes</h2>
- * <em>The following low-level information is presented here as a preview of
- * changes being made to the Java Virtual Machine specification for JSR 292.
- * This information will be incorporated in a future version of the JVM specification.</em>
- *
- * <h3><a name="indyinsn"></a>{@code invokedynamic} instruction format</h3>
- * In bytecode, an {@code invokedynamic} instruction is formatted as five bytes.
- * The first byte is the opcode 186 (hexadecimal {@code BA}).
- * The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
- * The final two bytes are reserved for future use and required to be zero.
- * The constant pool reference of an {@code invokedynamic} instruction is to a entry
- * with tag {@code CONSTANT_InvokeDynamic} (decimal 18).  See below for its format.
- * The entry specifies the following information:
- * <ul>
- * <li>a bootstrap method (a {@link java.dyn.MethodHandle MethodHandle} constant)</li>
- * <li>the dynamic invocation name (a UTF8 string)</li>
- * <li>the argument and return types of the call (encoded as a type descriptor in a UTF8 string)</li>
- * <li>optionally, a sequence of additional <em>static arguments</em> to the bootstrap method ({@code ldc}-type constants)</li>
- * </ul>
- * <p>
- * Each instance of an {@code invokedynamic} instruction is called a <em>dynamic call site</em>.
- * Multiple instances of an {@code invokedynamic} instruction can share a single
- * {@code CONSTANT_InvokeDynamic} entry.
- * In any case, distinct call sites always have distinct linkage state.
- * <p>
- * A dynamic call site is originally in an unlinked state.  In this state, there is
- * no target method for the call site to invoke.
- * A dynamic call site is linked by means of a bootstrap method,
- * as <a href="#bsm">described below</a>.
- *
- * <p style="font-size:smaller;">
- * <em>Historic Note:</em> Some older JVMs may allow the index of a {@code CONSTANT_NameAndType}
- * instead of a {@code CONSTANT_InvokeDynamic}.  In earlier, obsolete versions of this API, the
- * bootstrap method was specified dynamically, in a per-class basis, during class initialization.
- *
- * <h3><a name="indycon"></a>constant pool entries for {@code invokedynamic} instructions</h3>
- * If a constant pool entry has the tag {@code CONSTANT_InvokeDynamic} (decimal 18),
- * it must contain exactly four more bytes after the tag.
- * These bytes are interpreted as two 16-bit indexes, in the usual {@code u2} format.
- * The first pair of bytes after the tag must be an index into a side table called the
- * <em>bootstrap method table</em>, which is stored in the {@code BootstrapMethods}
- * attribute as <a href="#bsmattr">described below</a>.
- * The second pair of bytes must be an index to a {@code CONSTANT_NameAndType}.
- * <p>
- * The first index specifies a bootstrap method used by the associated dynamic call sites.
- * The second index specifies the method name, argument types, and return type of the dynamic call site.
- * The structure of such an entry is therefore analogous to a {@code CONSTANT_Methodref},
- * except that the bootstrap method specifier reference replaces
- * the {@code CONSTANT_Class} reference of a {@code CONSTANT_Methodref} entry.
- *
- * <h3><a name="mtcon"></a>constant pool entries for {@linkplain java.dyn.MethodType method types}</h3>
- * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
- * it must contain exactly two more bytes, which must be an index to a {@code CONSTANT_Utf8}
- * entry which represents a method type descriptor.
- * <p>
- * The JVM will ensure that on first
- * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType MethodType}
- * will be created which represents the type descriptor.
- * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
- * but not initialized.
- * Access checking and error reporting is performed exactly as it is for
- * references by {@code ldc} instructions to {@code CONSTANT_Class} constants.
- *
- * <h3><a name="mhcon"></a>constant pool entries for {@linkplain java.dyn.MethodHandle method handles}</h3>
- * If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
- * it must contain exactly three more bytes.  The first byte after the tag is a subtag
- * value which must be in the range 1 through 9, and the last two must be an index to a
- * {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
- * {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
- * for which a method handle is to be created.
- * Furthermore, the subtag value and the type of the constant index value
- * must agree according to the table below.
- * <p>
- * The JVM will ensure that on first execution of an {@code ldc} instruction
- * for this entry, a {@link java.dyn.MethodHandle MethodHandle} will be created which represents
- * the field or method reference, according to the specific mode implied by the subtag.
- * <p>
- * As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
- * the {@code Class} or {@code MethodType} object which reifies the field or method's
- * type is created.  Any classes mentioned in this reification will be loaded if necessary,
- * but not initialized, and access checking and error reporting performed as usual.
- * <p>
- * Unlike the reflective {@code Lookup} API, there are no security manager calls made
- * when these constants are resolved.
- * <p>
- * The method handle itself will have a type and behavior determined by the subtag as follows:
- * <code>
- * <table border=1 cellpadding=5 summary="CONSTANT_MethodHandle subtypes">
- * <tr><th>N</th><th>subtag name</th><th>member</th><th>MH type</th><th>bytecode behavior</th><th>lookup expression</th></tr>
- * <tr><td>1</td><td>REF_getField</td><td>C.f:T</td><td>(C)T</td><td>getfield C.f:T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findGetter findGetter(C.class,"f",T.class)}</td></tr>
- * <tr><td>2</td><td>REF_getStatic</td><td>C.f:T</td><td>(&nbsp;)T</td><td>getstatic C.f:T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter findStaticGetter(C.class,"f",T.class)}</td></tr>
- * <tr><td>3</td><td>REF_putField</td><td>C.f:T</td><td>(C,T)void</td><td>putfield C.f:T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findSetter findSetter(C.class,"f",T.class)}</td></tr>
- * <tr><td>4</td><td>REF_putStatic</td><td>C.f:T</td><td>(T)void</td><td>putstatic C.f:T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter findStaticSetter(C.class,"f",T.class)}</td></tr>
- * <tr><td>5</td><td>REF_invokeVirtual</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokevirtual C.m(A*)T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}</td></tr>
- * <tr><td>6</td><td>REF_invokeStatic</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokestatic C.m(A*)T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findStatic findStatic(C.class,"m",MT)}</td></tr>
- * <tr><td>7</td><td>REF_invokeSpecial</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokespecial C.m(A*)T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findSpecial findSpecial(C.class,"m",MT,this.class)}</td></tr>
- * <tr><td>8</td><td>REF_newInvokeSpecial</td><td>C.&lt;init&gt;(A*)void</td><td>(A*)C</td><td>new C; dup; invokespecial C.&lt;init&gt;(A*)void</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findConstructor findConstructor(C.class,MT)}</td></tr>
- * <tr><td>9</td><td>REF_invokeInterface</td><td>C.m(A*)T</td><td>(C,A*)T</td><td>invokeinterface C.m(A*)T</td>
- *               <td>{@linkplain java.dyn.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}</td></tr>
- * </table>
- * </code>
- * Here, the type {@code C} is taken from the {@code CONSTANT_Class} reference associated
- * with the {@code CONSTANT_NameAndType} descriptor.
- * The field name {@code f} or method name {@code m} is taken from the {@code CONSTANT_NameAndType}
- * as is the result type {@code T} and (in the case of a method or constructor) the argument type sequence
- * {@code A*}.
- * <p>
- * Each method handle constant has an equivalent instruction sequence called its <em>bytecode behavior</em>.
- * In general, creating a method handle constant can be done in exactly the same circumstances that
- * the JVM would successfully resolve the symbolic references in the bytecode behavior.
- * Also, the type of a method handle constant is such that a valid {@code invokeExact} call
- * on the method handle has exactly the same JVM stack effects as the <em>bytecode behavior</em>.
- * Finally, calling a method handle constant on a valid set of arguments has exactly the same effect
- * and returns the same result (if any) as the corresponding <em>bytecode behavior</em>.
- * <p>
- * Each method handle constant also has an equivalent reflective <em>lookup expression</em>,
- * which is a query to a method in {@link java.dyn.MethodHandles.Lookup}.
- * In the example lookup method expression given in the table above, the name {@code MT}
- * stands for a {@code MethodType} built from {@code T} and the sequence of argument types {@code A*}.
- * (Note that the type {@code C} is not prepended to the query type {@code MT} even if the member is non-static.)
- * In the case of {@code findSpecial}, the name {@code this.class} refers to the class containing
- * the bytecodes.
- * <p>
- * The special name {@code <clinit>} is not allowed.
- * The special name {@code <init>} is not allowed except for subtag 8 as shown.
- * <p>
- * The JVM verifier and linker apply the same access checks and restrictions for these references as for the hypothetical
- * bytecode instructions specified in the last column of the table.
- * A method handle constant will successfully resolve to a method handle if the symbolic references
- * of the corresponding bytecode instruction(s) would also resolve successfully.
- * Otherwise, an attempt to resolve the constant will throw equivalent linkage errors.
- * In particular, method handles to
- * private and protected members can be created in exactly those classes for which the corresponding
- * normal accesses are legal.
- * <p>
- * A constant may refer to a method or constructor with the {@code varargs}
- * bit (hexadecimal {@code 0x0080}) set in its modifier bitmask.
- * The method handle constant produced for such a method behaves as if
- * it were created by {@link java.dyn.MethodHandle#asVarargsCollector asVarargsCollector}.
- * In other words, the constant method handle will exhibit variable arity,
- * when invoked via {@code invokeGeneric}.
- * On the other hand, its behavior with respect to {@code invokeExact} will be the same
- * as if the {@code varargs} bit were not set.
- * <p>
- * Although the {@code CONSTANT_MethodHandle} and {@code CONSTANT_MethodType} constant types
- * resolve class names, they do not force class initialization.
- * Method handle constants for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
- * may force class initialization on their first invocation, just like the corresponding bytecodes.
- * <p>
- * The rules of section 5.4.3 of the
- * <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#73492">JVM Specification</a>
- * apply to the resolution of {@code CONSTANT_MethodType}, {@code CONSTANT_MethodHandle},
- * and {@code CONSTANT_InvokeDynamic} constants,
- * by the execution of {@code invokedynamic} and {@code ldc} instructions.
- * (Roughly speaking, this means that every use of a constant pool entry
- * must lead to the same outcome.
- * If the resolution succeeds, the same object reference is produced
- * by every subsequent execution of the same instruction.
- * If the resolution of the constant causes an error to occur,
- * the same error will be re-thrown on every subsequent attempt
- * to use this particular constant.)
- * <p>
- * Constants created by the resolution of these constant pool types are not necessarily
- * interned.  Except for {@code CONSTANT_Class} and {@code CONSTANT_String} entries,
- * two distinct constant pool entries might not resolve to the same reference
- * even if they contain the same symbolic reference.
- *
- * <h2><a name="bsm"></a>Bootstrap Methods</h2>
- * Before the JVM can execute a dynamic call site (an {@code invokedynamic} instruction),
- * the call site must first be <em>linked</em>.
- * Linking is accomplished by calling a <em>bootstrap method</em>
- * which is given the static information content of the call site,
- * and which must produce a {@link java.dyn.MethodHandle method handle}
- * that gives the behavior of the call site.
- * <p>
- * Each {@code invokedynamic} instruction statically specifies its own
- * bootstrap method as a constant pool reference.
- * The constant pool reference also specifies the call site's name and type descriptor,
- * just like {@code invokevirtual} and the other invoke instructions.
- * <p>
- * Linking starts with resolving the constant pool entry for the
- * bootstrap method, and resolving a {@link java.dyn.MethodType MethodType} object for
- * the type descriptor of the dynamic call site.
- * This resolution process may trigger class loading.
- * It may therefore throw an error if a class fails to load.
- * This error becomes the abnormal termination of the dynamic
- * call site execution.
- * Linkage does not trigger class initialization.
- * <p>
- * Next, the bootstrap method call is started, with at least four values being stacked:
- * <ul>
- * <li>a {@code MethodHandle}, the resolved bootstrap method itself </li>
- * <li>a {@code MethodHandles.Lookup}, a lookup object on the <em>caller class</em> in which dynamic call site occurs </li>
- * <li>a {@code String}, the method name mentioned in the call site </li>
- * <li>a {@code MethodType}, the resolved type descriptor of the call </li>
- * <li>optionally, one or more <a href="#args">additional static arguments</a> </li>
- * </ul>
- * The method handle is then applied to the other values as if by
- * {@link java.dyn.MethodHandle#invokeGeneric invokeGeneric}.
- * The returned result must be a {@link java.dyn.CallSite CallSite} (or a subclass).
- * The type of the call site's target must be exactly equal to the type
- * derived from the dynamic call site's type descriptor and passed to
- * the bootstrap method.
- * The call site then becomes permanently linked to the dynamic call site.
- * <p>
- * As long as each bootstrap method can be correctly invoked
- * by <code>invokeGeneric</code>, its detailed type is arbitrary.
- * For example, the first argument could be {@code Object}
- * instead of {@code MethodHandles.Lookup}, and the return type
- * could also be {@code Object} instead of {@code CallSite}.
- * <p>
- * As with any method handle constant, a {@code varargs} modifier bit
- * on the bootstrap method is ignored.
- * <p>
- * Note that the first argument of the bootstrap method cannot be
- * a simple {@code Class} reference.  (This is a change from earlier
- * versions of this specification.  If the caller class is needed,
- * it is easy to {@linkplain java.dyn.MethodHandles.Lookup#lookupClass() extract it}
- * from the {@code Lookup} object.)
- * <p>
- * After resolution, the linkage process may fail in a variety of ways.
- * All failures are reported by an {@link java.dyn.InvokeDynamicBootstrapError InvokeDynamicBootstrapError},
- * which is thrown as the abnormal termination of the dynamic call
- * site execution.
- * The following circumstances will cause this:
- * <ul>
- * <li>the index to the bootstrap method specifier is out of range </li>
- * <li>the bootstrap method cannot be resolved </li>
- * <li>the {@code MethodType} to pass to the bootstrap method cannot be resolved </li>
- * <li>a static argument to the bootstrap method cannot be resolved
- *     (i.e., a {@code CONSTANT_Class}, {@code CONSTANT_MethodType},
- *     or {@code CONSTANT_MethodHandle} argument cannot be linked) </li>
- * <li>the bootstrap method has the wrong arity,
- *     causing {@code invokeGeneric} to throw {@code WrongMethodTypeException} </li>
- * <li>the bootstrap method has a wrong argument or return type </li>
- * <li>the bootstrap method invocation completes abnormally </li>
- * <li>the result from the bootstrap invocation is not a reference to
- *     an object of type {@link java.dyn.CallSite CallSite} </li>
- * <li>the target of the {@code CallSite} does not have a target of
- *     the expected {@code MethodType} </li>
- * </ul>
- *
- * <h3><a name="linktime"></a>timing of linkage</h3>
- * 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.
- * <p>
- * If there are several such threads, the bootstrap method may be
- * invoked in several threads concurrently.
- * Therefore, bootstrap methods which access global application
- * data must take the usual precautions against race conditions.
- * In any case, every {@code invokedynamic} instruction is either
- * unlinked or linked to a unique {@code CallSite} object.
- * <p>
- * In an application which requires dynamic call sites with individually
- * mutable behaviors, their bootstrap methods should produce distinct
- * {@link java.dyn.CallSite CallSite} objects, one for each linkage request.
- * Alternatively, an application can link a single {@code CallSite} object
- * to several {@code invokedynamic} instructions, in which case
- * a change to the target method will become visible at each of
- * the instructions.
- * <p>
- * If several threads simultaneously execute a bootstrap method for a single dynamic
- * call site, the JVM must choose one {@code CallSite} object and install it visibly to
- * all threads.  Any other bootstrap method calls are allowed to complete, but their
- * results are ignored, and their dynamic call site invocations proceed with the originally
- * chosen target object.
- *
- * <p style="font-size:smaller;">
- * <em>Historic Note:</em> Unlike some previous versions of this specification,
- * these rules do not enable the JVM to duplicate dynamic call sites,
- * or to issue &ldquo;causeless&rdquo; bootstrap method calls.
- * Every dynamic call site transitions at most once from unlinked to linked,
- * just before its first invocation.
- *
- * <h3><a name="bsmattr">the {@code BootstrapMethods} attribute </h3>
- * Each {@code CONSTANT_InvokeDynamic} entry contains an index which references
- * a bootstrap method specifier; all such specifiers are contained in a separate array.
- * This array is defined by a class attribute named {@code BootstrapMethods}.
- * The body of this attribute consists of a sequence of byte pairs, all interpreted as
- * as 16-bit counts or constant pool indexes, in the {@code u2} format.
- * The attribute body starts with a count of bootstrap method specifiers,
- * which is immediately followed by the sequence of specifiers.
- * <p>
- * Each bootstrap method specifier contains an index to a
- * {@code CONSTANT_MethodHandle} constant, which is the bootstrap
- * method itself.
- * This is followed by a count, and then a sequence (perhaps empty) of
- * indexes to <a href="#args">additional static arguments</a>
- * for the bootstrap method.
- * <p>
- * During class loading, the verifier must check the structure of the
- * {@code BootstrapMethods} attribute.  In particular, each constant
- * pool index must be of the correct type.  A bootstrap method index
- * must refer to a {@code CONSTANT_MethodHandle} (tag 15).
- * Every other index must refer to a valid operand of an
- * {@code ldc_w} or {@code ldc2_w} instruction (tag 3..8 or 15..16).
- *
- * <h3><a name="args">static arguments to the bootstrap method</h3>
- * An {@code invokedynamic} instruction specifies at least three arguments
- * to pass to its bootstrap method:
- * The caller class (expressed as a {@link java.dyn.MethodHandles.Lookup Lookup object},
- * the name (extracted from the {@code CONSTANT_NameAndType} entry),
- * and the type (also extracted from the {@code CONSTANT_NameAndType} entry).
- * The {@code invokedynamic} instruction may specify additional metadata values
- * to pass to its bootstrap method.
- * Collectively, these values are called <em>static arguments</em> to the
- * {@code invokedynamic} instruction, because they are used once at link
- * time to determine the instruction's behavior on subsequent sets of
- * <em>dynamic arguments</em>.
- * <p>
- * Static arguments are used to communicate application-specific meta-data
- * to the bootstrap method.
- * Drawn from the constant pool, they may include references to classes, method handles,
- * strings, or numeric data that may be relevant to the task of linking that particular call site.
- * <p>
- * Static arguments are specified constant pool indexes stored in the {@code BootstrapMethods} attribute.
- * Before the bootstrap method is invoked, each index is used to compute an {@code Object}
- * reference to the indexed value in the constant pool.
- * The valid constant pool entries are listed in this table:
- * <code>
- * <table border=1 cellpadding=5 summary="Static argument types">
- * <tr><th>entry type</th><th>argument type</th><th>argument value</th></tr>
- * <tr><td>CONSTANT_String</td><td><code>java.lang.String</code></td><td>the indexed string literal</td></tr>
- * <tr><td>CONSTANT_Class</td><td><code>java.lang.Class</code></td><td>the indexed class, resolved</td></tr>
- * <tr><td>CONSTANT_Integer</td><td><code>java.lang.Integer</code></td><td>the indexed int value</td></tr>
- * <tr><td>CONSTANT_Long</td><td><code>java.lang.Long</code></td><td>the indexed long value</td></tr>
- * <tr><td>CONSTANT_Float</td><td><code>java.lang.Float</code></td><td>the indexed float value</td></tr>
- * <tr><td>CONSTANT_Double</td><td><code>java.lang.Double</code></td><td>the indexed double value</td></tr>
- * <tr><td>CONSTANT_MethodHandle</td><td><code>java.dyn.MethodHandle</code></td><td>the indexed method handle constant</td></tr>
- * <tr><td>CONSTANT_MethodType</td><td><code>java.dyn.MethodType</code></td><td>the indexed method type constant</td></tr>
- * </table>
- * </code>
- * <p>
- * If a given {@code invokedynamic} instruction specifies no static arguments,
- * the instruction's bootstrap method will be invoked on three arguments,
- * conveying the instruction's caller class, name, and method type.
- * If the {@code invokedynamic} instruction specifies one or more static arguments,
- * those values will be passed as additional arguments to the method handle.
- * (Note that because there is a limit of 255 arguments to any method,
- * at most 252 extra arguments can be supplied.)
- * The bootstrap method will be invoked as if by either {@code invokeGeneric}
- * or {@code invokeWithArguments}.  (There is no way to tell the difference.)
- * <p>
- * The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments.
- * For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
- * If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set),
- * then some or all of the arguments specified here may be collected into a trailing array parameter.
- * (This is not a special rule, but rather a useful consequence of the interaction
- * between {@code CONSTANT_MethodHandle} constants, the modifier bit for variable arity methods,
- * and the {@code java.dyn.MethodHandle#asVarargsCollector asVarargsCollector} transformation.)
- * <p>
- * Given these rules, here are examples of legal bootstrap method declarations,
- * given various numbers {@code N} of extra arguments.
- * The first rows (marked {@code *}) will work for any number of extra arguments.
- * <code>
- * <table border=1 cellpadding=5 summary="Static argument types">
- * <tr><th>N</th><th>sample bootstrap method</th></tr>
- * <tr><td>*</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)</code></td></tr>
- * <tr><td>*</td><td><code>CallSite bootstrap(Object... args)</code></td></tr>
- * <tr><td>*</td><td><code>CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)</code></td></tr>
- * <tr><td>0</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type)</code></td></tr>
- * <tr><td>0</td><td><code>CallSite bootstrap(Lookup caller, Object... nameAndType)</code></td></tr>
- * <tr><td>1</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)</code></td></tr>
- * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)</code></td></tr>
- * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)</code></td></tr>
- * <tr><td>2</td><td><code>CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)</code></td></tr>
- * </table>
- * </code>
- * The last example assumes that the extra arguments are of type
- * {@code CONSTANT_String} and {@code CONSTANT_Integer}, respectively.
- * The second-to-last example assumes that all extra arguments are of type
- * {@code CONSTANT_String}.
- * The other examples work with all types of extra arguments.
- * <p>
- * As noted above, the actual method type of the bootstrap method can vary.
- * For example, the fourth argument could be {@code MethodHandle},
- * if that is the type of the corresponding constant in
- * the {@code CONSTANT_InvokeDynamic} entry.
- * In that case, the {@code invokeGeneric} call will pass the extra method handle
- * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric}
- * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method.
- * (If a string constant were passed instead, by badly generated code, that cast would then fail,
- * resulting in an {@code InvokeDynamicBootstrapError}.)
- * <p>
- * Extra bootstrap method arguments are intended to allow language implementors
- * to safely and compactly encode metadata.
- * In principle, the name and extra arguments are redundant,
- * since each call site could be given its own unique bootstrap method.
- * Such a practice is likely to produce large class files and constant pools.
- *
- * <h2><a name="structs"></a>Structure Summary</h2>
- * <blockquote><pre>// summary of constant and attribute structures
-struct CONSTANT_MethodHandle_info {
-  u1 tag = 15;
-  u1 reference_kind;       // 1..8 (one of REF_invokeVirtual, etc.)
-  u2 reference_index;      // index to CONSTANT_Fieldref or *Methodref
-}
-struct CONSTANT_MethodType_info {
-  u1 tag = 16;
-  u2 descriptor_index;    // index to CONSTANT_Utf8, as in NameAndType
-}
-struct CONSTANT_InvokeDynamic_info {
-  u1 tag = 18;
-  u2 bootstrap_method_attr_index;  // index into BootstrapMethods_attr
-  u2 name_and_type_index;          // index to CONSTANT_NameAndType, as in Methodref
-}
-struct BootstrapMethods_attr {
- u2 name;  // CONSTANT_Utf8 = "BootstrapMethods"
- u4 size;
- u2 bootstrap_method_count;
- struct bootstrap_method_specifier {
-   u2 bootstrap_method_ref;  // index to CONSTANT_MethodHandle
-   u2 bootstrap_argument_count;
-   u2 bootstrap_arguments[bootstrap_argument_count];  // constant pool indexes
- } bootstrap_methods[bootstrap_method_count];
-}
- * </pre></blockquote>
- *
- * @author John Rose, JSR 292 EG
- */
-
-package java.dyn;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/BootstrapMethodError.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008, 2011, 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;
+
+/**
+ * Thrown to indicate that an {@code invokedynamic} instruction has
+ * failed to find its bootstrap method,
+ * or the bootstrap method has failed to provide a
+ * {@linkplain java.lang.invoke.CallSite call site} with a {@linkplain java.lang.invoke.CallSite#getTarget target}
+ * of the correct {@linkplain java.lang.invoke.MethodHandle#type method type}.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class BootstrapMethodError extends LinkageError {
+    private static final long serialVersionUID = 292L;
+
+    /**
+     * Constructs an {@code BootstrapMethodError} with no detail message.
+     */
+    public BootstrapMethodError() {
+        super();
+    }
+
+    /**
+     * Constructs an {@code BootstrapMethodError} with the specified
+     * detail message.
+     *
+     * @param s the detail message.
+     */
+    public BootstrapMethodError(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a {@code BootstrapMethodError} with the specified
+     * detail message and cause.
+     *
+     * @param s the detail message.
+     * @param cause the cause, may be {@code null}.
+     */
+    public BootstrapMethodError(String s, Throwable cause) {
+        super(s, cause);
+    }
+
+    /**
+     * Constructs a {@code BootstrapMethodError} with the specified
+     * cause.
+     *
+     * @param cause the cause, may be {@code null}.
+     */
+    public BootstrapMethodError(Throwable cause) {
+        // cf. Throwable(Throwable cause) constructor.
+        super(cause == null ? null : cause.toString());
+        initCause(cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/ClassValue.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2010, 2011, 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;
+
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Lazily associate a computed value with (potentially) every type.
+ * For example, if a dynamic language needs to construct a message dispatch
+ * table for each class encountered at a message send call site,
+ * it can use a {@code ClassValue} to cache information needed to
+ * perform the message send quickly, for each class encountered.
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public abstract class ClassValue<T> {
+    /**
+     * Computes the given class's derived value for this {@code ClassValue}.
+     * <p>
+     * This method will be invoked within the first thread that accesses
+     * the value with the {@link #get get} method.
+     * <p>
+     * Normally, this method is invoked at most once per class,
+     * but it may be invoked again if there has been a call to
+     * {@link #remove remove}.
+     * <p>
+     * If this method throws an exception, the corresponding call to {@code get}
+     * will terminate abnormally with that exception, and no class value will be recorded.
+     *
+     * @param type the type whose class value must be computed
+     * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface
+     * @see #get
+     * @see #remove
+     */
+    protected abstract T computeValue(Class<?> type);
+
+    /**
+     * Returns the value for the given class.
+     * If no value has yet been computed, it is obtained by
+     * an invocation of the {@link #computeValue computeValue} method.
+     * <p>
+     * The actual installation of the value on the class
+     * is performed atomically.
+     * At that point, if several racing threads have
+     * computed values, one is chosen, and returned to
+     * all the racing threads.
+     * <p>
+     * The {@code type} parameter is typically a class, but it may be any type,
+     * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}.
+     * <p>
+     * In the absence of {@code remove} calls, a class value has a simple
+     * state diagram:  uninitialized and initialized.
+     * When {@code remove} calls are made,
+     * the rules for value observation are more complex.
+     * See the documentation for {@link #remove remove} for more information.
+     *
+     * @param type the type whose class value must be computed or retrieved
+     * @return the current value associated with this {@code ClassValue}, for the given class or interface
+     * @throws NullPointerException if the argument is null
+     * @see #remove
+     * @see #computeValue
+     */
+    public T get(Class<?> type) {
+        ClassValueMap map = getMap(type);
+        if (map != null) {
+            Object x = map.get(this);
+            if (x != null) {
+                return (T) map.unmaskNull(x);
+            }
+        }
+        return setComputedValue(type);
+    }
+
+    /**
+     * Removes the associated value for the given class.
+     * If this value is subsequently {@linkplain #get read} for the same class,
+     * its value will be reinitialized by invoking its {@link #computeValue computeValue} method.
+     * This may result in an additional invocation of the
+     * {@code computeValue computeValue} method for the given class.
+     * <p>
+     * In order to explain the interaction between {@code get} and {@code remove} calls,
+     * we must model the state transitions of a class value to take into account
+     * the alternation between uninitialized and initialized states.
+     * To do this, number these states sequentially from zero, and note that
+     * uninitialized (or removed) states are numbered with even numbers,
+     * while initialized (or re-initialized) states have odd numbers.
+     * <p>
+     * When a thread {@code T} removes a class value in state {@code 2N},
+     * nothing happens, since the class value is already uninitialized.
+     * Otherwise, the state is advanced atomically to {@code 2N+1}.
+     * <p>
+     * When a thread {@code T} queries a class value in state {@code 2N},
+     * the thread first attempts to initialize the class value to state {@code 2N+1}
+     * by invoking {@code computeValue} and installing the resulting value.
+     * <p>
+     * When {@code T} attempts to install the newly computed value,
+     * if the state is still at {@code 2N}, the class value will be initialized
+     * with the computed value, advancing it to state {@code 2N+1}.
+     * <p>
+     * Otherwise, whether the new state is even or odd,
+     * {@code T} will discard the newly computed value
+     * and retry the {@code get} operation.
+     * <p>
+     * Discarding and retrying is an important proviso,
+     * since otherwise {@code T} could potentially install
+     * a disastrously stale value.  For example:
+     * <ul>
+     * <li>{@code T} calls {@code CV.get(C)} and sees state {@code 2N}
+     * <li>{@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it
+     * <li>{@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time
+     * <li>...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N}
+     * <li>{@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)}
+     * <li>{@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work
+     * <li> the previous actions of {@code T2} are repeated several times
+     * <li> also, the relevant computed values change over time: {@code V1}, {@code V2}, ...
+     * <li>...meanwhile, {@code T} wakes up and attempts to install {@code V0}; <em>this must fail</em>
+     * </ul>
+     * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
+     * observe the time-dependent states as it computes {@code V1}, etc.
+     * This does not remove the threat of a stale value, since there is a window of time
+     * between the return of {@code computeValue} in {@code T} and the installation
+     * of the the new value.  No user synchronization is possible during this time.
+     *
+     * @param type the type whose class value must be removed
+     * @throws NullPointerException if the argument is null
+     */
+    public void remove(Class<?> type) {
+        ClassValueMap map = getMap(type);
+        if (map != null) {
+            synchronized (map) {
+                map.remove(this);
+            }
+        }
+    }
+
+    /// Implementation...
+    // FIXME: Use a data structure here similar that of ThreadLocal (7030453).
+
+    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+
+    /** Slow path for {@link #get}. */
+    private T setComputedValue(Class<?> type) {
+        ClassValueMap map = getMap(type);
+        if (map == null) {
+            map = initializeMap(type);
+        }
+        T value = computeValue(type);
+        STORE_BARRIER.lazySet(0);
+        // All stores pending from computeValue are completed.
+        synchronized (map) {
+            // Warm up the table with a null entry.
+            map.preInitializeEntry(this);
+        }
+        STORE_BARRIER.lazySet(0);
+        // All stores pending from table expansion are completed.
+        synchronized (map) {
+            value = (T) map.initializeEntry(this, value);
+            // One might fear a possible race condition here
+            // if the code for map.put has flushed the write
+            // to map.table[*] before the writes to the Map.Entry
+            // are done.  This is not possible, since we have
+            // warmed up the table with an empty entry.
+        }
+        return value;
+    }
+
+    // Replace this map by a per-class slot.
+    private static final WeakHashMap<Class<?>, ClassValueMap> ROOT
+        = new WeakHashMap<Class<?>, ClassValueMap>();
+
+    private static ClassValueMap getMap(Class<?> type) {
+        return ROOT.get(type);
+    }
+
+    private static ClassValueMap initializeMap(Class<?> type) {
+        synchronized (ClassValue.class) {
+            ClassValueMap map = ROOT.get(type);
+            if (map == null)
+                ROOT.put(type, map = new ClassValueMap());
+            return map;
+        }
+    }
+
+    static class ClassValueMap extends WeakHashMap<ClassValue, Object> {
+        /** Make sure this table contains an Entry for the given key, even if it is empty. */
+        void preInitializeEntry(ClassValue key) {
+            if (!this.containsKey(key))
+                this.put(key, null);
+        }
+        /** Make sure this table contains a non-empty Entry for the given key. */
+        Object initializeEntry(ClassValue key, Object value) {
+            Object prior = this.get(key);
+            if (prior != null) {
+                return unmaskNull(prior);
+            }
+            this.put(key, maskNull(value));
+            return value;
+        }
+
+        Object maskNull(Object x) {
+            return x == null ? this : x;
+        }
+        Object unmaskNull(Object x) {
+            return x == this ? null : x;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2008, 2011, 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 sun.invoke.util.VerifyType;
+import sun.invoke.util.Wrapper;
+import java.util.Arrays;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * This method handle performs simple conversion or checking of a single argument.
+ * @author jrose
+ */
+class AdapterMethodHandle extends BoundMethodHandle {
+
+    //MethodHandle vmtarget;   // next AMH or BMH in chain or final DMH
+    //Object       argument;   // parameter to the conversion if needed
+    //int          vmargslot;  // which argument slot is affected
+    private final int conversion;  // the type of conversion: RETYPE_ONLY, etc.
+
+    // Constructors in this class *must* be package scoped or private.
+    private AdapterMethodHandle(MethodHandle target, MethodType newType,
+                long conv, Object convArg) {
+        super(newType, convArg, newType.parameterSlotDepth(1+convArgPos(conv)));
+        this.conversion = convCode(conv);
+        // JVM might update VM-specific bits of conversion (ignore)
+        MethodHandleNatives.init(this, target, convArgPos(conv));
+    }
+    private AdapterMethodHandle(MethodHandle target, MethodType newType,
+                long conv) {
+        this(target, newType, conv, null);
+    }
+
+    // TO DO:  When adapting another MH with a null conversion, clone
+    // the target and change its type, instead of adding another layer.
+
+    /** Can a JVM-level adapter directly implement the proposed
+     *  argument conversions, as if by MethodHandles.convertArguments?
+     */
+    static boolean canPairwiseConvert(MethodType newType, MethodType oldType) {
+        // same number of args, of course
+        int len = newType.parameterCount();
+        if (len != oldType.parameterCount())
+            return false;
+
+        // Check return type.  (Not much can be done with it.)
+        Class<?> exp = newType.returnType();
+        Class<?> ret = oldType.returnType();
+        if (!VerifyType.isNullConversion(ret, exp))
+            return false;
+
+        // Check args pairwise.
+        for (int i = 0; i < len; i++) {
+            Class<?> src = newType.parameterType(i); // source type
+            Class<?> dst = oldType.parameterType(i); // destination type
+            if (!canConvertArgument(src, dst))
+                return false;
+        }
+
+        return true;
+    }
+
+    /** Can a JVM-level adapter directly implement the proposed
+     *  argument conversion, as if by MethodHandles.convertArguments?
+     */
+    static boolean canConvertArgument(Class<?> src, Class<?> dst) {
+        // ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes,
+        // so we don't need to repeat so much decision making.
+        if (VerifyType.isNullConversion(src, dst)) {
+            return true;
+        } else if (src.isPrimitive()) {
+            if (dst.isPrimitive())
+                return canPrimCast(src, dst);
+            else
+                return canBoxArgument(src, dst);
+        } else {
+            if (dst.isPrimitive())
+                return canUnboxArgument(src, dst);
+            else
+                return true;  // any two refs can be interconverted
+        }
+    }
+
+    /**
+     * Create a JVM-level adapter method handle to conform the given method
+     * handle to the similar newType, using only pairwise argument conversions.
+     * For each argument, convert incoming argument to the exact type needed.
+     * Only null conversions are allowed on the return value (until
+     * the JVM supports ricochet adapters).
+     * The argument conversions allowed are casting, unboxing,
+     * integral widening or narrowing, and floating point widening or narrowing.
+     * @param newType required call type
+     * @param target original method handle
+     * @return an adapter to the original handle with the desired new type,
+     *          or the original target if the types are already identical
+     *          or null if the adaptation cannot be made
+     */
+    static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target) {
+        MethodType oldType = target.type();
+        if (newType == oldType)  return target;
+
+        if (!canPairwiseConvert(newType, oldType))
+            return null;
+        // (after this point, it is an assertion error to fail to convert)
+
+        // Find last non-trivial conversion (if any).
+        int lastConv = newType.parameterCount()-1;
+        while (lastConv >= 0) {
+            Class<?> src = newType.parameterType(lastConv); // source type
+            Class<?> dst = oldType.parameterType(lastConv); // destination type
+            if (VerifyType.isNullConversion(src, dst)) {
+                --lastConv;
+            } else {
+                break;
+            }
+        }
+        // Now build a chain of one or more adapters.
+        MethodHandle adapter = target;
+        MethodType midType = oldType.changeReturnType(newType.returnType());
+        for (int i = 0; i <= lastConv; i++) {
+            Class<?> src = newType.parameterType(i); // source type
+            Class<?> dst = midType.parameterType(i); // destination type
+            if (VerifyType.isNullConversion(src, dst)) {
+                // do nothing: difference is trivial
+                continue;
+            }
+            // Work the current type backward toward the desired caller type:
+            if (i != lastConv) {
+                midType = midType.changeParameterType(i, src);
+            } else {
+                // When doing the last (or only) real conversion,
+                // force all remaining null conversions to happen also.
+                assert(VerifyType.isNullConversion(newType, midType.changeParameterType(i, src)));
+                midType = newType;
+            }
+
+            // Tricky case analysis follows.
+            // It parallels canConvertArgument() above.
+            if (src.isPrimitive()) {
+                if (dst.isPrimitive()) {
+                    adapter = makePrimCast(midType, adapter, i, dst);
+                } else {
+                    adapter = makeBoxArgument(midType, adapter, i, dst);
+                }
+            } else {
+                if (dst.isPrimitive()) {
+                    // Caller has boxed a primitive.  Unbox it for the target.
+                    // The box type must correspond exactly to the primitive type.
+                    // This is simpler than the powerful set of widening
+                    // conversions supported by reflect.Method.invoke.
+                    // Those conversions require a big nest of if/then/else logic,
+                    // which we prefer to make a user responsibility.
+                    adapter = makeUnboxArgument(midType, adapter, i, dst);
+                } else {
+                    // Simple reference conversion.
+                    // Note:  Do not check for a class hierarchy relation
+                    // between src and dst.  In all cases a 'null' argument
+                    // will pass the cast conversion.
+                    adapter = makeCheckCast(midType, adapter, i, dst);
+                }
+            }
+            assert(adapter != null);
+            assert(adapter.type() == midType);
+        }
+        if (adapter.type() != newType) {
+            // Only trivial conversions remain.
+            adapter = makeRetypeOnly(newType, adapter);
+            assert(adapter != null);
+            // Actually, that's because there were no non-trivial ones:
+            assert(lastConv == -1);
+        }
+        assert(adapter.type() == newType);
+        return adapter;
+    }
+
+    /**
+     * Create a JVM-level adapter method handle to permute the arguments
+     * of the given method.
+     * @param newType required call type
+     * @param target original method handle
+     * @param argumentMap for each target argument, position of its source in newType
+     * @return an adapter to the original handle with the desired new type,
+     *          or the original target if the types are already identical
+     *          and the permutation is null
+     * @throws IllegalArgumentException if the adaptation cannot be made
+     *          directly by a JVM-level adapter, without help from Java code
+     */
+    static MethodHandle makePermutation(MethodType newType, MethodHandle target,
+                int[] argumentMap) {
+        MethodType oldType = target.type();
+        boolean nullPermutation = true;
+        for (int i = 0; i < argumentMap.length; i++) {
+            int pos = argumentMap[i];
+            if (pos != i)
+                nullPermutation = false;
+            if (pos < 0 || pos >= newType.parameterCount()) {
+                argumentMap = new int[0]; break;
+            }
+        }
+        if (argumentMap.length != oldType.parameterCount())
+            throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap));
+        if (nullPermutation) {
+            MethodHandle res = makePairwiseConvert(newType, target);
+            // well, that was easy
+            if (res == null)
+                throw newIllegalArgumentException("cannot convert pairwise: "+newType);
+            return res;
+        }
+
+        // Check return type.  (Not much can be done with it.)
+        Class<?> exp = newType.returnType();
+        Class<?> ret = oldType.returnType();
+        if (!VerifyType.isNullConversion(ret, exp))
+            throw newIllegalArgumentException("bad return conversion for "+newType);
+
+        // See if the argument types match up.
+        for (int i = 0; i < argumentMap.length; i++) {
+            int j = argumentMap[i];
+            Class<?> src = newType.parameterType(j);
+            Class<?> dst = oldType.parameterType(i);
+            if (!VerifyType.isNullConversion(src, dst))
+                throw newIllegalArgumentException("bad argument #"+j+" conversion for "+newType);
+        }
+
+        // Now figure out a nice mix of SWAP, ROT, DUP, and DROP adapters.
+        // A workable greedy algorithm is as follows:
+        // Drop unused outgoing arguments (right to left: shallowest first).
+        // Duplicate doubly-used outgoing arguments (left to right: deepest first).
+        // Then the remaining problem is a true argument permutation.
+        // Marshal the outgoing arguments as required from left to right.
+        // That is, find the deepest outgoing stack position that does not yet
+        // have the correct argument value, and correct at least that position
+        // by swapping or rotating in the misplaced value (from a shallower place).
+        // If the misplaced value is followed by one or more consecutive values
+        // (also misplaced)  issue a rotation which brings as many as possible
+        // into position.  Otherwise make progress with either a swap or a
+        // rotation.  Prefer the swap as cheaper, but do not use it if it
+        // breaks a slot pair.  Prefer the rotation over the swap if it would
+        // preserve more consecutive values shallower than the target position.
+        // When more than one rotation will work (because the required value
+        // is already adjacent to the target position), then use a rotation
+        // which moves the old value in the target position adjacent to
+        // one of its consecutive values.  Also, prefer shorter rotation
+        // spans, since they use fewer memory cycles for shuffling.
+
+        throw new UnsupportedOperationException("NYI");
+    }
+
+    private static byte basicType(Class<?> type) {
+        if (type == null)  return T_VOID;
+        switch (Wrapper.forBasicType(type)) {
+            case BOOLEAN:  return T_BOOLEAN;
+            case CHAR:     return T_CHAR;
+            case FLOAT:    return T_FLOAT;
+            case DOUBLE:   return T_DOUBLE;
+            case BYTE:     return T_BYTE;
+            case SHORT:    return T_SHORT;
+            case INT:      return T_INT;
+            case LONG:     return T_LONG;
+            case OBJECT:   return T_OBJECT;
+            case VOID:     return T_VOID;
+        }
+        return 99; // T_ILLEGAL or some such
+    }
+
+    /** Number of stack slots for the given type.
+     *  Two for T_DOUBLE and T_FLOAT, one for the rest.
+     */
+    private static int type2size(int type) {
+        assert(type >= T_BOOLEAN && type <= T_OBJECT);
+        return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
+    }
+    private static int type2size(Class<?> type) {
+        return type2size(basicType(type));
+    }
+
+    /** The given stackMove is the number of slots pushed.
+     * It might be negative.  Scale it (multiply) by the
+     * VM's notion of how an address changes with a push,
+     * to get the raw SP change for stackMove.
+     * Then shift and mask it into the correct field.
+     */
+    private static long insertStackMove(int stackMove) {
+        // following variable must be long to avoid sign extension after '<<'
+        long spChange = stackMove * MethodHandleNatives.JVM_STACK_MOVE_UNIT;
+        return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
+    }
+
+    /** Construct an adapter conversion descriptor for a single-argument conversion. */
+    private static long makeConv(int convOp, int argnum, int src, int dest) {
+        assert(src  == (src  & 0xF));
+        assert(dest == (dest & 0xF));
+        assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
+        int stackMove = type2size(dest) - type2size(src);
+        return ((long) argnum << 32 |
+                (long) convOp << CONV_OP_SHIFT |
+                (int)  src    << CONV_SRC_TYPE_SHIFT |
+                (int)  dest   << CONV_DEST_TYPE_SHIFT |
+                insertStackMove(stackMove)
+                );
+    }
+    private static long makeConv(int convOp, int argnum, int stackMove) {
+        assert(convOp >= OP_DUP_ARGS && convOp <= OP_SPREAD_ARGS);
+        byte src = 0, dest = 0;
+        if (convOp >= OP_COLLECT_ARGS && convOp <= OP_SPREAD_ARGS)
+            src = dest = T_OBJECT;
+        return ((long) argnum << 32 |
+                (long) convOp << CONV_OP_SHIFT |
+                (int)  src    << CONV_SRC_TYPE_SHIFT |
+                (int)  dest   << CONV_DEST_TYPE_SHIFT |
+                insertStackMove(stackMove)
+                );
+    }
+    private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
+        assert(convOp >= OP_SWAP_ARGS && convOp <= OP_ROT_ARGS);
+        return ((long) srcArg << 32 |
+                (long) convOp << CONV_OP_SHIFT |
+                (int)  type   << CONV_SRC_TYPE_SHIFT |
+                (int)  type   << CONV_DEST_TYPE_SHIFT |
+                (int)  destSlot << CONV_VMINFO_SHIFT
+                );
+    }
+    private static long makeConv(int convOp) {
+        assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
+        return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT);   // stackMove, src, dst all zero
+    }
+    private static int convCode(long conv) {
+        return (int)conv;
+    }
+    private static int convArgPos(long conv) {
+        return (int)(conv >>> 32);
+    }
+    private static boolean convOpSupported(int convOp) {
+        assert(convOp >= 0 && convOp <= CONV_OP_LIMIT);
+        return ((1<<convOp) & MethodHandleNatives.CONV_OP_IMPLEMENTED_MASK) != 0;
+    }
+
+    /** One of OP_RETYPE_ONLY, etc. */
+    int conversionOp() { return (conversion & CONV_OP_MASK) >> CONV_OP_SHIFT; }
+
+    /* Return one plus the position of the first non-trivial difference
+     * between the given types.  This is not a symmetric operation;
+     * we are considering adapting the targetType to adapterType.
+     * Trivial differences are those which could be ignored by the JVM
+     * without subverting the verifier.  Otherwise, adaptable differences
+     * are ones for which we could create an adapter to make the type change.
+     * Return zero if there are no differences (other than trivial ones).
+     * Return 1+N if N is the only adaptable argument difference.
+     * Return the -2-N where N is the first of several adaptable
+     * argument differences.
+     * Return -1 if there there are differences which are not adaptable.
+     */
+    private static int diffTypes(MethodType adapterType,
+                                 MethodType targetType,
+                                 boolean raw) {
+        int diff;
+        diff = diffReturnTypes(adapterType, targetType, raw);
+        if (diff != 0)  return diff;
+        int nargs = adapterType.parameterCount();
+        if (nargs != targetType.parameterCount())
+            return -1;
+        diff = diffParamTypes(adapterType, 0, targetType, 0, nargs, raw);
+        //System.out.println("diff "+adapterType);
+        //System.out.println("  "+diff+" "+targetType);
+        return diff;
+    }
+    private static int diffReturnTypes(MethodType adapterType,
+                                       MethodType targetType,
+                                       boolean raw) {
+        Class<?> src = targetType.returnType();
+        Class<?> dst = adapterType.returnType();
+        if ((!raw
+             ? VerifyType.canPassUnchecked(src, dst)
+             : VerifyType.canPassRaw(src, dst)
+             ) > 0)
+            return 0;  // no significant difference
+        if (raw && !src.isPrimitive() && !dst.isPrimitive())
+            return 0;  // can force a reference return (very carefully!)
+        //if (false)  return 1;  // never adaptable!
+        return -1;  // some significant difference
+    }
+    private static int diffParamTypes(MethodType adapterType, int astart,
+                                      MethodType targetType, int tstart,
+                                      int nargs, boolean raw) {
+        assert(nargs >= 0);
+        int res = 0;
+        for (int i = 0; i < nargs; i++) {
+            Class<?> src  = adapterType.parameterType(astart+i);
+            Class<?> dest = targetType.parameterType(tstart+i);
+            if ((!raw
+                 ? VerifyType.canPassUnchecked(src, dest)
+                 : VerifyType.canPassRaw(src, dest)
+                ) <= 0) {
+                // found a difference; is it the only one so far?
+                if (res != 0)
+                    return -1-res; // return -2-i for prev. i
+                res = 1+i;
+            }
+        }
+        return res;
+    }
+
+    /** Can a retyping adapter (alone) validly convert the target to newType? */
+    static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
+        return canRetype(newType, targetType, false);
+    }
+    /** Can a retyping adapter (alone) convert the target to newType?
+     *  It is allowed to widen subword types and void to int, to make bitwise
+     *  conversions between float/int and double/long, and to perform unchecked
+     *  reference conversions on return.  This last feature requires that the
+     *  caller be trusted, and perform explicit cast conversions on return values.
+     */
+    static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
+        return canRetype(newType, targetType, true);
+    }
+    static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
+        if (!convOpSupported(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY))  return false;
+        int diff = diffTypes(newType, targetType, raw);
+        // %%% This assert is too strong.  Factor diff into VerifyType and reconcile.
+        assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
+        return diff == 0;
+    }
+
+    /** Factory method:  Performs no conversions; simply retypes the adapter.
+     *  Allows unchecked argument conversions pairwise, if they are safe.
+     *  Returns null if not possible.
+     */
+    static MethodHandle makeRetypeOnly(MethodType newType, MethodHandle target) {
+        return makeRetype(newType, target, false);
+    }
+    static MethodHandle makeRetypeRaw(MethodType newType, MethodHandle target) {
+        return makeRetype(newType, target, true);
+    }
+    static MethodHandle makeRetype(MethodType newType, MethodHandle target, boolean raw) {
+        MethodType oldType = target.type();
+        if (oldType == newType)  return target;
+        if (!canRetype(newType, oldType, raw))
+            return null;
+        // TO DO:  clone the target guy, whatever he is, with new type.
+        return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
+    }
+
+    static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
+        return new AsVarargsCollector(target, arrayType);
+    }
+
+    static class AsVarargsCollector extends AdapterMethodHandle {
+        final MethodHandle target;
+        final Class<?> arrayType;
+        MethodHandle cache;
+
+        AsVarargsCollector(MethodHandle target, Class<?> arrayType) {
+            super(target, target.type(), makeConv(OP_RETYPE_ONLY));
+            this.target = target;
+            this.arrayType = arrayType;
+            this.cache = target.asCollector(arrayType, 0);
+        }
+
+        @Override
+        public boolean isVarargsCollector() {
+            return true;
+        }
+
+        @Override
+        public MethodHandle asType(MethodType newType) {
+            MethodType type = this.type();
+            int collectArg = type.parameterCount() - 1;
+            int newArity = newType.parameterCount();
+            if (newArity == collectArg+1 &&
+                type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
+                // if arity and trailing parameter are compatible, do normal thing
+                return super.asType(newType);
+            }
+            // check cache
+            if (cache.type().parameterCount() == newArity)
+                return cache.asType(newType);
+            // build and cache a collector
+            int arrayLength = newArity - collectArg;
+            MethodHandle collector;
+            try {
+                collector = target.asCollector(arrayType, arrayLength);
+            } catch (IllegalArgumentException ex) {
+                throw new WrongMethodTypeException("cannot build collector");
+            }
+            cache = collector;
+            return collector.asType(newType);
+        }
+
+        @Override
+        public MethodHandle asVarargsCollector(Class<?> arrayType) {
+            MethodType type = this.type();
+            if (type.parameterType(type.parameterCount()-1) == arrayType)
+                return this;
+            return super.asVarargsCollector(arrayType);
+        }
+    }
+
+    /** Can a checkcast adapter validly convert the target to newType?
+     *  The JVM supports all kind of reference casts, even silly ones.
+     */
+    static boolean canCheckCast(MethodType newType, MethodType targetType,
+                int arg, Class<?> castType) {
+        if (!convOpSupported(OP_CHECK_CAST))  return false;
+        Class<?> src = newType.parameterType(arg);
+        Class<?> dst = targetType.parameterType(arg);
+        if (!canCheckCast(src, castType)
+                || !VerifyType.isNullConversion(castType, dst))
+            return false;
+        int diff = diffTypes(newType, targetType, false);
+        return (diff == arg+1);  // arg is sole non-trivial diff
+    }
+    /** Can an primitive conversion adapter validly convert src to dst? */
+    static boolean canCheckCast(Class<?> src, Class<?> dst) {
+        return (!src.isPrimitive() && !dst.isPrimitive());
+    }
+
+    /** Factory method:  Forces a cast at the given argument.
+     *  The castType is the target of the cast, and can be any type
+     *  with a null conversion to the corresponding target parameter.
+     *  Return null if this cannot be done.
+     */
+    static MethodHandle makeCheckCast(MethodType newType, MethodHandle target,
+                int arg, Class<?> castType) {
+        if (!canCheckCast(newType, target.type(), arg, castType))
+            return null;
+        long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
+        return new AdapterMethodHandle(target, newType, conv, castType);
+    }
+
+    /** Can an primitive conversion adapter validly convert the target to newType?
+     *  The JVM currently supports all conversions except those between
+     *  floating and integral types.
+     */
+    static boolean canPrimCast(MethodType newType, MethodType targetType,
+                int arg, Class<?> convType) {
+        if (!convOpSupported(OP_PRIM_TO_PRIM))  return false;
+        Class<?> src = newType.parameterType(arg);
+        Class<?> dst = targetType.parameterType(arg);
+        if (!canPrimCast(src, convType)
+                || !VerifyType.isNullConversion(convType, dst))
+            return false;
+        int diff = diffTypes(newType, targetType, false);
+        return (diff == arg+1);  // arg is sole non-trivial diff
+    }
+    /** Can an primitive conversion adapter validly convert src to dst? */
+    static boolean canPrimCast(Class<?> src, Class<?> dst) {
+        if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) {
+            return false;
+        } else if (Wrapper.forPrimitiveType(dst).isFloating()) {
+            // both must be floating types
+            return Wrapper.forPrimitiveType(src).isFloating();
+        } else {
+            // both are integral, and all combinations work fine
+            assert(Wrapper.forPrimitiveType(src).isIntegral() &&
+                   Wrapper.forPrimitiveType(dst).isIntegral());
+            return true;
+        }
+    }
+
+    /** Factory method:  Truncate the given argument with zero or sign extension,
+     *  and/or convert between single and doubleword versions of integer or float.
+     *  The convType is the target of the conversion, and can be any type
+     *  with a null conversion to the corresponding target parameter.
+     *  Return null if this cannot be done.
+     */
+    static MethodHandle makePrimCast(MethodType newType, MethodHandle target,
+                int arg, Class<?> convType) {
+        MethodType oldType = target.type();
+        if (!canPrimCast(newType, oldType, arg, convType))
+            return null;
+        Class<?> src = newType.parameterType(arg);
+        long conv = makeConv(OP_PRIM_TO_PRIM, arg, basicType(src), basicType(convType));
+        return new AdapterMethodHandle(target, newType, conv);
+    }
+
+    /** Can an unboxing conversion validly convert src to dst?
+     *  The JVM currently supports all kinds of casting and unboxing.
+     *  The convType is the unboxed type; it can be either a primitive or wrapper.
+     */
+    static boolean canUnboxArgument(MethodType newType, MethodType targetType,
+                int arg, Class<?> convType) {
+        if (!convOpSupported(OP_REF_TO_PRIM))  return false;
+        Class<?> src = newType.parameterType(arg);
+        Class<?> dst = targetType.parameterType(arg);
+        Class<?> boxType = Wrapper.asWrapperType(convType);
+        convType = Wrapper.asPrimitiveType(convType);
+        if (!canCheckCast(src, boxType)
+                || boxType == convType
+                || !VerifyType.isNullConversion(convType, dst))
+            return false;
+        int diff = diffTypes(newType, targetType, false);
+        return (diff == arg+1);  // arg is sole non-trivial diff
+    }
+    /** Can an primitive unboxing adapter validly convert src to dst? */
+    static boolean canUnboxArgument(Class<?> src, Class<?> dst) {
+        return (!src.isPrimitive() && Wrapper.asPrimitiveType(dst).isPrimitive());
+    }
+
+    /** Factory method:  Unbox the given argument.
+     *  Return null if this cannot be done.
+     */
+    static MethodHandle makeUnboxArgument(MethodType newType, MethodHandle target,
+                int arg, Class<?> convType) {
+        MethodType oldType = target.type();
+        Class<?> src = newType.parameterType(arg);
+        Class<?> dst = oldType.parameterType(arg);
+        Class<?> boxType = Wrapper.asWrapperType(convType);
+        Class<?> primType = Wrapper.asPrimitiveType(convType);
+        if (!canUnboxArgument(newType, oldType, arg, convType))
+            return null;
+        MethodType castDone = newType;
+        if (!VerifyType.isNullConversion(src, boxType))
+            castDone = newType.changeParameterType(arg, boxType);
+        long conv = makeConv(OP_REF_TO_PRIM, arg, T_OBJECT, basicType(primType));
+        MethodHandle adapter = new AdapterMethodHandle(target, castDone, conv, boxType);
+        if (castDone == newType)
+            return adapter;
+        return makeCheckCast(newType, adapter, arg, boxType);
+    }
+
+    /** Can an primitive boxing adapter validly convert src to dst? */
+    static boolean canBoxArgument(Class<?> src, Class<?> dst) {
+        if (!convOpSupported(OP_PRIM_TO_REF))  return false;
+        throw new UnsupportedOperationException("NYI");
+    }
+
+    /** Factory method:  Unbox the given argument.
+     *  Return null if this cannot be done.
+     */
+    static MethodHandle makeBoxArgument(MethodType newType, MethodHandle target,
+                int arg, Class<?> convType) {
+        // this is difficult to do in the JVM because it must GC
+        return null;
+    }
+
+    /** Can an adapter simply drop arguments to convert the target to newType? */
+    static boolean canDropArguments(MethodType newType, MethodType targetType,
+                int dropArgPos, int dropArgCount) {
+        if (dropArgCount == 0)
+            return canRetypeOnly(newType, targetType);
+        if (!convOpSupported(OP_DROP_ARGS))  return false;
+        if (diffReturnTypes(newType, targetType, false) != 0)
+            return false;
+        int nptypes = newType.parameterCount();
+        // parameter types must be the same up to the drop point
+        if (dropArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, dropArgPos, false) != 0)
+            return false;
+        int afterPos = dropArgPos + dropArgCount;
+        int afterCount = nptypes - afterPos;
+        if (dropArgPos < 0 || dropArgPos >= nptypes ||
+            dropArgCount < 1 || afterPos > nptypes ||
+            targetType.parameterCount() != nptypes - dropArgCount)
+            return false;
+        // parameter types after the drop point must also be the same
+        if (afterCount != 0 && diffParamTypes(newType, afterPos, targetType, dropArgPos, afterCount, false) != 0)
+            return false;
+        return true;
+    }
+
+    /** Factory method:  Drop selected arguments.
+     *  Allow unchecked retyping of remaining arguments, pairwise.
+     *  Return null if this is not possible.
+     */
+    static MethodHandle makeDropArguments(MethodType newType, MethodHandle target,
+                int dropArgPos, int dropArgCount) {
+        if (dropArgCount == 0)
+            return makeRetypeOnly(newType, target);
+        if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
+            return null;
+        // in  arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
+        // out arglist: [0: ...keep1 |                        dpos: keep2... ]
+        int keep2InPos  = dropArgPos + dropArgCount;
+        int dropSlot    = newType.parameterSlotDepth(keep2InPos);
+        int keep1InSlot = newType.parameterSlotDepth(dropArgPos);
+        int slotCount   = keep1InSlot - dropSlot;
+        assert(slotCount >= dropArgCount);
+        assert(target.type().parameterSlotCount() + slotCount == newType.parameterSlotCount());
+        long conv = makeConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
+        return new AdapterMethodHandle(target, newType, conv);
+    }
+
+    /** Can an adapter duplicate an argument to convert the target to newType? */
+    static boolean canDupArguments(MethodType newType, MethodType targetType,
+                int dupArgPos, int dupArgCount) {
+        if (!convOpSupported(OP_DUP_ARGS))  return false;
+        if (diffReturnTypes(newType, targetType, false) != 0)
+            return false;
+        int nptypes = newType.parameterCount();
+        if (dupArgCount < 0 || dupArgPos + dupArgCount > nptypes)
+            return false;
+        if (targetType.parameterCount() != nptypes + dupArgCount)
+            return false;
+        // parameter types must be the same up to the duplicated arguments
+        if (diffParamTypes(newType, 0, targetType, 0, nptypes, false) != 0)
+            return false;
+        // duplicated types must be, well, duplicates
+        if (diffParamTypes(newType, dupArgPos, targetType, nptypes, dupArgCount, false) != 0)
+            return false;
+        return true;
+    }
+
+    /** Factory method:  Duplicate the selected argument.
+     *  Return null if this is not possible.
+     */
+    static MethodHandle makeDupArguments(MethodType newType, MethodHandle target,
+                int dupArgPos, int dupArgCount) {
+        if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
+            return null;
+        if (dupArgCount == 0)
+            return target;
+        // in  arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
+        // out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
+        int keep2InPos  = dupArgPos + dupArgCount;
+        int dupSlot     = newType.parameterSlotDepth(keep2InPos);
+        int keep1InSlot = newType.parameterSlotDepth(dupArgPos);
+        int slotCount   = keep1InSlot - dupSlot;
+        assert(target.type().parameterSlotCount() - slotCount == newType.parameterSlotCount());
+        long conv = makeConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
+        return new AdapterMethodHandle(target, newType, conv);
+    }
+
+    /** Can an adapter swap two arguments to convert the target to newType? */
+    static boolean canSwapArguments(MethodType newType, MethodType targetType,
+                int swapArg1, int swapArg2) {
+        if (!convOpSupported(OP_SWAP_ARGS))  return false;
+        if (diffReturnTypes(newType, targetType, false) != 0)
+            return false;
+        if (swapArg1 >= swapArg2)  return false;  // caller resp
+        int nptypes = newType.parameterCount();
+        if (targetType.parameterCount() != nptypes)
+            return false;
+        if (swapArg1 < 0 || swapArg2 >= nptypes)
+            return false;
+        if (diffParamTypes(newType, 0, targetType, 0, swapArg1, false) != 0)
+            return false;
+        if (diffParamTypes(newType, swapArg1, targetType, swapArg2, 1, false) != 0)
+            return false;
+        if (diffParamTypes(newType, swapArg1+1, targetType, swapArg1+1, swapArg2-swapArg1-1, false) != 0)
+            return false;
+        if (diffParamTypes(newType, swapArg2, targetType, swapArg1, 1, false) != 0)
+            return false;
+        if (diffParamTypes(newType, swapArg2+1, targetType, swapArg2+1, nptypes-swapArg2-1, false) != 0)
+            return false;
+        return true;
+    }
+
+    /** Factory method:  Swap the selected arguments.
+     *  Return null if this is not possible.
+     */
+    static MethodHandle makeSwapArguments(MethodType newType, MethodHandle target,
+                int swapArg1, int swapArg2) {
+        if (swapArg1 == swapArg2)
+            return target;
+        if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
+        if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
+            return null;
+        Class<?> swapType = newType.parameterType(swapArg1);
+        // in  arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
+        // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
+        int swapSlot2  = newType.parameterSlotDepth(swapArg2 + 1);
+        long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(swapType), swapSlot2);
+        return new AdapterMethodHandle(target, newType, conv);
+    }
+
+    static int positiveRotation(int argCount, int rotateBy) {
+        assert(argCount > 0);
+        if (rotateBy >= 0) {
+            if (rotateBy < argCount)
+                return rotateBy;
+            return rotateBy % argCount;
+        } else if (rotateBy >= -argCount) {
+            return rotateBy + argCount;
+        } else {
+            return (-1-((-1-rotateBy) % argCount)) + argCount;
+        }
+    }
+
+    final static int MAX_ARG_ROTATION = 1;
+
+    /** Can an adapter rotate arguments to convert the target to newType? */
+    static boolean canRotateArguments(MethodType newType, MethodType targetType,
+                int firstArg, int argCount, int rotateBy) {
+        if (!convOpSupported(OP_ROT_ARGS))  return false;
+        if (argCount <= 2)  return false;  // must be a swap, not a rotate
+        rotateBy = positiveRotation(argCount, rotateBy);
+        if (rotateBy == 0)  return false;  // no rotation
+        if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
+            return false;  // too many argument positions
+        // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
+        if (diffReturnTypes(newType, targetType, false) != 0)
+            return false;
+        int nptypes = newType.parameterCount();
+        if (targetType.parameterCount() != nptypes)
+            return false;
+        if (firstArg < 0 || firstArg >= nptypes)  return false;
+        int argLimit = firstArg + argCount;
+        if (argLimit > nptypes)  return false;
+        if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
+            return false;
+        int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
+        // swap new chunk1 with target chunk2
+        if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
+            return false;
+        // swap new chunk2 with target chunk1
+        if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
+            return false;
+        return true;
+    }
+
+    /** Factory method:  Rotate the selected argument range.
+     *  Return null if this is not possible.
+     */
+    static MethodHandle makeRotateArguments(MethodType newType, MethodHandle target,
+                int firstArg, int argCount, int rotateBy) {
+        rotateBy = positiveRotation(argCount, rotateBy);
+        if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
+            return null;
+        // Decide whether it should be done as a right or left rotation,
+        // on the JVM stack.  Return the number of stack slots to rotate by,
+        // positive if right, negative if left.
+        int limit = firstArg + argCount;
+        int depth0 = newType.parameterSlotDepth(firstArg);
+        int depth1 = newType.parameterSlotDepth(limit-rotateBy);
+        int depth2 = newType.parameterSlotDepth(limit);
+        int chunk1Slots = depth0 - depth1; assert(chunk1Slots > 0);
+        int chunk2Slots = depth1 - depth2; assert(chunk2Slots > 0);
+        // From here on out, it assumes a single-argument shift.
+        assert(MAX_ARG_ROTATION == 1);
+        int srcArg, dstArg;
+        byte basicType;
+        if (chunk2Slots <= chunk1Slots) {
+            // Rotate right/down N (rotateBy = +N, N small, c2 small):
+            // in  arglist: [0: ...keep1 | arg1: c1...  | limit-N: c2 | limit: keep2... ]
+            // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1...   | limit: keep2... ]
+            srcArg = limit-1;
+            dstArg = firstArg;
+            basicType = basicType(newType.parameterType(srcArg));
+            assert(chunk2Slots == type2size(basicType));
+        } else {
+            // Rotate left/up N (rotateBy = -N, N small, c1 small):
+            // in  arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2...   | limit: keep2... ]
+            // out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
+            srcArg = firstArg;
+            dstArg = limit-1;
+            basicType = basicType(newType.parameterType(srcArg));
+            assert(chunk1Slots == type2size(basicType));
+        }
+        int dstSlot = newType.parameterSlotDepth(dstArg + 1);
+        long conv = makeSwapConv(OP_ROT_ARGS, srcArg, basicType, dstSlot);
+        return new AdapterMethodHandle(target, newType, conv);
+    }
+
+    /** Can an adapter spread an argument to convert the target to newType? */
+    static boolean canSpreadArguments(MethodType newType, MethodType targetType,
+                Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
+        if (!convOpSupported(OP_SPREAD_ARGS))  return false;
+        if (diffReturnTypes(newType, targetType, false) != 0)
+            return false;
+        int nptypes = newType.parameterCount();
+        // parameter types must be the same up to the spread point
+        if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
+            return false;
+        int afterPos = spreadArgPos + spreadArgCount;
+        int afterCount = nptypes - (spreadArgPos + 1);
+        if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
+            spreadArgCount < 0 ||
+            targetType.parameterCount() != afterPos + afterCount)
+            return false;
+        // parameter types after the spread point must also be the same
+        if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
+            return false;
+        // match the array element type to the spread arg types
+        Class<?> rawSpreadArgType = newType.parameterType(spreadArgPos);
+        if (rawSpreadArgType != spreadArgType && !canCheckCast(rawSpreadArgType, spreadArgType))
+            return false;
+        for (int i = 0; i < spreadArgCount; i++) {
+            Class<?> src = VerifyType.spreadArgElementType(spreadArgType, i);
+            Class<?> dst = targetType.parameterType(spreadArgPos + i);
+            if (src == null || !VerifyType.isNullConversion(src, dst))
+                return false;
+        }
+        return true;
+    }
+
+
+    /** Factory method:  Spread selected argument. */
+    static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target,
+                Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
+        MethodType targetType = target.type();
+        if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
+            return null;
+        // in  arglist: [0: ...keep1 | spos: spreadArg | spos+1:      keep2... ]
+        // out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
+        int keep2OutPos  = spreadArgPos + spreadArgCount;
+        int spreadSlot   = targetType.parameterSlotDepth(keep2OutPos);
+        int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);
+        int slotCount    = keep1OutSlot - spreadSlot;
+        assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+1));
+        assert(slotCount >= spreadArgCount);
+        long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, slotCount-1);
+        MethodHandle res = new AdapterMethodHandle(target, newType, conv, spreadArgType);
+        assert(res.type().parameterType(spreadArgPos) == spreadArgType);
+        return res;
+    }
+
+    // TO DO: makeCollectArguments, makeFlyby, makeRicochet
+
+    @Override
+    public String toString() {
+        return getNameString(nonAdapter((MethodHandle)vmtarget), this);
+    }
+
+    private static MethodHandle nonAdapter(MethodHandle mh) {
+        while (mh instanceof AdapterMethodHandle) {
+            mh = (MethodHandle) mh.vmtarget;
+        }
+        return mh;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2008, 2011, 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 sun.invoke.util.VerifyType;
+import sun.invoke.util.Wrapper;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * The flavor of method handle which emulates an invoke instruction
+ * on a predetermined argument.  The JVM dispatches to the correct method
+ * when the handle is created, not when it is invoked.
+ * @author jrose
+ */
+class BoundMethodHandle extends MethodHandle {
+    //MethodHandle vmtarget;           // next BMH or final DMH or methodOop
+    private final Object argument;     // argument to insert
+    private final int    vmargslot;    // position at which it is inserted
+
+    // Constructors in this class *must* be package scoped or private.
+
+    /** Bind a direct MH to its receiver (or first ref. argument).
+     *  The JVM will pre-dispatch the MH if it is not already static.
+     */
+    /*non-public*/ BoundMethodHandle(DirectMethodHandle mh, Object argument) {
+        super(mh.type().dropParameterTypes(0, 1));
+        // check the type now, once for all:
+        this.argument = checkReferenceArgument(argument, mh, 0);
+        this.vmargslot = this.type().parameterSlotCount();
+        initTarget(mh, 0);
+    }
+
+    /** Insert an argument into an arbitrary method handle.
+     *  If argnum is zero, inserts the first argument, etc.
+     *  The argument type must be a reference.
+     */
+    /*non-public*/ BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
+        this(mh.type().dropParameterTypes(argnum, argnum+1),
+             mh, argument, argnum);
+    }
+
+    /** Insert an argument into an arbitrary method handle.
+     *  If argnum is zero, inserts the first argument, etc.
+     */
+    /*non-public*/ BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
+        super(type);
+        if (mh.type().parameterType(argnum).isPrimitive())
+            this.argument = bindPrimitiveArgument(argument, mh, argnum);
+        else {
+            this.argument = checkReferenceArgument(argument, mh, argnum);
+        }
+        this.vmargslot = type.parameterSlotDepth(argnum);
+        initTarget(mh, argnum);
+    }
+
+    private void initTarget(MethodHandle mh, int argnum) {
+        //this.vmtarget = mh;  // maybe updated by JVM
+        MethodHandleNatives.init(this, mh, argnum);
+    }
+
+    /** For the AdapterMethodHandle subclass.
+     */
+    /*non-public*/ BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
+        super(type);
+        this.argument = argument;
+        this.vmargslot = vmargslot;
+        assert(this instanceof AdapterMethodHandle);
+    }
+
+    /** Initialize the current object as a self-bound method handle, binding it
+     *  as the first argument of the method handle {@code entryPoint}.
+     *  The invocation type of the resulting method handle will be the
+     *  same as {@code entryPoint},  except that the first argument
+     *  type will be dropped.
+     */
+    /*non-public*/ BoundMethodHandle(MethodHandle entryPoint) {
+        super(entryPoint.type().dropParameterTypes(0, 1));
+        this.argument = this; // kludge; get rid of
+        this.vmargslot = this.type().parameterSlotDepth(0);
+        initTarget(entryPoint, 0);
+    }
+
+    /** Make sure the given {@code argument} can be used as {@code argnum}-th
+     *  parameter of the given method handle {@code mh}, which must be a reference.
+     *  <p>
+     *  If this fails, throw a suitable {@code WrongMethodTypeException},
+     *  which will prevent the creation of an illegally typed bound
+     *  method handle.
+     */
+    final static Object checkReferenceArgument(Object argument, MethodHandle mh, int argnum) {
+        Class<?> ptype = mh.type().parameterType(argnum);
+        if (ptype.isPrimitive()) {
+            // fail
+        } else if (argument == null) {
+            return null;
+        } else if (VerifyType.isNullReferenceConversion(argument.getClass(), ptype)) {
+            return argument;
+        }
+        throw badBoundArgumentException(argument, mh, argnum);
+    }
+
+    /** Make sure the given {@code argument} can be used as {@code argnum}-th
+     *  parameter of the given method handle {@code mh}, which must be a primitive.
+     *  <p>
+     *  If this fails, throw a suitable {@code WrongMethodTypeException},
+     *  which will prevent the creation of an illegally typed bound
+     *  method handle.
+     */
+    final static Object bindPrimitiveArgument(Object argument, MethodHandle mh, int argnum) {
+        Class<?> ptype = mh.type().parameterType(argnum);
+        Wrapper  wrap = Wrapper.forPrimitiveType(ptype);
+        Object   zero  = wrap.zero();
+        if (zero == null) {
+            // fail
+        } else if (argument == null) {
+            if (ptype != int.class && wrap.isSubwordOrInt())
+                return Integer.valueOf(0);
+            else
+                return zero;
+        } else if (VerifyType.isNullReferenceConversion(argument.getClass(), zero.getClass())) {
+            if (ptype != int.class && wrap.isSubwordOrInt())
+                return Wrapper.INT.wrap(argument);
+            else
+                return argument;
+        }
+        throw badBoundArgumentException(argument, mh, argnum);
+    }
+
+    final static RuntimeException badBoundArgumentException(Object argument, MethodHandle mh, int argnum) {
+        String atype = (argument == null) ? "null" : argument.getClass().toString();
+        return new WrongMethodTypeException("cannot bind "+atype+" argument to parameter #"+argnum+" of "+mh.type());
+    }
+
+    @Override
+    public String toString() {
+        return addTypeString(baseName(), this);
+    }
+
+    /** Component of toString() before the type string. */
+    protected String baseName() {
+        MethodHandle mh = this;
+        while (mh instanceof BoundMethodHandle) {
+            Object info = MethodHandleNatives.getTargetInfo(mh);
+            if (info instanceof MethodHandle) {
+                mh = (MethodHandle) info;
+            } else {
+                String name = null;
+                if (info instanceof MemberName)
+                    name = ((MemberName)info).getName();
+                if (name != null)
+                    return name;
+                else
+                    return noParens(super.toString()); // "invoke", probably
+            }
+            assert(mh != this);
+        }
+        return noParens(mh.toString());
+    }
+
+    private static String noParens(String str) {
+        int paren = str.indexOf('(');
+        if (paren >= 0) str = str.substring(0, paren);
+        return str;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2008, 2011, 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 sun.invoke.empty.Empty;
+import sun.misc.Unsafe;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * A {@code CallSite} is a holder for a variable {@link MethodHandle},
+ * which is called its {@code target}.
+ * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
+ * all calls to the site's current target.
+ * A {@code CallSite} may be associated with several {@code invokedynamic}
+ * instructions, or it may be "free floating", associated with none.
+ * In any case, it may be invoked through an associated method handle
+ * called its {@linkplain #dynamicInvoker dynamic invoker}.
+ * <p>
+ * {@code CallSite} is an abstract class which does not allow
+ * direct subclassing by users.  It has three immediate,
+ * concrete subclasses that may be either instantiated or subclassed.
+ * <ul>
+ * <li>If a mutable target is not required, an {@code invokedynamic} instruction
+ * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
+ * <li>If a mutable target is required which has volatile variable semantics,
+ * because updates to the target must be immediately and reliably witnessed by other threads,
+ * a {@linkplain VolatileCallSite volatile call site} may be used.
+ * <li>Otherwise, if a mutable target is required,
+ * a {@linkplain MutableCallSite mutable call site} may be used.
+ * </ul>
+ * <p>
+ * A non-constant call site may be <em>relinked</em> by changing its target.
+ * The new target must have the same {@linkplain MethodHandle#type() type}
+ * as the previous target.
+ * Thus, though a call site can be relinked to a series of
+ * successive targets, it cannot change its type.
+ * <p>
+ * Here is a sample use of call sites and bootstrap methods which links every
+ * dynamic call site to print its arguments:
+<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
+static void test() throws Throwable {
+    // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
+    InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
+}
+private static void printArgs(Object... args) {
+  System.out.println(java.util.Arrays.deepToString(args));
+}
+private static final MethodHandle printArgs;
+static {
+  MethodHandles.Lookup lookup = MethodHandles.lookup();
+  Class thisClass = lookup.lookupClass();  // (who am I?)
+  printArgs = lookup.findStatic(thisClass,
+      "printArgs", MethodType.methodType(void.class, Object[].class));
+}
+private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
+  // ignore caller and name, but match the type:
+  return new ConstantCallSite(printArgs.asType(type));
+}
+</pre></blockquote>
+ * @author John Rose, JSR 292 EG
+ */
+abstract
+public class CallSite {
+    static { MethodHandleImpl.initStatics(); }
+
+    // Fields used only by the JVM.  Do not use or change.
+    private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
+    private int        vmindex;  // supplied by the JVM (BCI within calling method)
+
+    // The actual payload of this call site:
+    /*package-private*/
+    MethodHandle target;
+
+    /**
+     * Make a blank call site object with the given method type.
+     * An initial target method is supplied which will throw
+     * an {@link IllegalStateException} if called.
+     * <p>
+     * Before this {@code CallSite} object is returned from a bootstrap method,
+     * it is usually provided with a more useful target method,
+     * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+     * @throws NullPointerException if the proposed type is null
+     */
+    /*package-private*/
+    CallSite(MethodType type) {
+        target = type.invokers().uninitializedCallSite();
+    }
+
+    /**
+     * Make a blank call site object, possibly equipped with an initial target method handle.
+     * @param target the method handle which will be the initial target of the call site
+     * @throws NullPointerException if the proposed target is null
+     */
+    /*package-private*/
+    CallSite(MethodHandle target) {
+        target.type();  // null check
+        this.target = target;
+    }
+
+    /**
+     * Returns the type of this call site's target.
+     * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
+     * The {@code setTarget} method enforces this invariant by refusing any new target that does
+     * not have the previous target's type.
+     * @return the type of the current target, which is also the type of any future target
+     */
+    public MethodType type() {
+        return target.type();
+    }
+
+    /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
+     *  The parameters are JVM-specific.
+     */
+    void initializeFromJVM(String name,
+                           MethodType type,
+                           MemberName callerMethod,
+                           int        callerBCI) {
+        if (this.vmmethod != null) {
+            // FIXME
+            throw new BootstrapMethodError("call site has already been linked to an invokedynamic instruction");
+        }
+        if (!this.type().equals(type)) {
+            throw wrongTargetType(target, type);
+        }
+        this.vmindex  = callerBCI;
+        this.vmmethod = callerMethod;
+    }
+
+    /**
+     * Returns the target method of the call site, according to the
+     * behavior defined by this call site's specific class.
+     * The immediate subclasses of {@code CallSite} document the
+     * class-specific behaviors of this method.
+     *
+     * @return the current linkage state of the call site, its target method handle
+     * @see ConstantCallSite
+     * @see VolatileCallSite
+     * @see #setTarget
+     * @see ConstantCallSite#getTarget
+     * @see MutableCallSite#getTarget
+     * @see VolatileCallSite#getTarget
+     */
+    public abstract MethodHandle getTarget();
+
+    /**
+     * Updates the target method of this call site, according to the
+     * behavior defined by this call site's specific class.
+     * The immediate subclasses of {@code CallSite} document the
+     * class-specific behaviors of this method.
+     * <p>
+     * The type of the new target must be {@linkplain MethodType#equals equal to}
+     * the type of the old target.
+     *
+     * @param newTarget the new target
+     * @throws NullPointerException if the proposed new target is null
+     * @throws WrongMethodTypeException if the proposed new target
+     *         has a method type that differs from the previous target
+     * @see CallSite#getTarget
+     * @see ConstantCallSite#setTarget
+     * @see MutableCallSite#setTarget
+     * @see VolatileCallSite#setTarget
+     */
+    public abstract void setTarget(MethodHandle newTarget);
+
+    void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
+        MethodType oldType = oldTarget.type();
+        MethodType newType = newTarget.type();  // null check!
+        if (!newType.equals(oldType))
+            throw wrongTargetType(newTarget, oldType);
+    }
+
+    private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
+        return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
+    }
+
+    /**
+     * Produces a method handle equivalent to an invokedynamic instruction
+     * which has been linked to this call site.
+     * <p>
+     * This method is equivalent to the following code:
+     * <blockquote><pre>
+     * MethodHandle getTarget, invoker, result;
+     * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
+     * invoker = MethodHandles.exactInvoker(this.type());
+     * result = MethodHandles.foldArguments(invoker, getTarget)
+     * </pre></blockquote>
+     *
+     * @return a method handle which always invokes this call site's current target
+     */
+    public abstract MethodHandle dynamicInvoker();
+
+    /*non-public*/ MethodHandle makeDynamicInvoker() {
+        MethodHandle getTarget = MethodHandleImpl.bindReceiver(GET_TARGET, this);
+        MethodHandle invoker = MethodHandles.exactInvoker(this.type());
+        return MethodHandles.foldArguments(invoker, getTarget);
+    }
+
+    private static final MethodHandle GET_TARGET;
+    static {
+        try {
+            GET_TARGET = IMPL_LOOKUP.
+                findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
+        } catch (ReflectiveOperationException ignore) {
+            throw new InternalError();
+        }
+    }
+
+    /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
+    /*package-private*/
+    static Empty uninitializedCallSite() {
+        throw new IllegalStateException("uninitialized call site");
+    }
+
+    // unsafe stuff:
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final long TARGET_OFFSET;
+
+    static {
+        try {
+            TARGET_OFFSET = unsafe.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+
+    /*package-private*/
+    void setTargetNormal(MethodHandle newTarget) {
+        target = newTarget;
+    }
+    /*package-private*/
+    MethodHandle getTargetVolatile() {
+        return (MethodHandle) unsafe.getObjectVolatile(this, TARGET_OFFSET);
+    }
+    /*package-private*/
+    void setTargetVolatile(MethodHandle newTarget) {
+        unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
+    }
+
+    // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
+    static CallSite makeSite(MethodHandle bootstrapMethod,
+                             // Callee information:
+                             String name, MethodType type,
+                             // Extra arguments for BSM, if any:
+                             Object info,
+                             // Caller information:
+                             MemberName callerMethod, int callerBCI) {
+        Class<?> callerClass = callerMethod.getDeclaringClass();
+        Object caller = IMPL_LOOKUP.in(callerClass);
+        CallSite site;
+        try {
+            Object binding;
+            info = maybeReBox(info);
+            if (info == null) {
+                binding = bootstrapMethod.invokeGeneric(caller, name, type);
+            } else if (!info.getClass().isArray()) {
+                binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
+            } else {
+                Object[] argv = (Object[]) info;
+                maybeReBoxElements(argv);
+                if (3 + argv.length > 255)
+                    throw new BootstrapMethodError("too many bootstrap method arguments");
+                MethodType bsmType = bootstrapMethod.type();
+                if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
+                    binding = bootstrapMethod.invokeGeneric(caller, name, type, argv);
+                else
+                    binding = MethodHandles.spreadInvoker(bsmType, 3)
+                        .invokeGeneric(bootstrapMethod, caller, name, type, argv);
+            }
+            //System.out.println("BSM for "+name+type+" => "+binding);
+            if (binding instanceof CallSite) {
+                site = (CallSite) binding;
+            }  else {
+                throw new ClassCastException("bootstrap method failed to produce a CallSite");
+            }
+            assert(site.getTarget() != null);
+            assert(site.getTarget().type().equals(type));
+        } catch (Throwable ex) {
+            BootstrapMethodError bex;
+            if (ex instanceof BootstrapMethodError)
+                bex = (BootstrapMethodError) ex;
+            else
+                bex = new BootstrapMethodError("call site initialization exception", ex);
+            throw bex;
+        }
+        return site;
+    }
+
+    private static Object maybeReBox(Object x) {
+        if (x instanceof Integer) {
+            int xi = (int) x;
+            if (xi == (byte) xi)
+                x = xi;  // must rebox; see JLS 5.1.7
+        }
+        return x;
+    }
+    private static void maybeReBoxElements(Object[] xa) {
+        for (int i = 0; i < xa.length; i++) {
+            xa[i] = maybeReBox(xa[i]);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/ConstantCallSite.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010, 2011, 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;
+
+/**
+ * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
+ * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
+ * bound to the call site's target.
+ * @author John Rose, JSR 292 EG
+ */
+public class ConstantCallSite extends CallSite {
+    /**
+     * Creates a call site with a permanent target.
+     * @param target the target to be permanently associated with this call site
+     * @throws NullPointerException if the proposed target is null
+     */
+    public ConstantCallSite(MethodHandle target) {
+        super(target);
+    }
+
+    /**
+     * Returns the target method of the call site, which behaves
+     * like a {@code final} field of the {@code ConstantCallSite}.
+     * That is, the the target is always the original value passed
+     * to the constructor call which created this instance.
+     *
+     * @return the immutable linkage state of this call site, a constant method handle
+     * @throws UnsupportedOperationException because this kind of call site cannot change its target
+     */
+    @Override public final MethodHandle getTarget() {
+        return target;
+    }
+
+    /**
+     * Always throws an {@link UnsupportedOperationException}.
+     * This kind of call site cannot change its target.
+     * @param ignore a new target proposed for the call site, which is ignored
+     * @throws UnsupportedOperationException because this kind of call site cannot change its target
+     */
+    @Override public final void setTarget(MethodHandle ignore) {
+        throw new UnsupportedOperationException("ConstantCallSite");
+    }
+
+    /**
+     * Returns this call site's permanent target.
+     * Since that target will never change, this is a correct implementation
+     * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
+     * @return the immutable linkage state of this call site, a constant method handle
+     */
+    @Override
+    public final MethodHandle dynamicInvoker() {
+        return getTarget();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2008, 2011, 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 static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * The flavor of method handle which emulates invokespecial or invokestatic.
+ * @author jrose
+ */
+class DirectMethodHandle extends MethodHandle {
+    //inherited oop    vmtarget;    // methodOop or virtual class/interface oop
+    private final int  vmindex;     // method index within class or interface
+    { vmindex = VM_INDEX_UNINITIALIZED; }  // JVM may change this
+
+    // Constructors in this class *must* be package scoped or private.
+    DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class<?> lookupClass) {
+        super(mtype);
+
+        assert(m.isMethod() || !doDispatch && m.isConstructor());
+        if (!m.isResolved())
+            throw new InternalError();
+
+        MethodHandleNatives.init(this, (Object) m, doDispatch, lookupClass);
+    }
+
+    boolean isValid() {
+        return (vmindex != VM_INDEX_UNINITIALIZED);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java	Tue Mar 29 13:28:10 2011 -0700
@@ -0,0 +1,4496 @@
+/*
+ * Copyright (c) 2008, 2011, 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.lang.reflect.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * These adapters apply arbitrary conversions to arguments
+ * on the way to a ultimate target.
+ * For simplicity, these are all generically typed.
+ * @author jrose
+ */
+class FilterGeneric {
+    // type for the incoming call (will be generic)
+    private final MethodType entryType;
+    // prototype adapters (clone and customize for each new target & conversion!)
+    private final Adapter[] adapters;
+
+    /** Compute and cache information common to all filtering adapters
+     *  with the given generic type
+     */
+    FilterGeneric(MethodType entryType) {
+        this.entryType = entryType;
+        int tableSize = Kind.LIMIT.invokerIndex(1 + entryType.parameterCount());
+        this.adapters = new Adapter[tableSize];
+    }
+
+    Adapter getAdapter(Kind kind, int pos) {
+        int index = kind.invokerIndex(pos);
+        Adapter ad = adapters[index];
+        if (ad != null)  return ad;
+        ad = findAdapter(entryType, kind, pos);
+        if (ad == null)
+            ad = buildAdapterFromBytecodes(entryType, kind, pos);
+        adapters[index] = ad;
+        return ad;
+    }
+
+    Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
+        Adapter ad = getAdapter(kind, pos);
+        return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
+    }
+
+    /** Build an adapter of the given generic type, which invokes filter
+     *  on the selected incoming argument before passing it to the target.
+     * @param pos the argument to filter
+     * @param filter the function to call on the argument
+     * @param target the target to call with the modified argument list
+     * @return an adapter method handle
+     */
+    public static MethodHandle makeArgumentFilter(int pos, MethodHandle filter, MethodHandle target) {
+        return make(Kind.value, pos, filter, target);
+    }
+
+    /** Build an adapter of the given generic type, which invokes a combiner
+     *  on a selected group of leading arguments.
+     *  The result of the combiner is prepended before all those arguments.
+     * @param combiner the function to call on the selected leading arguments
+     * @param target the target to call with the modified argument list
+     * @return an adapter method handle
+     */
+    public static MethodHandle makeArgumentFolder(MethodHandle combiner, MethodHandle target) {
+        int num = combiner.type().parameterCount();
+        return make(Kind.fold, num, combiner, target);
+    }
+
+    /** Build an adapter of the given generic type, which invokes a filter
+     *  on the incoming arguments, reified as a group.
+     *  The argument may be modified (by side effects in the filter).
+     *  The arguments, possibly modified, are passed on to the target.
+     * @param filter the function to call on the arguments
+     * @param target the target to call with the possibly-modified argument list
+     * @return an adapter method handle
+     */
+    public static MethodHandle makeFlyby(MethodHandle filter, MethodHandle target) {
+        return make(Kind.flyby, 0, filter, target);
+    }
+
+    /** Build an adapter of the given generic type, which invokes a collector
+     *  on the selected incoming argument and all following arguments.
+     *  The result of the collector replaces all those arguments.
+     * @param collector the function to call on the selected trailing arguments
+     * @param target the target to call with the modified argument list
+     * @return an adapter method handle
+     */
+    public static MethodHandle makeArgumentCollector(MethodHandle collector, MethodHandle target) {
+        int pos = target.type().parameterCount() - 1;
+        return make(Kind.collect, pos, collector, target);
+    }
+
+    static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
+        FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
+        return fgen.makeInstance(kind, pos, filter, target);
+    }
+
+    /** Return the adapter information for this target and filter type. */
+    static FilterGeneric of(Kind kind, int pos, MethodType filterType, MethodType targetType) {
+        MethodType entryType = entryType(kind, pos, filterType, targetType);
+        if (entryType.generic() != entryType)
+            throw newIllegalArgumentException("must be generic: "+entryType);
+        MethodTypeForm form = entryType.form();
+        FilterGeneric filterGen = form.filterGeneric;
+        if (filterGen == null)
+            form.filterGeneric = filterGen = new FilterGeneric(entryType);
+        return filterGen;
+    }
+
+    public String toString() {
+        return "FilterGeneric/"+entryType;
+    }
+
+    static MethodType targetType(MethodType entryType, Kind kind, int pos, MethodType filterType) {
+        MethodType type = entryType;
+        switch (kind) {
+            case value:
+            case flyby:
+                break;  // no change
+            case fold:
+                type = type.insertParameterTypes(0, filterType.returnType());
+                break;
+            case collect:
+                type = type.dropParameterTypes(pos, type.parameterCount());
+                type = type.insertParameterTypes(pos, filterType.returnType());
+                break;
+            default:
+                throw new InternalError();
+        }
+        return type;
+    }
+
+    static MethodType entryType(Kind kind, int pos, MethodType filterType, MethodType targetType) {
+        MethodType type = targetType;
+        switch (kind) {
+            case value:
+            case flyby:
+                break;  // no change
+            case fold:
+                type = type.dropParameterTypes(0, 1);
+                break;
+            case collect:
+                type = type.dropParameterTypes(pos, pos+1);
+                type = type.insertParameterTypes(pos, filterType.parameterList());
+                break;
+            default:
+                throw new InternalError();
+        }
+        return type;
+    }
+
+    /* Create an adapter that handles spreading calls for the given type. */
+    static Adapter findAdapter(MethodType entryType, Kind kind, int pos) {
+        int argc = entryType.parameterCount();
+        String cname0 = "F"+argc;
+        String cname1 = "F"+argc+kind.key;
+        String[] cnames = { cname0, cname1 };
+        String iname = kind.invokerName(pos);
+        // e.g., F5; invoke_C3
+        for (String cname : cnames) {
+            Class<? extends Adapter> acls = Adapter.findSubClass(cname);
+            if (acls == null)  continue;
+            // see if it has the required invoke method
+            MethodHandle entryPoint = null;
+            try {
+                entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
+            } catch (ReflectiveOperationException ex) {
+            }
+            if (entryPoint == null)  continue;
+            Constructor<? extends Adapter> ctor = null;
+            try {
+                ctor = acls.getDeclaredConstructor(MethodHandle.class);
+            } catch (NoSuchMethodException ex) {
+            } catch (SecurityException ex) {
+            }
+            if (ctor == null)  continue;
+            try {
+                // Produce an instance configured as a prototype.
+                return ctor.newInstance(entryPoint);
+            } catch (IllegalArgumentException ex) {
+            } catch (InvocationTargetException wex) {
+                Throwable ex = wex.getTargetException();
+                if (ex instanceof Error)  throw (Error)ex;
+                if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
+            } catch (InstantiationException ex) {
+            } catch (IllegalAccessException ex) {
+            }
+        }
+        return null;
+    }
+
+    static Adapter buildAdapterFromBytecodes(MethodType entryType, Kind kind, int pos) {
+