Merge jdk7-b118
authortrims
Wed, 10 Nov 2010 20:40:19 -0800
changeset 3048b357910aa04a
parent 3042 bb30977193b0
parent 3047 aec1afae879d
child 3049 ecab7eefb8f2
child 3184 5e54a0a879e8
child 3186 e3ecd9555ff0
Merge
src/share/classes/java/dyn/JavaMethodHandle.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/java/dyn/BootstrapMethod.java	Wed Nov 10 20:40:19 2010 -0800
     1.3 @@ -0,0 +1,82 @@
     1.4 +/*
     1.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package java.dyn;
    1.30 +
    1.31 +import java.lang.annotation.*;
    1.32 +
    1.33 +/**
    1.34 + * Annotation on InvokeDynamic method calls which requests the JVM to use a specific
    1.35 + * <a href="package-summary.html#bsm">bootstrap method</a>
    1.36 + * to link the call.  This annotation is not retained as such in the class file,
    1.37 + * but is transformed into a constant-pool entry for the invokedynamic instruction which
    1.38 + * specifies the desired bootstrap method.
    1.39 + * <p>
    1.40 + * If only the <code>value</code> is given, it must name a subclass of {@link CallSite}
    1.41 + * with a constructor which accepts a class, string, and method type.
    1.42 + * If the <code>value</code> and <code>name</code> are both given, there must be
    1.43 + * a static method in the given class of the given name which accepts a class, string,
    1.44 + * and method type, and returns a reference coercible to {@link CallSite}.
    1.45 + * <p>
    1.46 + * This annotation can be placed either on the return type of a single {@link InvokeDynamic}
    1.47 + * call (see examples) or else it can be placed on an enclosing class or method, where it
    1.48 + * determines a default bootstrap method for any {@link InvokeDynamic} calls which are not
    1.49 + * specifically annotated with a bootstrap method.
    1.50 + * Every {@link InvokeDynamic} call must be given a bootstrap method.
    1.51 + * <p>
    1.52 + * Examples:
    1.53 +<blockquote><pre>
    1.54 +&#064;BootstrapMethod(value=MyLanguageRuntime.class, name="bootstrapDynamic")
    1.55 +String x = (String) InvokeDynamic.greet();
    1.56 +//BSM => MyLanguageRuntime.bootstrapDynamic(Here.class, "greet", methodType(String.class))
    1.57 +&#064;BootstrapMethod(MyCallSite.class)
    1.58 +void example() throws Throwable {
    1.59 +    InvokeDynamic.greet();
    1.60 +    //BSM => new MyCallSite(Here.class, "greet", methodType(void.class))
    1.61 +}
    1.62 +</pre></blockquote>
    1.63 + * <p>
    1.64 + */
    1.65 +@Target({ElementType.TYPE_USE,
    1.66 +            // For defaulting every indy site within a class or method; cf. @SuppressWarnings:
    1.67 +            ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR
    1.68 +            })
    1.69 +@Retention(RetentionPolicy.SOURCE)
    1.70 +public @interface BootstrapMethod {
    1.71 +    /** The class containing the bootstrap method. */
    1.72 +    Class<?> value();
    1.73 +
    1.74 +    /** The name of the bootstrap method.
    1.75 +     *  If this is the empty string, an instance of the bootstrap class is created,
    1.76 +     *  and a constructor is invoked.
    1.77 +     *  Otherwise, there must be a static method of the required name.
    1.78 +     */
    1.79 +    String name() default "";  // empty string denotes a constructor with 'new'
    1.80 +
    1.81 +    /** The argument types of the bootstrap method, as passed out by the JVM.
    1.82 +     *  There is usually no reason to override the default.
    1.83 +     */
    1.84 +    Class<?>[] arguments() default {Class.class, String.class, MethodType.class};
    1.85 +}
     2.1 --- a/src/share/classes/java/dyn/CallSite.java	Tue Nov 09 22:53:18 2010 -0800
     2.2 +++ b/src/share/classes/java/dyn/CallSite.java	Wed Nov 10 20:40:19 2010 -0800
     2.3 @@ -25,56 +25,26 @@
     2.4  
     2.5  package java.dyn;
     2.6  
     2.7 -import sun.dyn.Access;
     2.8 -import sun.dyn.MemberName;
     2.9 -import sun.dyn.CallSiteImpl;
    2.10 +import sun.dyn.*;
    2.11 +import java.util.Collection;
    2.12  
    2.13  /**
    2.14 - * A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode,
    2.15 - * and controls its linkage.
    2.16 - * Every linked {@code CallSite} object corresponds to a distinct instance
    2.17 - * of the {@code invokedynamic} instruction, and vice versa.
    2.18 + * A {@code CallSite} is a holder for a variable {@link MethodHandle},
    2.19 + * which is called its {@code target}.
    2.20 + * Every call to a {@code CallSite} is delegated to the site's current target.
    2.21   * <p>
    2.22 - * Every linked {@code CallSite} object has one state variable,
    2.23 - * a {@link MethodHandle} reference called the {@code target}.
    2.24 - * This reference is never null.  Though it can change its value
    2.25 - * successive values must always have exactly the {@link MethodType method type}
    2.26 - * called for by the bytecodes of the associated {@code invokedynamic} instruction
    2.27 + * A call site is initially created in an <em>unlinked</em> state,
    2.28 + * which is distinguished by a null target variable.
    2.29 + * Before the call site may be invoked (and before certain other
    2.30 + * operations are attempted), the call site must be linked to
    2.31 + * a non-null target.
    2.32   * <p>
    2.33 - * It is the responsibility of each class's
    2.34 - * {@link Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
    2.35 - * to produce call sites which have been pre-linked to an initial target method.
    2.36 - * The required {@link MethodType type} for the target method is a parameter
    2.37 - * to each bootstrap method call.
    2.38 - * <p>
    2.39 - * The bootstrap method may elect to produce call sites of a
    2.40 - * language-specific subclass of {@code CallSite}.  In such a case,
    2.41 - * the subclass may claim responsibility for initializing its target to
    2.42 - * a non-null value, by overriding {@link #initialTarget}.
    2.43 - * <p>
    2.44 - * An {@code invokedynamic} instruction which has not yet been executed
    2.45 - * is said to be <em>unlinked</em>.  When an unlinked call site is executed,
    2.46 - * the containing class's bootstrap method is called to manufacture a call site,
    2.47 - * for the instruction.  If the bootstrap method does not assign a non-null
    2.48 - * value to the new call site's target variable, the method {@link #initialTarget}
    2.49 - * is called to produce the new call site's first target method.
    2.50 - * <p>
    2.51 - * A freshly-created {@code CallSite} object is not yet in a linked state.
    2.52 - * An unlinked {@code CallSite} object reports null for its {@code callerClass}.
    2.53 - * When the JVM receives a {@code CallSite} object from a bootstrap method,
    2.54 - * it first ensures that its target is non-null and of the correct type.
    2.55 - * The JVM then links the {@code CallSite} object to the call site instruction,
    2.56 - * enabling the {@code callerClass} to return the class in which the instruction occurs.
    2.57 - * <p>
    2.58 - * Next, the JVM links the instruction to the {@code CallSite}, at which point
    2.59 - * any further execution of the {@code invokedynamic} instruction implicitly
    2.60 - * invokes the current target of the {@code CallSite} object.
    2.61 - * After this two-way linkage, both the instruction and the {@code CallSite}
    2.62 - * object are said to be linked.
    2.63 - * <p>
    2.64 - * This state of linkage continues until the method containing the
    2.65 - * dynamic call site is garbage collected, or the dynamic call site
    2.66 - * is invalidated by an explicit request.
    2.67 + * A call site may be <em>relinked</em> by changing its target.
    2.68 + * The new target must be non-null and must have the same
    2.69 + * {@linkplain MethodHandle#type() type}
    2.70 + * as the previous target.
    2.71 + * Thus, though a call site can be relinked to a series of
    2.72 + * successive targets, it cannot change its type.
    2.73   * <p>
    2.74   * Linkage happens once in the lifetime of any given {@code CallSite} object.
    2.75   * Because of call site invalidation, this linkage can be repeated for
    2.76 @@ -87,6 +57,10 @@
    2.77   * Here is a sample use of call sites and bootstrap methods which links every
    2.78   * dynamic call site to print its arguments:
    2.79  <blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
    2.80 +&#064;BootstrapMethod(value=PrintArgsDemo.class, name="bootstrapDynamic")
    2.81 +static void test() throws Throwable {
    2.82 +    InvokeDynamic.baz("baz arg", 2, 3.14);
    2.83 +}
    2.84  private static void printArgs(Object... args) {
    2.85    System.out.println(java.util.Arrays.deepToString(args));
    2.86  }
    2.87 @@ -96,17 +70,16 @@
    2.88    Class thisClass = lookup.lookupClass();  // (who am I?)
    2.89    printArgs = lookup.findStatic(thisClass,
    2.90        "printArgs", MethodType.methodType(void.class, Object[].class));
    2.91 -  Linkage.registerBootstrapMethod("bootstrapDynamic");
    2.92  }
    2.93  private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) {
    2.94    // ignore caller and name, but match the type:
    2.95    return new CallSite(MethodHandles.collectArguments(printArgs, type));
    2.96  }
    2.97  </pre></blockquote>
    2.98 - * @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
    2.99   * @author John Rose, JSR 292 EG
   2.100   */
   2.101  public class CallSite
   2.102 +    implements MethodHandleProvider
   2.103  {
   2.104      private static final Access IMPL_TOKEN = Access.getToken();
   2.105  
   2.106 @@ -209,6 +182,7 @@
   2.107       * {@code InvokeDynamicBootstrapError}, which in turn causes the
   2.108       * linkage of the {@code invokedynamic} instruction to terminate
   2.109       * abnormally.
   2.110 +     * @deprecated transitional form defined in EDR but removed in PFD
   2.111       */
   2.112      protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) {
   2.113          throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type);
   2.114 @@ -278,16 +252,44 @@
   2.115       */
   2.116      @Override
   2.117      public String toString() {
   2.118 -        StringBuilder buf = new StringBuilder("CallSite#");
   2.119 -        buf.append(hashCode());
   2.120 -        if (!isLinked())
   2.121 -            buf.append("[unlinked]");
   2.122 -        else
   2.123 -            buf.append("[")
   2.124 -                .append("from ").append(vmmethod.getDeclaringClass().getName())
   2.125 -                .append(" : ").append(getTarget().type())
   2.126 -                .append(" => ").append(getTarget())
   2.127 -                .append("]");
   2.128 -        return buf.toString();
   2.129 +        return "CallSite"+(target == null ? "" : target.type());
   2.130      }
   2.131 +
   2.132 +    /**
   2.133 +     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
   2.134 +     * Produce a method handle equivalent to an invokedynamic instruction
   2.135 +     * which has been linked to this call site.
   2.136 +     * <p>If this call site is a {@link ConstantCallSite}, this method
   2.137 +     * simply returns the call site's target, since that will not change.
   2.138 +     * <p>Otherwise, this method is equivalent to the following code:
   2.139 +     * <p><blockquote><pre>
   2.140 +     * MethodHandle getTarget, invoker, result;
   2.141 +     * getTarget = MethodHandles.lookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
   2.142 +     * invoker = MethodHandles.exactInvoker(this.type());
   2.143 +     * result = MethodHandles.foldArguments(invoker, getTarget)
   2.144 +     * </pre></blockquote>
   2.145 +     * @return a method handle which always invokes this call site's current target
   2.146 +     */
   2.147 +    public final MethodHandle dynamicInvoker() {
   2.148 +        if (this instanceof ConstantCallSite)
   2.149 +            return getTarget();  // will not change dynamically
   2.150 +        MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this);
   2.151 +        MethodHandle invoker = MethodHandles.exactInvoker(this.type());
   2.152 +        return MethodHandles.foldArguments(invoker, getTarget);
   2.153 +    }
   2.154 +    private static final MethodHandle GET_TARGET;
   2.155 +    static {
   2.156 +        try {
   2.157 +            GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP.
   2.158 +                findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
   2.159 +        } catch (NoAccessException ignore) {
   2.160 +            throw new InternalError();
   2.161 +        }
   2.162 +    }
   2.163 +
   2.164 +    /** Implementation of {@link MethodHandleProvider} which returns {@code this.dynamicInvoker()}. */
   2.165 +    public final MethodHandle asMethodHandle() { return dynamicInvoker(); }
   2.166 +
   2.167 +    /** Implementation of {@link MethodHandleProvider}, which returns {@code this.dynamicInvoker().asType(type)}. */
   2.168 +    public final MethodHandle asMethodHandle(MethodType type) { return dynamicInvoker().asType(type); }
   2.169  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/share/classes/java/dyn/ClassValue.java	Wed Nov 10 20:40:19 2010 -0800
     3.3 @@ -0,0 +1,173 @@
     3.4 +/*
     3.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Oracle designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Oracle in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.25 + * or visit www.oracle.com if you need additional information or have any
    3.26 + * questions.
    3.27 + */
    3.28 +
    3.29 +package java.dyn;
    3.30 +
    3.31 +import java.util.WeakHashMap;
    3.32 +import java.util.concurrent.atomic.AtomicInteger;
    3.33 +import java.util.concurrent.atomic.AtomicReference;
    3.34 +
    3.35 +/**
    3.36 + * Lazily associate a computed value with (potentially) every class.
    3.37 + * @author John Rose, JSR 292 EG
    3.38 + */
    3.39 +public abstract class ClassValue<T> {
    3.40 +    /**
    3.41 +     * Compute the given class's derived value for this {@code ClassValue}.
    3.42 +     * <p>
    3.43 +     * This method will be invoked within the first thread that accesses
    3.44 +     * the value with the {@link #get}.
    3.45 +     * <p>
    3.46 +     * Normally, this method is invoked at most once per class,
    3.47 +     * but it may be invoked again in case of subsequent invocations
    3.48 +     * of {@link #remove} followed by {@link #get}.
    3.49 +     *
    3.50 +     * @return the computed value for this thread-local
    3.51 +     */
    3.52 +    protected abstract T computeValue(Class<?> type);
    3.53 +
    3.54 +    /**
    3.55 +     * Creates a new class value.
    3.56 +     */
    3.57 +    protected ClassValue() {
    3.58 +    }
    3.59 +
    3.60 +    /**
    3.61 +     * Returns the value for the given class.
    3.62 +     * If no value has yet been computed, it is obtained by
    3.63 +     * by an invocation of the {@link #computeValue} method.
    3.64 +     * <p>
    3.65 +     * The actual installation of the value on the class
    3.66 +     * is performed while the class's synchronization lock
    3.67 +     * is held.  At that point, if racing threads have
    3.68 +     * computed values, one is chosen, and returned to
    3.69 +     * all the racing threads.
    3.70 +     *
    3.71 +     * @return the current thread's value of this thread-local
    3.72 +     */
    3.73 +    public T get(Class<?> type) {
    3.74 +        ClassValueMap map = getMap(type);
    3.75 +        if (map != null) {
    3.76 +            Object x = map.get(this);
    3.77 +            if (x != null) {
    3.78 +                return (T) map.unmaskNull(x);
    3.79 +            }
    3.80 +        }
    3.81 +        return setComputedValue(type);
    3.82 +    }
    3.83 +
    3.84 +    /**
    3.85 +     * Removes the associated value for the given class.
    3.86 +     * If this value is subsequently {@linkplain #get read} for the same class,
    3.87 +     * its value will be reinitialized by invoking its {@link #computeValue} method.
    3.88 +     * This may result in an additional invocation of the
    3.89 +     * {@code computeValue} method for the given class.
    3.90 +     */
    3.91 +    public void remove(Class<?> type) {
    3.92 +        ClassValueMap map = getMap(type);
    3.93 +        if (map != null) {
    3.94 +            synchronized (map) {
    3.95 +                map.remove(this);
    3.96 +            }
    3.97 +        }
    3.98 +    }
    3.99 +
   3.100 +    /// Implementation...
   3.101 +
   3.102 +    /** The hash code for this type is based on the identity of the object,
   3.103 +     *  and is well-dispersed for power-of-two tables.
   3.104 +     */
   3.105 +    public final int hashCode() { return hashCode; }
   3.106 +    private final int hashCode = HASH_CODES.getAndAdd(0x61c88647);
   3.107 +    private static final AtomicInteger HASH_CODES = new AtomicInteger();
   3.108 +
   3.109 +    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
   3.110 +
   3.111 +    /** Slow path for {@link #get}. */
   3.112 +    private T setComputedValue(Class<?> type) {
   3.113 +        ClassValueMap map = getMap(type);
   3.114 +        if (map == null) {
   3.115 +            map = initializeMap(type);
   3.116 +        }
   3.117 +        T value = computeValue(type);
   3.118 +        STORE_BARRIER.lazySet(0);
   3.119 +        // All stores pending from computeValue are completed.
   3.120 +        synchronized (map) {
   3.121 +            // Warm up the table with a null entry.
   3.122 +            map.preInitializeEntry(this);
   3.123 +        }
   3.124 +        // All stores pending from table expansion are completed.
   3.125 +        synchronized (map) {
   3.126 +            value = (T) map.initializeEntry(this, value);
   3.127 +            // One might fear a possible race condition here
   3.128 +            // if the code for map.put has flushed the write
   3.129 +            // to map.table[*] before the writes to the Map.Entry
   3.130 +            // are done.  This is not possible, since we have
   3.131 +            // warmed up the table with an empty entry.
   3.132 +        }
   3.133 +        return value;
   3.134 +    }
   3.135 +
   3.136 +    // Replace this map by a per-class slot.
   3.137 +    private static final WeakHashMap<Class<?>, ClassValueMap> ROOT
   3.138 +        = new WeakHashMap<Class<?>, ClassValueMap>();
   3.139 +
   3.140 +    private static ClassValueMap getMap(Class<?> type) {
   3.141 +        return ROOT.get(type);
   3.142 +    }
   3.143 +
   3.144 +    private static ClassValueMap initializeMap(Class<?> type) {
   3.145 +        synchronized (ClassValue.class) {
   3.146 +            ClassValueMap map = ROOT.get(type);
   3.147 +            if (map == null)
   3.148 +                ROOT.put(type, map = new ClassValueMap());
   3.149 +            return map;
   3.150 +        }
   3.151 +    }
   3.152 +
   3.153 +    static class ClassValueMap extends WeakHashMap<ClassValue, Object> {
   3.154 +        /** Make sure this table contains an Entry for the given key, even if it is empty. */
   3.155 +        void preInitializeEntry(ClassValue key) {
   3.156 +            if (!this.containsKey(key))
   3.157 +                this.put(key, null);
   3.158 +        }
   3.159 +        /** Make sure this table contains a non-empty Entry for the given key. */
   3.160 +        Object initializeEntry(ClassValue key, Object value) {
   3.161 +            Object prior = this.get(key);
   3.162 +            if (prior != null) {
   3.163 +                return unmaskNull(prior);
   3.164 +            }
   3.165 +            this.put(key, maskNull(value));
   3.166 +            return value;
   3.167 +        }
   3.168 +
   3.169 +        Object maskNull(Object x) {
   3.170 +            return x == null ? this : x;
   3.171 +        }
   3.172 +        Object unmaskNull(Object x) {
   3.173 +            return x == this ? null : x;
   3.174 +        }
   3.175 +    }
   3.176 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/share/classes/java/dyn/ConstantCallSite.java	Wed Nov 10 20:40:19 2010 -0800
     4.3 @@ -0,0 +1,43 @@
     4.4 +/*
     4.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.  Oracle designates this
    4.11 + * particular file as subject to the "Classpath" exception as provided
    4.12 + * by Oracle in the LICENSE file that accompanied this code.
    4.13 + *
    4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 + * version 2 for more details (a copy is included in the LICENSE file that
    4.18 + * accompanied this code).
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License version
    4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 + *
    4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 + * or visit www.oracle.com if you need additional information or have any
    4.26 + * questions.
    4.27 + */
    4.28 +
    4.29 +package java.dyn;
    4.30 +
    4.31 +/**
    4.32 + * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
    4.33 + * The only way to relink an {@code invokedynamic} instruction bound to a {@code ConstantCallSite} is
    4.34 + * to invalidate the instruction as a whole.
    4.35 + * @author John Rose, JSR 292 EG
    4.36 + */
    4.37 +public class ConstantCallSite extends CallSite {
    4.38 +    /** Create a call site with a permanent target. */
    4.39 +    public ConstantCallSite(MethodHandle target) {
    4.40 +        super(target);
    4.41 +    }
    4.42 +    /** Throw an {@link IllegalArgumentException}, because this kind of call site cannot change its target. */
    4.43 +    @Override public final void setTarget(MethodHandle ignore) {
    4.44 +        throw new IllegalArgumentException("ConstantCallSite");
    4.45 +    }
    4.46 +}
     5.1 --- a/src/share/classes/java/dyn/InvokeDynamic.java	Tue Nov 09 22:53:18 2010 -0800
     5.2 +++ b/src/share/classes/java/dyn/InvokeDynamic.java	Wed Nov 10 20:40:19 2010 -0800
     5.3 @@ -35,7 +35,7 @@
     5.4   * The target method is a property of the reified {@linkplain CallSite call site object}
     5.5   * which is linked to each active {@code invokedynamic} instruction.
     5.6   * The call site object is initially produced by a
     5.7 - * {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
     5.8 + * {@linkplain BootstrapMethod bootstrap method}
     5.9   * associated with the class whose bytecodes include the dynamic call site.
    5.10   * <p>
    5.11   * The type {@code InvokeDynamic} has no particular meaning as a
    5.12 @@ -45,22 +45,31 @@
    5.13   * It may be imported for ease of use.
    5.14   * <p>
    5.15   * Here are some examples:
    5.16 - * <p><blockquote><pre>
    5.17 - * Object x; String s; int i;
    5.18 - * x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
    5.19 - * s = InvokeDynamic.&lt;String&gt;hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
    5.20 - * InvokeDynamic.&lt;void&gt;cogito(); // cogito()V
    5.21 - * i = InvokeDynamic.&lt;int&gt;#"op:+"(2, 3); // "op:+"(II)I
    5.22 - * </pre></blockquote>
    5.23 +<blockquote><pre><!-- see indy-demo/src/JavaDocExamples.java -->
    5.24 +&#064;BootstrapMethod(value=Here.class, name="bootstrapDynamic")
    5.25 +static void example() throws Throwable {
    5.26 +    Object x; String s; int i;
    5.27 +    x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
    5.28 +    s = (String) InvokeDynamic.hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
    5.29 +    InvokeDynamic.cogito(); // cogito()V
    5.30 +    i = (int) InvokeDynamic.#"op:+"(2, 3); // "op:+"(II)I
    5.31 +}
    5.32 +static MethodHandle bootstrapDynamic(Class caller, String name, MethodType type) { ... }
    5.33 +</pre></blockquote>
    5.34   * Each of the above calls generates a single invokedynamic instruction
    5.35   * with the name-and-type descriptors indicated in the comments.
    5.36 + * <p>
    5.37   * The argument types are taken directly from the actual arguments,
    5.38 - * while the return type is taken from the type parameter.
    5.39 - * (This type parameter may be a primtive, and it defaults to {@code Object}.)
    5.40 + * while the return type corresponds to the target of the assignment.
    5.41 + * (Currently, the return type must be given as a false type parameter.
    5.42 + * This type parameter is an irregular use of the generic type syntax,
    5.43 + * and is likely to change in favor of a convention based on target typing.)
    5.44 + * <p>
    5.45   * The final example uses a special syntax for uttering non-Java names.
    5.46   * Any name legal to the JVM may be given between the double quotes.
    5.47 + * <p>
    5.48   * None of these calls is complete without a bootstrap method,
    5.49 - * which must be registered by the static initializer of the enclosing class.
    5.50 + * which must be declared for the enclosing class or method.
    5.51   * @author John Rose, JSR 292 EG
    5.52   */
    5.53  @MethodHandle.PolymorphicSignature
     6.1 --- a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Tue Nov 09 22:53:18 2010 -0800
     6.2 +++ b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Wed Nov 10 20:40:19 2010 -0800
     6.3 @@ -28,15 +28,11 @@
     6.4  /**
     6.5   * Thrown to indicate that an {@code invokedynamic} instruction has
     6.6   * failed to find its
     6.7 - * {@linkplain Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method},
     6.8 + * {@linkplain BootstrapMethod bootstrap method},
     6.9   * or the bootstrap method has
    6.10   * failed to provide a
    6.11   * {@linkplain CallSite} call site with a non-null {@linkplain MethodHandle target}
    6.12   * of the correct {@linkplain MethodType method type}.
    6.13 - * <p>
    6.14 - * The bootstrap method must have been declared during a class's initialization
    6.15 - * by a call to one of the overloadings of
    6.16 - * {@link Linkage#registerBootstrapMethod registerBootstrapMethod}.
    6.17   *
    6.18   * @author John Rose, JSR 292 EG
    6.19   * @since 1.7
     7.1 --- a/src/share/classes/java/dyn/JavaMethodHandle.java	Tue Nov 09 22:53:18 2010 -0800
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,237 +0,0 @@
     7.4 -/*
     7.5 - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
     7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 - *
     7.8 - * This code is free software; you can redistribute it and/or modify it
     7.9 - * under the terms of the GNU General Public License version 2 only, as
    7.10 - * published by the Free Software Foundation.  Oracle designates this
    7.11 - * particular file as subject to the "Classpath" exception as provided
    7.12 - * by Oracle in the LICENSE file that accompanied this code.
    7.13 - *
    7.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 - * version 2 for more details (a copy is included in the LICENSE file that
    7.18 - * accompanied this code).
    7.19 - *
    7.20 - * You should have received a copy of the GNU General Public License version
    7.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 - *
    7.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 - * or visit www.oracle.com if you need additional information or have any
    7.26 - * questions.
    7.27 - */
    7.28 -
    7.29 -package java.dyn;
    7.30 -
    7.31 -import sun.dyn.Access;
    7.32 -
    7.33 -/**
    7.34 - * A Java method handle is a deprecated proposal for extending
    7.35 - * the basic method handle type with additional
    7.36 - * programmer defined methods and fields.
    7.37 - * Its behavior as a method handle is determined at instance creation time,
    7.38 - * by providing the new instance with an "entry point" method handle
    7.39 - * to handle calls.  This entry point must accept a leading argument
    7.40 - * whose type is the Java method handle itself or a supertype, and the
    7.41 - * entry point is always called with the Java method handle itself as
    7.42 - * the first argument.  This is similar to ordinary virtual methods, which also
    7.43 - * accept the receiver object {@code this} as an implicit leading argument.
    7.44 - * The {@code MethodType} of the Java method handle is the same as that
    7.45 - * of the entry point method handle, with the leading parameter type
    7.46 - * omitted.
    7.47 - * <p>
    7.48 - * Here is an example of usage, creating a hybrid object/functional datum:
    7.49 - * <p><blockquote><pre>
    7.50 - * class Greeter extends JavaMethodHandle {
    7.51 - *     private String greeting = "hello";
    7.52 - *     public void setGreeting(String s) { greeting = s; }
    7.53 - *     public void run() { System.out.println(greeting+", "+greetee); }
    7.54 - *     private final String greetee;
    7.55 - *     Greeter(String greetee) {
    7.56 - *         super(RUN); // alternatively, super("run")
    7.57 - *         this.greetee = greetee;
    7.58 - *     }
    7.59 - *     // the entry point function is computed once:
    7.60 - *     private static final MethodHandle RUN
    7.61 - *         = MethodHandles.lookup().findVirtual(Greeter.class, "run",
    7.62 - *               MethodType.make(void.class));
    7.63 - * }
    7.64 - * // class Main { public static void main(String... av) { ...
    7.65 - * Greeter greeter = new Greeter("world");
    7.66 - * greeter.run();  // prints "hello, world"
    7.67 - * // Statically typed method handle invocation (most direct):
    7.68 - * MethodHandle mh = greeter;
    7.69 - * mh.&lt;void&gt;invokeExact();  // also prints "hello, world"
    7.70 - * // Dynamically typed method handle invocation:
    7.71 - * MethodHandles.invokeExact(greeter);  // also prints "hello, world"
    7.72 - * greeter.setGreeting("howdy");
    7.73 - * mh.invokeExact();  // prints "howdy, world" (object-like mutable behavior)
    7.74 - * </pre></blockquote>
    7.75 - * <p>
    7.76 - * In the example of {@code Greeter}, the method {@code run} provides the entry point.
    7.77 - * The entry point need not be a constant value; it may be independently
    7.78 - * computed in each call to the constructor.  The entry point does not
    7.79 - * even need to be a method on the {@code Greeter} class, though
    7.80 - * that is the typical case.
    7.81 - * <p>
    7.82 - * The entry point may also be provided symbolically, in which case the the
    7.83 - * {@code JavaMethodHandle} constructor performs the lookup of the entry point.
    7.84 - * This makes it possible to use {@code JavaMethodHandle} to create an anonymous
    7.85 - * inner class:
    7.86 - * <p><blockquote><pre>
    7.87 - * // We can also do this with symbolic names and/or inner classes:
    7.88 - * MethodHandles.invokeExact(new JavaMethodHandle("yow") {
    7.89 - *     void yow() { System.out.println("yow, world"); }
    7.90 - * });
    7.91 - * </pre></blockquote>
    7.92 - * <p>
    7.93 - * Here is similar lower-level code which works in terms of a bound method handle.
    7.94 - * <p><blockquote><pre>
    7.95 - *     class Greeter {
    7.96 - *         public void run() { System.out.println("hello, "+greetee); }
    7.97 - *         private final String greetee;
    7.98 - *         Greeter(String greetee) { this.greetee = greetee; }
    7.99 - *         // the entry point function is computed once:
   7.100 - *         private static final MethodHandle RUN
   7.101 - *             = MethodHandles.findVirtual(Greeter.class, "run",
   7.102 - *                   MethodType.make(void.class));
   7.103 - *     }
   7.104 - *     // class Main { public static void main(String... av) { ...
   7.105 - *     Greeter greeter = new Greeter("world");
   7.106 - *     greeter.run();  // prints "hello, world"
   7.107 - *     MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
   7.108 - *     mh.invokeExact();  // also prints "hello, world"
   7.109 - * </pre></blockquote>
   7.110 - * Note that the method handle must be separately created as a view on the base object.
   7.111 - * This increases footprint, complexity, and dynamic indirections.
   7.112 - * <p>
   7.113 - * Here is a pure functional value expressed most concisely as an anonymous inner class:
   7.114 - * <p><blockquote><pre>
   7.115 - *     // class Main { public static void main(String... av) { ...
   7.116 - *     final String greetee = "world";
   7.117 - *     MethodHandle greeter = new JavaMethodHandle("run") {
   7.118 - *         private void run() { System.out.println("hello, "+greetee); }
   7.119 - *     }
   7.120 - *     greeter.invokeExact();  // prints "hello, world"
   7.121 - * </pre></blockquote>
   7.122 - * <p>
   7.123 - * Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
   7.124 - * and instantiated as an anonymous class.  The data structure is a handle to 1-D array,
   7.125 - * with a specialized index type (long).  It is created by inner class, and uses
   7.126 - * signature-polymorphic APIs throughout.
   7.127 - * <p><blockquote><pre>
   7.128 - *     abstract class AssignableMethodHandle extends JavaMethodHandle {
   7.129 - *       private final MethodHandle setter;
   7.130 - *       public MethodHandle setter() { return setter; }
   7.131 - *       public AssignableMethodHandle(String get, String set) {
   7.132 - *         super(get);
   7.133 - *         MethodType getType = this.type();
   7.134 - *         MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
   7.135 - *         this.setter = MethodHandles.publicLookup().bind(this, set, setType);
   7.136 - *       }
   7.137 - *     }
   7.138 - *     // class Main { public static void main(String... av) { ...
   7.139 - *     final Number[] stuff = { 123, 456 };
   7.140 - *     AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
   7.141 - *         public Number get(long i)           { return stuff[(int)i]; }
   7.142 - *         public void   set(long i, Object x) {        stuff[(int)i] = x; }
   7.143 - *     }
   7.144 - *     int x = (Integer) stuffPtr.&lt;Number&gt;invokeExact(1L);  // 456
   7.145 - *     stuffPtr.setter().&lt;void&gt;invokeExact(0L, (Number) 789);  // replaces 123 with 789
   7.146 - * </pre></blockquote>
   7.147 - * @see MethodHandle
   7.148 - * @deprecated The JSR 292 EG intends to replace {@code JavaMethodHandle} with
   7.149 - * an interface-based API for mixing method handle behavior with other classes.
   7.150 - * @author John Rose, JSR 292 EG
   7.151 - */
   7.152 -public abstract class JavaMethodHandle
   7.153 -        // Note: This is an implementation inheritance hack, and will be removed
   7.154 -        // with a JVM change which moves the required hidden behavior onto this class.
   7.155 -        extends sun.dyn.BoundMethodHandle
   7.156 -{
   7.157 -    private static final Access IMPL_TOKEN = Access.getToken();
   7.158 -
   7.159 -    /**
   7.160 -     * When creating a {@code JavaMethodHandle}, the actual method handle
   7.161 -     * invocation behavior will be delegated to the specified {@code entryPoint}.
   7.162 -     * This may be any method handle which can take the newly constructed object
   7.163 -     * as a leading parameter.
   7.164 -     * <p>
   7.165 -     * The method handle type of {@code this} (i.e, the fully constructed object)
   7.166 -     * will be {@code entryPoint}, minus the leading argument.
   7.167 -     * The leading argument will be bound to {@code this} on every method
   7.168 -     * handle invocation.
   7.169 -     * @param entryPoint the method handle to handle calls
   7.170 -     */
   7.171 -    protected JavaMethodHandle(MethodHandle entryPoint) {
   7.172 -        super(entryPoint);
   7.173 -    }
   7.174 -
   7.175 -    /**
   7.176 -     * Create a method handle whose entry point is a non-static method
   7.177 -     * visible in the exact (most specific) class of
   7.178 -     * the newly constructed object.
   7.179 -     * <p>
   7.180 -     * The method is specified by name and type, as if via this expression:
   7.181 -     * {@code MethodHandles.lookup().findVirtual(this.getClass(), name, type)}.
   7.182 -     * The class defining the method might be an anonymous inner class.
   7.183 -     * <p>
   7.184 -     * The method handle type of {@code this} (i.e, the fully constructed object)
   7.185 -     * will be the given method handle type.
   7.186 -     * A call to {@code this} will invoke the selected method.
   7.187 -     * The receiver argument will be bound to {@code this} on every method
   7.188 -     * handle invocation.
   7.189 -     * <p>
   7.190 -     * <i>Rationale:</i>
   7.191 -     * Although this constructor may seem to be a mere luxury,
   7.192 -     * it is not subsumed by the more general constructor which
   7.193 -     * takes any {@code MethodHandle} as the entry point argument.
   7.194 -     * In order to convert an entry point name to a method handle,
   7.195 -     * the self-class of the object is required (in order to do
   7.196 -     * the lookup).  The self-class, in turn, is generally not
   7.197 -     * available at the time of the constructor invocation,
   7.198 -     * due to the rules of Java and the JVM verifier.
   7.199 -     * One cannot call {@code this.getClass()}, because
   7.200 -     * the value of {@code this} is inaccessible at the point
   7.201 -     * of the constructor call.  (Changing this would require
   7.202 -     * change to the Java language, verifiers, and compilers.)
   7.203 -     * In particular, this constructor allows {@code JavaMethodHandle}s
   7.204 -     * to be created in combination with the anonymous inner class syntax.
   7.205 -     * @param entryPointName the name of the entry point method
   7.206 -     * @param type (optional) the desired type of the method handle
   7.207 -     */
   7.208 -    protected JavaMethodHandle(String entryPointName, MethodType type) {
   7.209 -        super(entryPointName, type, true);
   7.210 -
   7.211 -    }
   7.212 -
   7.213 -    /**
   7.214 -     * Create a method handle whose entry point is a non-static method
   7.215 -     * visible in the exact (most specific) class of
   7.216 -     * the newly constructed object.
   7.217 -     * <p>
   7.218 -     * The method is specified only by name.
   7.219 -     * There must be exactly one method of that name visible in the object class,
   7.220 -     * either inherited or locally declared.
   7.221 -     * (That is, the method must not be overloaded.)
   7.222 -     * <p>
   7.223 -     * The method handle type of {@code this} (i.e, the fully constructed object)
   7.224 -     * will be the same as the type of the selected non-static method.
   7.225 -     * The receiver argument will be bound to {@code this} on every method
   7.226 -     * handle invocation.
   7.227 -     * <p>ISSUE: This signature wildcarding feature does not correspond to
   7.228 -     * any MethodHandles.Lookup API element.  Can we eliminate it?
   7.229 -     * Alternatively, it is useful for naming non-overloaded methods.
   7.230 -     * Shall we make type arguments optional in the Lookup methods,
   7.231 -     * throwing an error in cases of ambiguity?
   7.232 -     * <p>
   7.233 -     * For this method's rationale, see the documentation
   7.234 -     * for {@link #JavaMethodHandle(String,MethodType)}.
   7.235 -     * @param entryPointName the name of the entry point method
   7.236 -     */
   7.237 -    protected JavaMethodHandle(String entryPointName) {
   7.238 -        super(entryPointName, (MethodType) null, false);
   7.239 -    }
   7.240 -}
     8.1 --- a/src/share/classes/java/dyn/Linkage.java	Tue Nov 09 22:53:18 2010 -0800
     8.2 +++ b/src/share/classes/java/dyn/Linkage.java	Wed Nov 10 20:40:19 2010 -0800
     8.3 @@ -25,7 +25,6 @@
     8.4  
     8.5  package java.dyn;
     8.6  
     8.7 -import java.lang.annotation.Annotation;
     8.8  import java.dyn.MethodHandles.Lookup;
     8.9  import java.util.WeakHashMap;
    8.10  import sun.dyn.Access;
    8.11 @@ -56,11 +55,7 @@
    8.12       * <li>the class containing the {@code invokedynamic} instruction, for which the bootstrap method was registered
    8.13       * <li>the name of the method being invoked (a {@link String})
    8.14       * <li>the type of the method being invoked (a {@link MethodType})
    8.15 -     * <li><em>TBD</em> optionally, an unordered array of {@link Annotation}s attached to the call site
    8.16 -     *     <em>(Until this feature is implemented, this will always receive an empty array.)</em>
    8.17       * </ul>
    8.18 -     * <em>(TBD: The final argument type may be missing from the method handle's type.
    8.19 -     * Additional arguments may be added in the future.)</em>
    8.20       * The bootstrap method acts as a factory method which accepts the given arguments
    8.21       * and returns a {@code CallSite} object (possibly of a subclass of {@code CallSite}).
    8.22       * <p>
    8.23 @@ -86,6 +81,7 @@
    8.24       *            or is already running in another thread
    8.25       * @exception SecurityException if there is a security manager installed,
    8.26       *            and a {@link LinkagePermission} check fails for "registerBootstrapMethod"
    8.27 +     * @deprecated Use @{@link BootstrapMethod} annotations instead
    8.28       */
    8.29      public static
    8.30      void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
    8.31 @@ -97,14 +93,9 @@
    8.32  
    8.33      static private void checkBSM(MethodHandle mh) {
    8.34          if (mh == null)  throw newIllegalArgumentException("null bootstrap method");
    8.35 -        if (mh.type() == BOOTSTRAP_METHOD_TYPE_2)
    8.36 -            // For now, always pass an empty array for the Annotations argument
    8.37 -            mh = MethodHandles.insertArguments(mh, BOOTSTRAP_METHOD_TYPE_2.parameterCount()-1,
    8.38 -                                               (Object)NO_ANNOTATIONS);
    8.39          if (mh.type() == BOOTSTRAP_METHOD_TYPE)  return;
    8.40          throw new WrongMethodTypeException(mh.toString());
    8.41      }
    8.42 -    static private final Annotation[] NO_ANNOTATIONS = { };
    8.43  
    8.44      /**
    8.45       * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
    8.46 @@ -115,6 +106,7 @@
    8.47       * @throws NoSuchMethodException if there is no such method
    8.48       * @throws IllegalStateException if the caller class's static initializer
    8.49       *         has already run, or is already running in another thread
    8.50 +     * @deprecated Use @{@link BootstrapMethod} annotations instead
    8.51       */
    8.52      public static
    8.53      void registerBootstrapMethod(Class<?> runtime, String name) {
    8.54 @@ -131,6 +123,7 @@
    8.55       * @throws IllegalArgumentException if there is no such method
    8.56       * @throws IllegalStateException if the caller class's static initializer
    8.57       *         has already run, or is already running in another thread
    8.58 +     * @deprecated Use @{@link BootstrapMethod} annotations instead
    8.59       */
    8.60      public static
    8.61      void registerBootstrapMethod(String name) {
    8.62 @@ -142,18 +135,10 @@
    8.63      void registerBootstrapMethodLookup(Class<?> callerClass, Class<?> runtime, String name) {
    8.64          Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
    8.65          MethodHandle bootstrapMethod;
    8.66 -        // Try both types.  TBD
    8.67          try {
    8.68 -            bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE_2);
    8.69 +            bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
    8.70          } catch (NoAccessException ex) {
    8.71 -            bootstrapMethod = null;
    8.72 -        }
    8.73 -        if (bootstrapMethod == null) {
    8.74 -            try {
    8.75 -                bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
    8.76 -            } catch (NoAccessException ex) {
    8.77 -                throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
    8.78 -            }
    8.79 +            throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
    8.80          }
    8.81          checkBSM(bootstrapMethod);
    8.82          MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
    8.83 @@ -172,6 +157,7 @@
    8.84       *            and the immediate caller of this method is not in the same
    8.85       *            package as the caller class
    8.86       *            and a {@link LinkagePermission} check fails for "getBootstrapMethod"
    8.87 +     * @deprecated
    8.88       */
    8.89      public static
    8.90      MethodHandle getBootstrapMethod(Class callerClass) {
    8.91 @@ -188,10 +174,6 @@
    8.92      public static final MethodType BOOTSTRAP_METHOD_TYPE
    8.93              = MethodType.methodType(CallSite.class,
    8.94                                      Class.class, String.class, MethodType.class);
    8.95 -    static final MethodType BOOTSTRAP_METHOD_TYPE_2
    8.96 -            = MethodType.methodType(CallSite.class,
    8.97 -                                    Class.class, String.class, MethodType.class,
    8.98 -                                    Annotation[].class);
    8.99  
   8.100      /**
   8.101       * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
     9.1 --- a/src/share/classes/java/dyn/LinkagePermission.java	Tue Nov 09 22:53:18 2010 -0800
     9.2 +++ b/src/share/classes/java/dyn/LinkagePermission.java	Wed Nov 10 20:40:19 2010 -0800
     9.3 @@ -31,6 +31,7 @@
     9.4  import java.util.StringTokenizer;
     9.5  
     9.6  /**
     9.7 + * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
     9.8   * This class is for managing runtime permission checking for
     9.9   * operations performed by methods in the {@link Linkage} class.
    9.10   * Like a {@link RuntimePermission}, on which it is modeled,
    9.11 @@ -52,13 +53,6 @@
    9.12   * </tr>
    9.13   *
    9.14   * <tr>
    9.15 - *   <td>registerBootstrapMethod.{class name}</td>
    9.16 - *   <td>Specifying a bootstrap method for {@code invokedynamic} instructions within a class of the given name</td>
    9.17 - *   <td>An attacker could attempt to attach a bootstrap method to a class which
    9.18 - *       has just been loaded, thus gaining control of its {@code invokedynamic} calls.</td>
    9.19 - * </tr>
    9.20 - *
    9.21 - * <tr>
    9.22   *   <td>invalidateAll</td>
    9.23   *   <td>Force the relinking of invokedynamic call sites everywhere.</td>
    9.24   *   <td>This could allow an attacker to slow down the system,
    9.25 @@ -73,8 +67,9 @@
    9.26   *   <td>See {@code invalidateAll}.</td>
    9.27   * </tr>
    9.28   * </table>
    9.29 + * <p>ISSUE: Is this still needed?
    9.30   *
    9.31 - * @see java.security.RuntimePermission
    9.32 + * @see java.lang.RuntimePermission
    9.33   * @see java.lang.SecurityManager
    9.34   *
    9.35   * @author John Rose, JSR 292 EG
    9.36 @@ -86,7 +81,7 @@
    9.37      /**
    9.38       * Create a new LinkagePermission with the given name.
    9.39       * The name is the symbolic name of the LinkagePermission, such as
    9.40 -     * "registerBootstrapMethod", "invalidateCallerClass.*", etc. An asterisk
    9.41 +     * "invalidateCallerClass.*", etc. An asterisk
    9.42       * may appear at the end of the name, following a ".", or by itself, to
    9.43       * signify a wildcard match.
    9.44       *
    10.1 --- a/src/share/classes/java/dyn/MethodHandle.java	Tue Nov 09 22:53:18 2010 -0800
    10.2 +++ b/src/share/classes/java/dyn/MethodHandle.java	Wed Nov 10 20:40:19 2010 -0800
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -36,11 +36,13 @@
   10.11  /**
   10.12   * A method handle is a typed, directly executable reference to a method,
   10.13   * constructor, field, or similar low-level operation, with optional
   10.14 - * conversion or substitution of arguments or return values.
   10.15 + * transformations of arguments or return values.
   10.16 + * (These transformations include conversion, insertion, deletion,
   10.17 + * substitution.  See the methods of this class and of {@link MethodHandles}.)
   10.18   * <p>
   10.19   * Method handles are strongly typed according to signature.
   10.20   * They are not distinguished by method name or enclosing class.
   10.21 - * A method handle must be invoked under a signature which exactly matches
   10.22 + * A method handle must be invoked under a signature which matches
   10.23   * the method handle's own {@link MethodType method type}.
   10.24   * <p>
   10.25   * Every method handle confesses its type via the {@code type} accessor.
   10.26 @@ -174,9 +176,10 @@
   10.27   * merely a documentation convention.  These type parameters do
   10.28   * not play a role in type-checking method handle invocations.
   10.29   * <p>
   10.30 - * Note: Like classes and strings, method handles that correspond directly
   10.31 - * to fields and methods can be represented directly as constants to be
   10.32 - * loaded by {@code ldc} bytecodes.
   10.33 + * Like classes and strings, method handles that correspond to accessible
   10.34 + * fields, methods, and constructors can be represented directly
   10.35 + * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
   10.36 + * Loading such a constant causes the component classes of its type to be loaded as necessary.
   10.37   *
   10.38   * @see MethodType
   10.39   * @see MethodHandles
   10.40 @@ -186,6 +189,7 @@
   10.41          // Note: This is an implementation inheritance hack, and will be removed
   10.42          // with a JVM change which moves the required hidden state onto this class.
   10.43          extends MethodHandleImpl
   10.44 +        implements MethodHandleProvider
   10.45  {
   10.46      private static Access IMPL_TOKEN = Access.getToken();
   10.47  
   10.48 @@ -197,7 +201,7 @@
   10.49       * those methods which are signature polymorphic.
   10.50       */
   10.51      @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.TYPE})
   10.52 -    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
   10.53 +    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
   10.54      @interface PolymorphicSignature { }
   10.55  
   10.56      private MethodType type;
   10.57 @@ -274,10 +278,14 @@
   10.58       * and performing simple conversions for arguments and return types.
   10.59       * The signature at the call site of {@code invokeGeneric} must
   10.60       * have the same arity as this method handle's {@code type}.
   10.61 -     * The same conversions are allowed on arguments or return values as are supported by
   10.62 -     * by {@link MethodHandles#convertArguments}.
   10.63 +     * <p>
   10.64       * If the call site signature exactly matches this method handle's {@code type},
   10.65       * the call proceeds as if by {@link #invokeExact}.
   10.66 +     * <p>
   10.67 +     * Otherwise, the call proceeds as if this method handle were first
   10.68 +     * adjusted by calling {@link #asType} to adjust this method handle
   10.69 +     * to the required type, and then the call proceeds as if by
   10.70 +     * {@link #invokeExact} on the adjusted method handle.
   10.71       */
   10.72      public final native @PolymorphicSignature <R,A> R invokeGeneric(A... args) throws Throwable;
   10.73  
   10.74 @@ -538,4 +546,10 @@
   10.75      public final MethodHandle bindTo(Object x) {
   10.76          return MethodHandles.insertArguments(this, 0, x);
   10.77      }
   10.78 +
   10.79 +    /** Implementation of {@link MethodHandleProvider}, which returns {@code this}. */
   10.80 +    public final MethodHandle asMethodHandle() { return this; }
   10.81 +
   10.82 +    /** Implementation of {@link MethodHandleProvider}, which returns {@code this.asType(type)}. */
   10.83 +    public final MethodHandle asMethodHandle(MethodType type) { return this.asType(type); }
   10.84  }
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/share/classes/java/dyn/MethodHandleProvider.java	Wed Nov 10 20:40:19 2010 -0800
    11.3 @@ -0,0 +1,80 @@
    11.4 +/*
    11.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.  Oracle designates this
   11.11 + * particular file as subject to the "Classpath" exception as provided
   11.12 + * by Oracle in the LICENSE file that accompanied this code.
   11.13 + *
   11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 + * version 2 for more details (a copy is included in the LICENSE file that
   11.18 + * accompanied this code).
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License version
   11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 + *
   11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 + * or visit www.oracle.com if you need additional information or have any
   11.26 + * questions.
   11.27 + */
   11.28 +
   11.29 +package java.dyn;
   11.30 +
   11.31 +/**
   11.32 + * An interface for an object to provide a target {@linkplain MethodHandle method handle} to a {@code invokedynamic} instruction.
   11.33 + * There are many function-like objects in various Java APIs.
   11.34 + * This interface provides a standard way for such function-like objects to be bound
   11.35 + * to a dynamic call site, by providing a view of their behavior in the form of a low-level method handle.
   11.36 + * <p>
   11.37 + * The type {@link MethodHandle} is a concrete class whose implementation
   11.38 + * hierarchy (if any) may be tightly coupled to the underlying JVM implementation.
   11.39 + * It cannot also serve as a base type for user-defined functional APIs.
   11.40 + * For this reason, {@code MethodHandle} cannot be subclassed to add new
   11.41 + * behavior to method handles.  But this interface can be used to provide
   11.42 + * a link between a user-defined function and the {@code invokedynamic}
   11.43 + * instruction and the method handle API.
   11.44 + */
   11.45 +public interface MethodHandleProvider {
   11.46 +    /** Produce a method handle which will serve as a behavioral proxy for the current object.
   11.47 +     *  The type and invocation behavior of the proxy method handle are user-defined,
   11.48 +     *  and should have some relation to the intended meaning of the original object itself.
   11.49 +     *  <p>
   11.50 +     *  The current object may have a changeable behavior.
   11.51 +     *  For example, {@link CallSite} has a {@code setTarget} method which changes its invocation.
   11.52 +     *  In such a case, it is <em>incorrect</em> for {@code asMethodHandle} to return
   11.53 +     *  a method handle whose behavior may diverge from that of the current object.
   11.54 +     *  Rather, the returned method handle must stably and permanently access
   11.55 +     *  the behavior of the current object, even if that behavior is changeable.
   11.56 +     *  <p>
   11.57 +     *  The reference identity of the proxy method handle is not guaranteed to
   11.58 +     *  have any particular relation to the reference identity of the object.
   11.59 +     *  In particular, several objects with the same intended meaning could
   11.60 +     *  share a common method handle, or the same object could return different
   11.61 +     *  method handles at different times.  In the latter case, the different
   11.62 +     *  method handles should have the same type and invocation behavior,
   11.63 +     *  and be usable from any thread at any time.
   11.64 +     *  In particular, if a MethodHandleProvider is bound to an <code>invokedynamic</code>
   11.65 +     *  call site, the proxy method handle extracted at the time of binding
   11.66 +     *  will be used for an unlimited time, until the call site is rebound.
   11.67 +     *  <p>
   11.68 +     *  The type {@link MethodHandle} itself implements {@code MethodHandleProvider}, and
   11.69 +     *  for this method simply returns {@code this}.
   11.70 +     */
   11.71 +    public MethodHandle asMethodHandle();
   11.72 +
   11.73 +    /** Produce a method handle of a given type which will serve as a behavioral proxy for the current object.
   11.74 +     *  As for the no-argument version {@link #asMethodHandle()}, the invocation behavior of the
   11.75 +     *  proxy method handle is user-defined.  But the type must be the given type,
   11.76 +     *  or else a {@link WrongMethodTypeException} must be thrown.
   11.77 +     *  <p>
   11.78 +     *  If the current object somehow represents a variadic or overloaded behavior,
   11.79 +     *  the method handle returned for a given type might represent only a subset of
   11.80 +     *  the current object's repertoire of behaviors, which correspond to that type.
   11.81 +     */
   11.82 +    public MethodHandle asMethodHandle(MethodType type) throws WrongMethodTypeException;
   11.83 +}
    12.1 --- a/src/share/classes/java/dyn/MethodHandles.java	Tue Nov 09 22:53:18 2010 -0800
    12.2 +++ b/src/share/classes/java/dyn/MethodHandles.java	Wed Nov 10 20:40:19 2010 -0800
    12.3 @@ -25,15 +25,12 @@
    12.4  
    12.5  package java.dyn;
    12.6  
    12.7 -import java.lang.reflect.Constructor;
    12.8 +import java.lang.reflect.*;
    12.9  import sun.dyn.Access;
   12.10  import sun.dyn.MemberName;
   12.11  import sun.dyn.MethodHandleImpl;
   12.12  import sun.dyn.util.VerifyAccess;
   12.13  import sun.dyn.util.Wrapper;
   12.14 -import java.lang.reflect.Field;
   12.15 -import java.lang.reflect.Method;
   12.16 -import java.lang.reflect.Modifier;
   12.17  import java.util.List;
   12.18  import java.util.ArrayList;
   12.19  import java.util.Arrays;
   12.20 @@ -81,6 +78,14 @@
   12.21       * Return a {@link Lookup lookup object} which is trusted minimally.
   12.22       * It can only be used to create method handles to
   12.23       * publicly accessible fields and methods.
   12.24 +     * <p>
   12.25 +     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
   12.26 +     * of this lookup object will be {@link java.lang.Object}.
   12.27 +     * <p>
   12.28 +     * The lookup class can be changed to any other class {@code C} using an expression of the form
   12.29 +     * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
   12.30 +     * Since all classes have equal access to public names,
   12.31 +     * such a change would confer no new access rights.
   12.32       */
   12.33      public static Lookup publicLookup() {
   12.34          return Lookup.PUBLIC_LOOKUP;
   12.35 @@ -90,9 +95,10 @@
   12.36       * A <em>lookup object</em> is a factory for creating method handles,
   12.37       * when the creation requires access checking.
   12.38       * Method handles do not perform
   12.39 -     * access checks when they are called; this is a major difference
   12.40 +     * access checks when they are called, but rather when they are created.
   12.41 +     * (This is a major difference
   12.42       * from reflective {@link Method}, which performs access checking
   12.43 -     * against every caller, on every call.
   12.44 +     * against every caller, on every call.)
   12.45       * Therefore, method handle access
   12.46       * restrictions must be enforced when a method handle is created.
   12.47       * The caller class against which those restrictions are enforced
   12.48 @@ -107,7 +113,7 @@
   12.49       * It may then use this factory to create method handles on
   12.50       * all of its methods, including private ones.
   12.51       * It may also delegate the lookup (e.g., to a metaobject protocol)
   12.52 -     * by passing the {@code Lookup} object to other code.
   12.53 +     * by passing the lookup object to other code.
   12.54       * If this other code creates method handles, they will be access
   12.55       * checked against the original lookup class, and not with any higher
   12.56       * privileges.
   12.57 @@ -125,23 +131,28 @@
   12.58       * It can also fail if a security manager is installed and refuses
   12.59       * access.  In any of these cases, an exception will be
   12.60       * thrown from the attempted lookup.
   12.61 +     * <p>
   12.62       * In general, the conditions under which a method handle may be
   12.63       * created for a method {@code M} are exactly as restrictive as the conditions
   12.64       * under which the lookup class could have compiled a call to {@code M}.
   12.65 -     * At least some of these error conditions are likely to be
   12.66 -     * represented by checked exceptions in the final version of this API.
   12.67 +     * This rule is applied even if the Java compiler might have created
   12.68 +     * an wrapper method to access a private method of another class
   12.69 +     * in the same top-level declaration.
   12.70 +     * For example, a lookup object created for a nested class {@code C.D}
   12.71 +     * can access private members within other related classes such as
   12.72 +     * {@code C}, {@code C.D.E}, or {@code C.B}.
   12.73       */
   12.74      public static final
   12.75      class Lookup {
   12.76          /** The class on behalf of whom the lookup is being performed. */
   12.77          private final Class<?> lookupClass;
   12.78  
   12.79 -        /** The allowed sorts of members which may be looked up (public, etc.), with STRICT for package. */
   12.80 +        /** The allowed sorts of members which may be looked up (public, etc.), with STATIC for package. */
   12.81          private final int allowedModes;
   12.82  
   12.83          private static final int
   12.84              PUBLIC    = Modifier.PUBLIC,
   12.85 -            PACKAGE   = Modifier.STRICT,
   12.86 +            PACKAGE   = Modifier.STATIC,
   12.87              PROTECTED = Modifier.PROTECTED,
   12.88              PRIVATE   = Modifier.PRIVATE,
   12.89              ALL_MODES = (PUBLIC | PACKAGE | PROTECTED | PRIVATE),
   12.90 @@ -155,8 +166,10 @@
   12.91          /** Which class is performing the lookup?  It is this class against
   12.92           *  which checks are performed for visibility and access permissions.
   12.93           *  <p>
   12.94 -         *  This value is null if and only if this lookup was produced
   12.95 -         *  by {@link MethodHandles#publicLookup}.
   12.96 +         *  The class implies a maximum level of access permission,
   12.97 +         *  but the permissions may be additionally limited by the bitmask
   12.98 +         *  {@link #lookupModes}, which controls whether non-public members
   12.99 +         *  can be accessed.
  12.100           */
  12.101          public Class<?> lookupClass() {
  12.102              return lookupClass;
  12.103 @@ -168,10 +181,15 @@
  12.104          }
  12.105  
  12.106          /** Which types of members can this lookup object produce?
  12.107 -         *  The result is a bit-mask of the modifier bits PUBLIC, PROTECTED, PRIVATE, and STRICT.
  12.108 -         *  The modifier bit STRICT stands in for the (non-existent) package protection mode.
  12.109 +         *  The result is a bit-mask of the {@link Modifier} bits
  12.110 +         *  {@linkplain Modifier#PUBLIC PUBLIC (0x01)},
  12.111 +         *  {@linkplain Modifier#PROTECTED PROTECTED (0x02)},
  12.112 +         *  {@linkplain Modifier#PRIVATE PRIVATE (0x04)},
  12.113 +         *  and {@linkplain Modifier#STATIC STATIC (0x08)}.
  12.114 +         *  The modifier bit {@code STATIC} stands in for the package protection mode,
  12.115 +         *  which does not have an explicit modifier bit.
  12.116           */
  12.117 -        int lookupModes() {
  12.118 +        public int lookupModes() {
  12.119              return allowedModes & ALL_MODES;
  12.120          }
  12.121  
  12.122 @@ -621,32 +639,32 @@
  12.123  
  12.124          /// Helper methods, all package-private.
  12.125  
  12.126 -        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) {
  12.127 +        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoAccessException {
  12.128              checkSymbolicClass(refc);  // do this before attempting to resolve
  12.129              int mods = (isStatic ? Modifier.STATIC : 0);
  12.130              return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
  12.131          }
  12.132  
  12.133 -        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) {
  12.134 +        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoAccessException {
  12.135              checkSymbolicClass(refc);  // do this before attempting to resolve
  12.136              int mods = (isStatic ? Modifier.STATIC : 0);
  12.137              return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
  12.138          }
  12.139  
  12.140          MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
  12.141 -                                 boolean searchSupers, Class<?> specialCaller) {
  12.142 +                                 boolean searchSupers, Class<?> specialCaller) throws NoAccessException {
  12.143              checkSymbolicClass(refc);  // do this before attempting to resolve
  12.144              int mods = (isStatic ? Modifier.STATIC : 0);
  12.145              return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller);
  12.146          }
  12.147  
  12.148 -        void checkSymbolicClass(Class<?> refc) {
  12.149 +        void checkSymbolicClass(Class<?> refc) throws NoAccessException {
  12.150              Class<?> caller = lookupClassOrNull();
  12.151              if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
  12.152                  throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), caller);
  12.153          }
  12.154  
  12.155 -        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) {
  12.156 +        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws NoAccessException {
  12.157              String message;
  12.158              if (m.isConstructor())
  12.159                  message = "expected a method, not a constructor";
  12.160 @@ -659,7 +677,7 @@
  12.161              throw newNoAccessException(message, m, lookupClass());
  12.162          }
  12.163  
  12.164 -        void checkAccess(Class<?> refc, MemberName m) {
  12.165 +        void checkAccess(Class<?> refc, MemberName m) throws NoAccessException {
  12.166              int allowedModes = this.allowedModes;
  12.167              if (allowedModes == TRUSTED)  return;
  12.168              int mods = m.getModifiers();
  12.169 @@ -695,14 +713,14 @@
  12.170              return "member is private to package";
  12.171          }
  12.172  
  12.173 -        void checkSpecialCaller(Class<?> specialCaller) {
  12.174 +        void checkSpecialCaller(Class<?> specialCaller) throws NoAccessException {
  12.175              if (allowedModes == TRUSTED)  return;
  12.176              if (!VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))
  12.177                  throw newNoAccessException("no private access for invokespecial",
  12.178                                             new MemberName(specialCaller), lookupClass());
  12.179          }
  12.180  
  12.181 -        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) {
  12.182 +        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws NoAccessException {
  12.183              // The accessing class only has the right to use a protected member
  12.184              // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
  12.185              if (!method.isProtected() || method.isStatic()
  12.186 @@ -712,7 +730,7 @@
  12.187              else
  12.188                  return restrictReceiver(method, mh, lookupClass());
  12.189          }
  12.190 -        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) {
  12.191 +        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws NoAccessException {
  12.192              assert(!method.isStatic());
  12.193              Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
  12.194              if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
  12.195 @@ -898,11 +916,16 @@
  12.196       * @return a method handle which always invokes the call site's target
  12.197       */
  12.198      public static
  12.199 -    MethodHandle dynamicInvoker(CallSite site) {
  12.200 +    MethodHandle dynamicInvoker(CallSite site) throws NoAccessException {
  12.201          MethodHandle getCSTarget = GET_TARGET;
  12.202 -        if (getCSTarget == null)
  12.203 -            GET_TARGET = getCSTarget = Lookup.IMPL_LOOKUP.
  12.204 -                findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
  12.205 +        if (getCSTarget == null) {
  12.206 +            try {
  12.207 +                GET_TARGET = getCSTarget = Lookup.IMPL_LOOKUP.
  12.208 +                    findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
  12.209 +            } catch (NoAccessException ex) {
  12.210 +                throw new InternalError();
  12.211 +            }
  12.212 +        }
  12.213          MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, getCSTarget, site);
  12.214          MethodHandle invoker = exactInvoker(site.type());
  12.215          return foldArguments(invoker, getTarget);
  12.216 @@ -1260,17 +1283,20 @@
  12.217       * <p>
  12.218       * <b>Example:</b>
  12.219       * <p><blockquote><pre>
  12.220 -     *   MethodHandle cat = MethodHandles.lookup().
  12.221 -     *     findVirtual(String.class, "concat", String.class, String.class);
  12.222 -     *   System.out.println(cat.&lt;String&gt;invokeExact("x", "y")); // xy
  12.223 +     *   import static java.dyn.MethodHandles.*;
  12.224 +     *   import static java.dyn.MethodType.*;
  12.225 +     *   ...
  12.226 +     *   MethodHandle cat = lookup().findVirtual(String.class,
  12.227 +     *     "concat", methodType(String.class, String.class));
  12.228 +     *   System.out.println((String) cat.invokeExact("x", "y")); // xy
  12.229       *   MethodHandle d0 = dropArguments(cat, 0, String.class);
  12.230 -     *   System.out.println(d0.&lt;String&gt;invokeExact("x", "y", "z")); // xy
  12.231 +     *   System.out.println((String) d0.invokeExact("x", "y", "z")); // yz
  12.232       *   MethodHandle d1 = dropArguments(cat, 1, String.class);
  12.233 -     *   System.out.println(d1.&lt;String&gt;invokeExact("x", "y", "z")); // xz
  12.234 +     *   System.out.println((String) d1.invokeExact("x", "y", "z")); // xz
  12.235       *   MethodHandle d2 = dropArguments(cat, 2, String.class);
  12.236 -     *   System.out.println(d2.&lt;String&gt;invokeExact("x", "y", "z")); // yz
  12.237 -     *   MethodHandle d12 = dropArguments(cat, 1, String.class, String.class);
  12.238 -     *   System.out.println(d12.&lt;String&gt;invokeExact("w", "x", "y", "z")); // wz
  12.239 +     *   System.out.println((String) d2.invokeExact("x", "y", "z")); // xy
  12.240 +     *   MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
  12.241 +     *   System.out.println((String) d12.invokeExact("x", 12, true, "z")); // xz
  12.242       * </pre></blockquote>
  12.243       * @param target the method handle to invoke after the argument is dropped
  12.244       * @param valueTypes the type(s) of the argument to drop
  12.245 @@ -1562,4 +1588,107 @@
  12.246      MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
  12.247          return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
  12.248      }
  12.249 +
  12.250 +    /**
  12.251 +     * Produce a wrapper instance of the given "SAM" type which redirects its calls to the given method handle.
  12.252 +     * A SAM type is a type which declares a single abstract method.
  12.253 +     * Additionally, it must have either no constructor (as an interface)
  12.254 +     * or have a public or protected constructor of zero arguments (as a class).
  12.255 +     * <p>
  12.256 +     * The resulting instance of the required SAM type will respond to
  12.257 +     * invocation of the SAM type's single abstract method by calling
  12.258 +     * the given {@code target} on the incoming arguments,
  12.259 +     * and returning or throwing whatever the {@code target}
  12.260 +     * returns or throws.  The invocation will be as if by
  12.261 +     * {@code target.invokeExact}.
  12.262 +     * <p>
  12.263 +     * The method handle may throw an <em>undeclared exception</em>,
  12.264 +     * which means any checked exception (or other checked throwable)
  12.265 +     * not declared by the SAM type's single abstract method.
  12.266 +     * If this happens, the throwable will be wrapped in an instance
  12.267 +     * of {@link UndeclaredThrowableException} and thrown in that
  12.268 +     * wrapped form.
  12.269 +     * <p>
  12.270 +     * The wrapper instance is guaranteed to be of a non-public
  12.271 +     * implementation class C in a package containing no classes
  12.272 +     * or methods except system-defined classes and methods.
  12.273 +     * The implementation class C will have no public supertypes
  12.274 +     * or public methods beyond the following:
  12.275 +     * <ul>
  12.276 +     * <li>the SAM type itself and any methods in the SAM type
  12.277 +     * <li>the supertypes of the SAM type (if any) and their methods
  12.278 +     * <li>{@link Object} and its methods
  12.279 +     * <li>{@link MethodHandleProvider} and its methods
  12.280 +     * </ul>
  12.281 +     * <p>
  12.282 +     * No stable mapping is promised between the SAM type and
  12.283 +     * the implementation class C.  Over time, several implementation
  12.284 +     * classes might be used for the same SAM type.
  12.285 +     * <p>
  12.286 +     * This method is not guaranteed to return a distinct
  12.287 +     * wrapper object for each separate call.  If the JVM is able
  12.288 +     * to prove that a wrapper has already been created for a given
  12.289 +     * method handle, or for another method handle with the
  12.290 +     * same behavior, the JVM may return that wrapper in place of
  12.291 +     * a new wrapper.
  12.292 +     * @param target the method handle to invoke from the wrapper
  12.293 +     * @param samType the desired type of the wrapper, a SAM type
  12.294 +     * @return a correctly-typed wrapper for the given {@code target}
  12.295 +     * @throws IllegalArgumentException if the {@code target} throws
  12.296 +     *         an undeclared exception
  12.297 +     */
  12.298 +    // ISSUE: Should we delegate equals/hashCode to the targets?
  12.299 +    // Not useful unless there is a stable equals/hashCode behavior
  12.300 +    // for MethodHandle, and for MethodHandleProvider.asMethodHandle.
  12.301 +    public static
  12.302 +    <T> T asInstance(MethodHandle target, Class<T> samType) {
  12.303 +        // POC implementation only; violates the above contract several ways
  12.304 +        final Method sam = getSamMethod(samType);
  12.305 +        if (sam == null)
  12.306 +            throw new IllegalArgumentException("not a SAM type: "+samType.getName());
  12.307 +        MethodType samMT = MethodType.methodType(sam.getReturnType(), sam.getParameterTypes());
  12.308 +        if (!samMT.equals(target.type()))
  12.309 +            throw new IllegalArgumentException("wrong method type");
  12.310 +        final MethodHandle mh = target;
  12.311 +        return samType.cast(Proxy.newProxyInstance(
  12.312 +                samType.getClassLoader(),
  12.313 +                new Class[]{ samType, MethodHandleProvider.class },
  12.314 +                new InvocationHandler() {
  12.315 +                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  12.316 +                        if (method.getDeclaringClass() == MethodHandleProvider.class) {
  12.317 +                            return method.invoke(mh, args);
  12.318 +                        }
  12.319 +                        assert method.equals(sam) : method;
  12.320 +                        return mh.invokeVarargs(args);
  12.321 +                    }
  12.322 +                }));
  12.323 +    }
  12.324 +
  12.325 +    private static
  12.326 +    Method getSamMethod(Class<?> samType) {
  12.327 +        Method sam = null;
  12.328 +        for (Method m : samType.getMethods()) {
  12.329 +            int mod = m.getModifiers();
  12.330 +            if (Modifier.isAbstract(mod)) {
  12.331 +                if (sam != null)
  12.332 +                    return null;  // too many abstract methods
  12.333 +                sam = m;
  12.334 +            }
  12.335 +        }
  12.336 +        if (!samType.isInterface() && getSamConstructor(samType) == null)
  12.337 +            return null;  // wrong kind of constructor
  12.338 +        return sam;
  12.339 +    }
  12.340 +
  12.341 +    private static
  12.342 +    Constructor getSamConstructor(Class<?> samType) {
  12.343 +        for (Constructor c : samType.getDeclaredConstructors()) {
  12.344 +            if (c.getParameterTypes().length == 0) {
  12.345 +                int mod = c.getModifiers();
  12.346 +                if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
  12.347 +                    return c;
  12.348 +            }
  12.349 +        }
  12.350 +        return null;
  12.351 +    }
  12.352  }
    13.1 --- a/src/share/classes/java/dyn/MethodType.java	Tue Nov 09 22:53:18 2010 -0800
    13.2 +++ b/src/share/classes/java/dyn/MethodType.java	Wed Nov 10 20:40:19 2010 -0800
    13.3 @@ -40,24 +40,37 @@
    13.4   * returned by a method handle, or the arguments and return type passed
    13.5   * and expected  by a method handle caller.  Method types must be properly
    13.6   * matched between a method handle and all its callers,
    13.7 - * and the JVM's operations enforce this matching at all times.
    13.8 + * and the JVM's operations enforce this matching at, specifically
    13.9 + * during calls to {@link MethodHandle#invokeExact}
   13.10 + * and {@link MethodHandle#invokeGeneric}, and during execution
   13.11 + * of {@code invokedynamic} instructions.
   13.12   * <p>
   13.13   * The structure is a return type accompanied by any number of parameter types.
   13.14 - * The types (primitive, void, and reference) are represented by Class objects.
   13.15 + * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
   13.16 + * (For ease of exposition, we treat {@code void} as if it were a type.
   13.17 + * In fact, it denotes the absence of a return type.)
   13.18   * <p>
   13.19 - * All instances of <code>MethodType</code> are immutable.
   13.20 + * All instances of {@code MethodType} are immutable.
   13.21   * Two instances are completely interchangeable if they compare equal.
   13.22   * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
   13.23   * <p>
   13.24   * This type can be created only by factory methods.
   13.25   * All factory methods may cache values, though caching is not guaranteed.
   13.26   * <p>
   13.27 - * Note: Like classes and strings, method types can be represented directly
   13.28 - * as constants to be loaded by {@code ldc} bytecodes.
   13.29 + * {@code MethodType} objects are sometimes derived from bytecode instructions
   13.30 + * such as {@code invokedynamic}, specifically from the type descriptor strings associated
   13.31 + * with the instructions in a class file's constant pool.
   13.32 + * When this occurs, any classes named in the descriptor strings must be loaded.
   13.33 + * (But they need not be initialized.)
   13.34 + * This loading may occur at any time before the {@code MethodType} object is first derived.
   13.35 + * <p>
   13.36 + * Like classes and strings, method types can be represented directly
   13.37 + * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
   13.38 + * Loading such a constant causes its component classes to be loaded as necessary.
   13.39   * @author John Rose, JSR 292 EG
   13.40   */
   13.41  public final
   13.42 -class MethodType {
   13.43 +class MethodType implements java.lang.reflect.Type {
   13.44      private final Class<?>   rtype;
   13.45      private final Class<?>[] ptypes;
   13.46      private MethodTypeForm form; // erased form, plus cached data about primitives
   13.47 @@ -636,11 +649,11 @@
   13.48  
   13.49      /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
   13.50       * Find or create an instance of the given method type.
   13.51 -     * Any class or interface name embedded in the signature string
   13.52 +     * Any class or interface name embedded in the descriptor string
   13.53       * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
   13.54       * on the given loader (or if it is null, on the system class loader).
   13.55       * <p>
   13.56 -     * Note that it is possible to build method types which cannot be
   13.57 +     * Note that it is possible to encounter method types which cannot be
   13.58       * constructed by this method, because their component types are
   13.59       * not all reachable from a common class loader.
   13.60       * <p>
   13.61 @@ -662,8 +675,11 @@
   13.62      }
   13.63  
   13.64      /**
   13.65 -     * Create a bytecode signature representation of the type.
   13.66 -     * Note that this is not a strict inverse of
   13.67 +     * Create a bytecode descriptor representation of the method type.
   13.68 +     * <p>
   13.69 +     * Note that this is not a strict inverse of {@link #fromMethodDescriptorString}.
   13.70 +     * Two distinct classes which share a common name but have different class loaders
   13.71 +     * will appear identical when viewed within descriptor strings.
   13.72       * <p>
   13.73       * This method is included for the benfit of applications that must
   13.74       * generate bytecodes that process method handles and invokedynamic.
    14.1 --- a/src/share/classes/java/dyn/NoAccessException.java	Tue Nov 09 22:53:18 2010 -0800
    14.2 +++ b/src/share/classes/java/dyn/NoAccessException.java	Wed Nov 10 20:40:19 2010 -0800
    14.3 @@ -37,7 +37,7 @@
    14.4   * @author John Rose, JSR 292 EG
    14.5   * @since 1.7
    14.6   */
    14.7 -public class NoAccessException extends RuntimeException {
    14.8 +public class NoAccessException extends ReflectiveOperationException {
    14.9      private static final long serialVersionUID = 292L;
   14.10  
   14.11      /**
    15.1 --- a/src/share/classes/java/dyn/package-info.java	Tue Nov 09 22:53:18 2010 -0800
    15.2 +++ b/src/share/classes/java/dyn/package-info.java	Wed Nov 10 20:40:19 2010 -0800
    15.3 @@ -40,20 +40,18 @@
    15.4   * The JVM links any such call (regardless of signature) to a dynamically
    15.5   * typed method handle invocation.  In the case of {@code invokeGeneric},
    15.6   * argument and return value conversions are applied.
    15.7 + * </li>
    15.8   *
    15.9 - * <li>In source code, the class {@link java.dyn.InvokeDynamic} appears to accept
   15.10 + * <li>In source code, the class {@link java.dyn.InvokeDynamic InvokeDynamic} appears to accept
   15.11   * any static method invocation, of any name and any signature.
   15.12   * But instead of emitting
   15.13   * an {@code invokestatic} instruction for such a call, the Java compiler emits
   15.14   * an {@code invokedynamic} instruction with the given name and signature.
   15.15 - *
   15.16 - * <li>When the JVM links an {@code invokedynamic} instruction, it calls the
   15.17 - * {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
   15.18 - * of the containing class to obtain a {@linkplain java.dyn.CallSite call site} object through which
   15.19 - * the call site will link its target {@linkplain java.dyn.MethodHandle method handle}.
   15.20 + * </li>
   15.21   *
   15.22   * <li>The JVM bytecode format supports immediate constants of
   15.23 - * the classes {@link java.dyn.MethodHandle} and {@link java.dyn.MethodType}.
   15.24 + * the classes {@link java.dyn.MethodHandle MethodHandle} and {@link java.dyn.MethodType MethodType}.
   15.25 + * </li>
   15.26   * </ul>
   15.27   *
   15.28   * <h2><a name="jvm_mods"></a>Corresponding JVM bytecode format changes</h2>
   15.29 @@ -65,18 +63,50 @@
   15.30   * The first byte is the opcode 186 (hexadecimal {@code BA}).
   15.31   * The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
   15.32   * The final two bytes are reserved for future use and required to be zero.
   15.33 - * The constant pool reference is to a entry with tag {@code CONSTANT_NameAndType}
   15.34 - * (decimal 12).  It is thus not a method reference of any sort, but merely
   15.35 - * the method name, argument types, and return type of the dynamic call site.
   15.36 - * <em>(TBD: The EG is discussing the possibility of a special constant pool entry type,
   15.37 - * so that other information may be added, such as a per-instruction bootstrap
   15.38 - * method and/or annotations.)</em>
   15.39 + * The constant pool reference of an {@code invokedynamic} instruction is to a entry
   15.40 + * with tag {@code CONSTANT_InvokeDynamic} (decimal 17).  See below for its format.
   15.41 + * The entry specifies the bootstrap method (a {@link java.dyn.MethodHandle MethodHandle} constant),
   15.42 + * the dynamic invocation name, and the argument types and return type of the call.
   15.43 + * <p>
   15.44 + * Each instance of an {@code invokedynamic} instruction is called a <em>dynamic call site</em>.
   15.45 + * Multiple instances of an {@code invokedynamic} instruction can share a single
   15.46 + * {@code CONSTANT_InvokeDynamic} entry.
   15.47 + * In any case, distinct call sites always have distinct linkage state.
   15.48 + * <p>
   15.49 + * Moreover, for the purpose of distinguishing dynamic call sites,
   15.50 + * the JVM is allowed (but not required) to make internal copies
   15.51 + * of {@code invokedynamic} instructions, each one
   15.52 + * constituting a separate dynamic call site with its own linkage state.
   15.53 + * Such copying, if it occurs, cannot be observed except indirectly via
   15.54 + * execution of bootstrap methods and target methods.
   15.55 + * <p>
   15.56 + * A dynamic call site is originally in an unlinked state.  In this state, there is
   15.57 + * no target method for the call site to invoke.
   15.58 + * A dynamic call site is linked by means of a bootstrap method,
   15.59 + * as <a href="#bsm">described below</a>.
   15.60 + * <p>
   15.61 + * <em>(Historic Note: Some older JVMs may allow the index of a {@code CONSTANT_NameAndType}
   15.62 + * instead of a {@code CONSTANT_InvokeDynamic}.  In earlier, obsolete versions of this API, the
   15.63 + * bootstrap method was specified dynamically, in a per-class basis, during class initialization.)</em>
   15.64 + *
   15.65 + * <h3>constant pool entries for {@code invokedynamic} instructions</h3>
   15.66 + * If a constant pool entry has the tag {@code CONSTANT_InvokeDynamic} (decimal 17),
   15.67 + * it must contain exactly four more bytes.
   15.68 + * The first two bytes after the tag must be an index to a {@code CONSTANT_MethodHandle}
   15.69 + * entry, and the second two bytes must be an index to a {@code CONSTANT_NameAndType}.
   15.70 + * The first index specifies a bootstrap method used by the associated dynamic call sites.
   15.71 + * The second index specifies the method name, argument types, and return type of the dynamic call site.
   15.72 + * The structure of such an entry is therefore analogous to a {@code CONSTANT_Methodref},
   15.73 + * except that the {@code CONSTANT_Class} reference in a {@code CONSTANT_Methodref} entry
   15.74 + * is replaced by a bootstrap method reference.
   15.75   *
   15.76   * <h3>constant pool entries for {@code MethodType}s</h3>
   15.77   * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
   15.78 - * it must contain exactly two more bytes, which are an index to a {@code CONSTANT_Utf8}
   15.79 - * entry which represents a method type signature.  The JVM will ensure that on first
   15.80 - * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType}
   15.81 + * it must contain exactly two more bytes, which must be an index to a {@code CONSTANT_Utf8}
   15.82 + * entry which represents a method type signature.
   15.83 + * <p>
   15.84 + * The JVM will ensure that on first
   15.85 + * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType MethodType}
   15.86   * will be created which represents the signature.
   15.87   * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
   15.88   * but not initialized.
   15.89 @@ -86,12 +116,15 @@
   15.90   * <h3>constant pool entries for {@code MethodHandle}s</h3>
   15.91   * If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
   15.92   * it must contain exactly three more bytes.  The first byte after the tag is a subtag
   15.93 - * value in the range 1 through 9, and the last two are an index to a
   15.94 + * value which must be in the range 1 through 9, and the last two must be an index to a
   15.95   * {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
   15.96   * {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
   15.97   * for which a method handle is to be created.
   15.98 + * Furthermore, the subtag value and the type of the constant index value
   15.99 + * must agree according to the table below.
  15.100 + * <p>
  15.101   * The JVM will ensure that on first execution of an {@code ldc} instruction
  15.102 - * for this entry, a {@link java.dyn.MethodHandle} will be created which represents
  15.103 + * for this entry, a {@link java.dyn.MethodHandle MethodHandle} will be created which represents
  15.104   * the field or method reference, according to the specific mode implied by the subtag.
  15.105   * <p>
  15.106   * As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
  15.107 @@ -126,6 +159,129 @@
  15.108   * Method handles for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
  15.109   * may force class initialization on their first invocation, just like the corresponding bytecodes.
  15.110   *
  15.111 + * <h2><a name="bsm"></a>Bootstrap Methods</h2>
  15.112 + * Before the JVM can execute a dynamic call site (an {@code invokedynamic} instruction),
  15.113 + * the call site must first be <em>linked</em>.
  15.114 + * Linking is accomplished by calling a <em>bootstrap method</em>
  15.115 + * which is given the static information content of the call site,
  15.116 + * and which must produce a {@link java.dyn.MethodHandle method handle}
  15.117 + * that gives the behavior of the call site.
  15.118 + * <p>
  15.119 + * Each {@code invokedynamic} instruction statically specifies its own
  15.120 + * bootstrap method as a constant pool reference.
  15.121 + * The constant pool reference also specifies the call site's name and type signature,
  15.122 + * just like {@code invokevirtual} and the other invoke instructions.
  15.123 + * <p>
  15.124 + * Linking starts with resolving the constant pool entry for the
  15.125 + * bootstrap method, and resolving a {@link java.dyn.MethodType MethodType} object for
  15.126 + * the type signature of the dynamic call site.
  15.127 + * This resolution process may trigger class loading.
  15.128 + * It may therefore throw an error if a class fails to load.
  15.129 + * This error becomes the abnormal termination of the dynamic
  15.130 + * call site execution.
  15.131 + * Linkage does not trigger class initialization.
  15.132 + * <p>
  15.133 + * Next, the bootstrap method call is started, with four values being stacked:
  15.134 + * <ul>
  15.135 + * <li>a {@code MethodHandle}, the resolved bootstrap method itself </li>
  15.136 + * <li>a {@code Class}, the <em>caller class</em> in which dynamic call site occurs </li>
  15.137 + * <li>a {@code String}, the method name mentioned in the call site </li>
  15.138 + * <li>a {@code MethodType}, the resolved type signature of the call </li>
  15.139 + * </ul>
  15.140 + * The method handle is then applied to the other values as if by
  15.141 + * {@linkplain java.dyn.MethodHandle#invokeGeneric the <code>invokeGeneric</code> method}.
  15.142 + * The returned result must be a {@link java.dyn.CallSite CallSite}, a {@link java.dyn.MethodHandle MethodHandle},
  15.143 + * or another {@link java.dyn.MethodHandleProvider MethodHandleProvider} value.
  15.144 + * The method {@linkplain java.dyn.MethodHandleProvider#asMethodHandle asMethodHandle}
  15.145 + * is then called on the returned value.  The result of that second
  15.146 + * call is the {@code MethodHandle} which becomes the
  15.147 + * permanent binding for the dynamic call site.
  15.148 + * That method handle's type must be exactly equal to the type
  15.149 + * derived from the dynamic call site signature and passed to
  15.150 + * the bootstrap method.
  15.151 + * <p>
  15.152 + * After resolution, the linkage process may fail in a variety of ways.
  15.153 + * All failures are reported by an {@link java.dyn.InvokeDynamicBootstrapError InvokeDynamicBootstrapError},
  15.154 + * which is thrown as the abnormal termination of the dynamic call
  15.155 + * site execution.
  15.156 + * The following circumstances will cause this:
  15.157 + * <ul>
  15.158 + * <li>the bootstrap method invocation completes abnormally </li>
  15.159 + * <li>the result from the bootstrap invocation is not a reference to
  15.160 + *     an object of type {@link java.dyn.MethodHandleProvider MethodHandleProvider} </li>
  15.161 + * <li>the call to {@code asMethodHandle} completes abnormally </li>
  15.162 + * <li>the call to {@code asMethodHandle} fails to return a reference to
  15.163 + *     an object of type {@link java.dyn.MethodHandle MethodHandle} </li>
  15.164 + * <li>the method handle produced by {@code asMethodHandle} does not have
  15.165 + *     the expected {@code MethodType} </li>
  15.166 + * </ul>
  15.167 + * <h3>timing of linkage</h3>
  15.168 + * A dynamic call site is linked just before its first execution.
  15.169 + * The bootstrap method call implementing the linkage occurs within
  15.170 + * a thread that is attempting a first execution.
  15.171 + * <p>
  15.172 + * If there are several such threads, the JVM picks one thread
  15.173 + * and runs the bootstrap method while the others wait for the
  15.174 + * invocation to terminate normally or abnormally.
  15.175 + * <p>
  15.176 + * After a bootstrap method is called and a method handle target
  15.177 + * successfully extracted, the JVM attempts to link the instruction
  15.178 + * being executed to the target method handle.
  15.179 + * This may fail if there has been intervening linkage
  15.180 + * or invalidation event for the same instruction.
  15.181 + * If such a failure occurs, the dynamic call site must be
  15.182 + * re-executed from the beginning, either re-linking it
  15.183 + * (if it has been invalidated) or invoking the target
  15.184 + * (if it the instruction has been linked by some other means).
  15.185 + * <p>
  15.186 + * If the instruction is linked successfully, the target method
  15.187 + * handle is invoked to complete the instruction execution.
  15.188 + * The state of linkage continues until the method containing the
  15.189 + * dynamic call site is garbage collected, or the dynamic call site
  15.190 + * is invalidated by an explicit request,
  15.191 + * such as {@link java.dyn.Linkage#invalidateCallerClass Linkage.invalidateCallerClass}.
  15.192 + * <p>
  15.193 + * In an application which requires dynamic call sites with individually
  15.194 + * mutable behaviors, their bootstrap methods should produce distinct
  15.195 + * {@link java.dyn.CallSite CallSite} objects, one for each linkage request.
  15.196 + * <p>
  15.197 + * If a class containing {@code invokedynamic} instructions
  15.198 + * is {@linkplain java.dyn.Linkage#invalidateCallerClass(Class) invalidated},
  15.199 + * subsequent execution of those {@code invokedynamic} instructions
  15.200 + * will require linking.
  15.201 + * It is as if they had never been executed in the first place.
  15.202 + * (However, invalidation does not cause constant pool entries to be
  15.203 + * resolved a second time.)
  15.204 + * <p>
  15.205 + * Invalidation events and bootstrap method calls for a particular
  15.206 + * dynamic call site are globally ordered relative to each other.
  15.207 + * When an invokedynamic instruction is invalidated, if there is
  15.208 + * simultaneously a bootstrap method invocation in process
  15.209 + * (in the same thread or a different thread), the result
  15.210 + * eventually returned must not be used to link the call site.
  15.211 + * Put another way, when a call site is invalidated, its
  15.212 + * subsequent linkage (if any) must be performed by a bootstrap method
  15.213 + * call initiated after the invalidation occurred.
  15.214 + * <p>
  15.215 + * If several threads simultaneously execute a bootstrap method for a single dynamic
  15.216 + * call site, the JVM must choose one target object and installs it visibly to
  15.217 + * all threads.  Any other bootstrap method calls are allowed to complete, but their
  15.218 + * results are ignored, and their dynamic call site invocations proceed with the originally
  15.219 + * chosen target object.
  15.220 + * <p>
  15.221 + * The JVM is free to duplicate dynamic call sites.
  15.222 + * This means that, even if a class contains just one {@code invokedynamic}
  15.223 + * instruction, its bootstrap method may be executed several times,
  15.224 + * once for each duplicate.  Thus, bootstrap method code should not
  15.225 + * assume an exclusive one-to-one correspondence between particular occurrences
  15.226 + * of {@code invokedynamic} bytecodes in class files and linkage events.
  15.227 + * <p>
  15.228 + * In principle, each individual execution of an {@code invokedynamic}
  15.229 + * instruction could be deemed (by a conforming implementation) to be a separate
  15.230 + * duplicate, requiring its own execution of the bootstrap method.
  15.231 + * However, implementations are expected to perform code duplication
  15.232 + * (if at all) in order to improve performance, not make it worse.
  15.233 + *
  15.234   * @author John Rose, JSR 292 EG
  15.235   */
  15.236  
    16.1 --- a/src/share/classes/sun/dyn/BoundMethodHandle.java	Tue Nov 09 22:53:18 2010 -0800
    16.2 +++ b/src/share/classes/sun/dyn/BoundMethodHandle.java	Wed Nov 10 20:40:19 2010 -0800
    16.3 @@ -48,8 +48,6 @@
    16.4      private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
    16.5  
    16.6      // Constructors in this class *must* be package scoped or private.
    16.7 -    // Exception:  JavaMethodHandle constructors are protected.
    16.8 -    // (The link between JMH and BMH is temporary.)
    16.9  
   16.10      /** Bind a direct MH to its receiver (or first ref. argument).
   16.11       *  The JVM will pre-dispatch the MH if it is not already static.
   16.12 @@ -122,55 +120,6 @@
   16.13          assert(this instanceof JavaMethodHandle);
   16.14      }
   16.15  
   16.16 -    /** Initialize the current object as a Java method handle.
   16.17 -     */
   16.18 -    protected BoundMethodHandle(String entryPointName, MethodType type, boolean matchArity) {
   16.19 -        super(Access.TOKEN, null);
   16.20 -        MethodHandle entryPoint
   16.21 -                = findJavaMethodHandleEntryPoint(this.getClass(),
   16.22 -                                        entryPointName, type, matchArity);
   16.23 -        MethodHandleImpl.initType(this, entryPoint.type().dropParameterTypes(0, 1));
   16.24 -        this.argument = this; // kludge; get rid of
   16.25 -        this.vmargslot = this.type().parameterSlotDepth(0);
   16.26 -        initTarget(entryPoint, 0);
   16.27 -        assert(this instanceof JavaMethodHandle);
   16.28 -    }
   16.29 -
   16.30 -    private static
   16.31 -    MethodHandle findJavaMethodHandleEntryPoint(Class<?> caller,
   16.32 -                                                String name,
   16.33 -                                                MethodType type,
   16.34 -                                                boolean matchArity) {
   16.35 -        if (matchArity)  type.getClass();  // elicit NPE
   16.36 -        List<MemberName> methods = IMPL_NAMES.getMethods(caller, true, name, null, caller);
   16.37 -        MethodType foundType = null;
   16.38 -        MemberName foundMethod = null;
   16.39 -        for (MemberName method : methods) {
   16.40 -            if (method.getDeclaringClass() == MethodHandle.class)
   16.41 -                continue;  // ignore methods inherited from MH class itself
   16.42 -            MethodType mtype = method.getMethodType();
   16.43 -            if (type != null && type.parameterCount() != mtype.parameterCount())
   16.44 -                continue;
   16.45 -            else if (foundType == null)
   16.46 -                foundType = mtype;
   16.47 -            else if (foundType != mtype)
   16.48 -                throw newIllegalArgumentException("more than one method named "+name+" in "+caller.getName());
   16.49 -            // discard overrides
   16.50 -            if (foundMethod == null)
   16.51 -                foundMethod = method;
   16.52 -            else if (foundMethod.getDeclaringClass().isAssignableFrom(method.getDeclaringClass()))
   16.53 -                foundMethod = method;
   16.54 -        }
   16.55 -        if (foundMethod == null)
   16.56 -            throw newIllegalArgumentException("no method named "+name+" in "+caller.getName());
   16.57 -        MethodHandle entryPoint = MethodHandleImpl.findMethod(IMPL_TOKEN, foundMethod, true, caller);
   16.58 -        if (type != null) {
   16.59 -            MethodType epType = type.insertParameterTypes(0, entryPoint.type().parameterType(0));
   16.60 -            entryPoint = MethodHandles.convertArguments(entryPoint, epType);
   16.61 -        }
   16.62 -        return entryPoint;
   16.63 -    }
   16.64 -
   16.65      /** Make sure the given {@code argument} can be used as {@code argnum}-th
   16.66       *  parameter of the given method handle {@code mh}, which must be a reference.
   16.67       *  <p>
    17.1 --- a/src/share/classes/sun/dyn/CallSiteImpl.java	Tue Nov 09 22:53:18 2010 -0800
    17.2 +++ b/src/share/classes/sun/dyn/CallSiteImpl.java	Wed Nov 10 20:40:19 2010 -0800
    17.3 @@ -26,6 +26,7 @@
    17.4  package sun.dyn;
    17.5  
    17.6  import java.dyn.*;
    17.7 +import static sun.dyn.MemberName.uncaughtException;
    17.8  
    17.9  /**
   17.10   * Parts of CallSite known to the JVM.
   17.11 @@ -49,18 +50,21 @@
   17.12          }
   17.13          CallSite site;
   17.14          try {
   17.15 -            if (bootstrapMethod.type().parameterCount() == 3)
   17.16 -                site = bootstrapMethod.<CallSite>invokeExact(caller, name, type);
   17.17 -            else if (bootstrapMethod.type().parameterCount() == 4)
   17.18 -                site = bootstrapMethod.<CallSite>invokeExact(caller, name, type,
   17.19 -                                                             !(info instanceof java.lang.annotation.Annotation[]) ? null
   17.20 -                                                             : (java.lang.annotation.Annotation[]) info);
   17.21 +            Object binding;
   17.22 +            if (false)  // switch when invokeGeneric works
   17.23 +                binding = bootstrapMethod.invokeGeneric(caller, name, type);
   17.24              else
   17.25 -                throw new InternalError("bad BSM: "+bootstrapMethod);
   17.26 -            if (!(site instanceof CallSite))
   17.27 -                throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
   17.28 -            PRIVATE_INITIALIZE_CALL_SITE.<void>invokeExact(site,
   17.29 -                                                           name, type,
   17.30 +                binding = bootstrapMethod.invokeVarargs(new Object[]{ caller, name, type });
   17.31 +            //System.out.println("BSM for "+name+type+" => "+binding);
   17.32 +            if (binding instanceof CallSite) {
   17.33 +                site = (CallSite) binding;
   17.34 +            } else if (binding instanceof MethodHandleProvider) {
   17.35 +                MethodHandle target = ((MethodHandleProvider) binding).asMethodHandle();
   17.36 +                site = new ConstantCallSite(target);
   17.37 +            } else {
   17.38 +                throw new ClassCastException("bootstrap method failed to produce a MethodHandle or CallSite");
   17.39 +            }
   17.40 +            PRIVATE_INITIALIZE_CALL_SITE.<void>invokeExact(site, name, type,
   17.41                                                             callerMethod, callerBCI);
   17.42              assert(site.getTarget() != null);
   17.43              assert(site.getTarget().type().equals(type));
   17.44 @@ -77,11 +81,18 @@
   17.45  
   17.46      // This method is private in CallSite because it touches private fields in CallSite.
   17.47      // These private fields (vmmethod, vmindex) are specific to the JVM.
   17.48 -    private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
   17.49 +    private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE;
   17.50 +    static {
   17.51 +        try {
   17.52 +            PRIVATE_INITIALIZE_CALL_SITE =
   17.53              MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM",
   17.54                  MethodType.methodType(void.class,
   17.55                                        String.class, MethodType.class,
   17.56                                        MemberName.class, int.class));
   17.57 +        } catch (NoAccessException ex) {
   17.58 +            throw uncaughtException(ex);
   17.59 +        }
   17.60 +    }
   17.61  
   17.62      public static void setCallSiteTarget(Access token, CallSite site, MethodHandle target) {
   17.63          Access.check(token);
    18.1 --- a/src/share/classes/sun/dyn/FilterGeneric.java	Tue Nov 09 22:53:18 2010 -0800
    18.2 +++ b/src/share/classes/sun/dyn/FilterGeneric.java	Wed Nov 10 20:40:19 2010 -0800
    18.3 @@ -25,12 +25,8 @@
    18.4  
    18.5  package sun.dyn;
    18.6  
    18.7 -import java.dyn.JavaMethodHandle;
    18.8 -import java.dyn.MethodHandle;
    18.9 -import java.dyn.MethodType;
   18.10 -import java.dyn.NoAccessException;
   18.11 -import java.lang.reflect.Constructor;
   18.12 -import java.lang.reflect.InvocationTargetException;
   18.13 +import java.dyn.*;
   18.14 +import java.lang.reflect.*;
   18.15  import static sun.dyn.MemberName.newIllegalArgumentException;
   18.16  
   18.17  /**
   18.18 @@ -119,7 +115,7 @@
   18.19  
   18.20      static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
   18.21          FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
   18.22 -        return fgen.makeInstance(kind, pos, filter, target);
   18.23 +        return fgen.makeInstance(kind, pos, filter, target).asMethodHandle();
   18.24      }
   18.25  
   18.26      /** Return the adapter information for this target and filter type. */
    19.1 --- a/src/share/classes/sun/dyn/FilterOneArgument.java	Tue Nov 09 22:53:18 2010 -0800
    19.2 +++ b/src/share/classes/sun/dyn/FilterOneArgument.java	Wed Nov 10 20:40:19 2010 -0800
    19.3 @@ -25,9 +25,8 @@
    19.4  
    19.5  package sun.dyn;
    19.6  
    19.7 -import java.dyn.JavaMethodHandle;
    19.8 -import java.dyn.MethodHandle;
    19.9 -import java.dyn.MethodType;
   19.10 +import java.dyn.*;
   19.11 +import static sun.dyn.MemberName.uncaughtException;
   19.12  
   19.13  /**
   19.14   * Unary function composition, useful for many small plumbing jobs.
   19.15 @@ -51,8 +50,16 @@
   19.16          return target.invokeExact(filteredArgument);
   19.17      }
   19.18  
   19.19 -    private static final MethodHandle INVOKE =
   19.20 -        MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke", MethodType.genericMethodType(1));
   19.21 +    private static final MethodHandle INVOKE;
   19.22 +    static {
   19.23 +        try {
   19.24 +            INVOKE =
   19.25 +                MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
   19.26 +                                                         MethodType.genericMethodType(1));
   19.27 +        } catch (NoAccessException ex) {
   19.28 +            throw uncaughtException(ex);
   19.29 +        }
   19.30 +    }
   19.31  
   19.32      protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
   19.33          super(INVOKE);
    20.1 --- a/src/share/classes/sun/dyn/FromGeneric.java	Tue Nov 09 22:53:18 2010 -0800
    20.2 +++ b/src/share/classes/sun/dyn/FromGeneric.java	Wed Nov 10 20:40:19 2010 -0800
    20.3 @@ -25,15 +25,9 @@
    20.4  
    20.5  package sun.dyn;
    20.6  
    20.7 -import java.dyn.JavaMethodHandle;
    20.8 -import java.dyn.MethodHandle;
    20.9 -import java.dyn.MethodHandles;
   20.10 -import java.dyn.MethodType;
   20.11 -import java.dyn.NoAccessException;
   20.12 -import java.lang.reflect.Constructor;
   20.13 -import java.lang.reflect.InvocationTargetException;
   20.14 -import sun.dyn.util.ValueConversions;
   20.15 -import sun.dyn.util.Wrapper;
   20.16 +import java.dyn.*;
   20.17 +import java.lang.reflect.*;
   20.18 +import sun.dyn.util.*;
   20.19  
   20.20  /**
   20.21   * Adapters which mediate between incoming calls which are generic
    21.1 --- a/src/share/classes/sun/dyn/Invokers.java	Tue Nov 09 22:53:18 2010 -0800
    21.2 +++ b/src/share/classes/sun/dyn/Invokers.java	Wed Nov 10 20:40:19 2010 -0800
    21.3 @@ -25,10 +25,7 @@
    21.4  
    21.5  package sun.dyn;
    21.6  
    21.7 -import java.dyn.MethodHandle;
    21.8 -import java.dyn.MethodHandles;
    21.9 -import java.dyn.MethodType;
   21.10 -
   21.11 +import java.dyn.*;
   21.12  
   21.13  /**
   21.14   * Construction and caching of often-used invokers.
   21.15 @@ -63,8 +60,11 @@
   21.16      public MethodHandle exactInvoker() {
   21.17          MethodHandle invoker = exactInvoker;
   21.18          if (invoker != null)  return invoker;
   21.19 -        invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invoke", targetType);
   21.20 -        if (invoker == null)  throw new InternalError("JVM cannot find invoker for "+targetType);
   21.21 +        try {
   21.22 +            invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invoke", targetType);
   21.23 +        } catch (NoAccessException ex) {
   21.24 +            throw new InternalError("JVM cannot find invoker for "+targetType);
   21.25 +        }
   21.26          assert(invokerType(targetType) == invoker.type());
   21.27          exactInvoker = invoker;
   21.28          return invoker;
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/share/classes/sun/dyn/JavaMethodHandle.java	Wed Nov 10 20:40:19 2010 -0800
    22.3 @@ -0,0 +1,172 @@
    22.4 +/*
    22.5 + * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
    22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 + *
    22.8 + * This code is free software; you can redistribute it and/or modify it
    22.9 + * under the terms of the GNU General Public License version 2 only, as
   22.10 + * published by the Free Software Foundation.  Oracle designates this
   22.11 + * particular file as subject to the "Classpath" exception as provided
   22.12 + * by Oracle in the LICENSE file that accompanied this code.
   22.13 + *
   22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.17 + * version 2 for more details (a copy is included in the LICENSE file that
   22.18 + * accompanied this code).
   22.19 + *
   22.20 + * You should have received a copy of the GNU General Public License version
   22.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.23 + *
   22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.25 + * or visit www.oracle.com if you need additional information or have any
   22.26 + * questions.
   22.27 + */
   22.28 +
   22.29 +package sun.dyn;
   22.30 +
   22.31 +import java.dyn.*;
   22.32 +import sun.dyn.Access;
   22.33 +
   22.34 +/**
   22.35 + * A Java method handle is a deprecated proposal for extending
   22.36 + * the basic method handle type with additional
   22.37 + * programmer defined methods and fields.
   22.38 + * Its behavior as a method handle is determined at instance creation time,
   22.39 + * by providing the new instance with an "entry point" method handle
   22.40 + * to handle calls.  This entry point must accept a leading argument
   22.41 + * whose type is the Java method handle itself or a supertype, and the
   22.42 + * entry point is always called with the Java method handle itself as
   22.43 + * the first argument.  This is similar to ordinary virtual methods, which also
   22.44 + * accept the receiver object {@code this} as an implicit leading argument.
   22.45 + * The {@code MethodType} of the Java method handle is the same as that
   22.46 + * of the entry point method handle, with the leading parameter type
   22.47 + * omitted.
   22.48 + * <p>
   22.49 + * Here is an example of usage, creating a hybrid object/functional datum:
   22.50 + * <p><blockquote><pre>
   22.51 + * class Greeter extends JavaMethodHandle {
   22.52 + *     private String greeting = "hello";
   22.53 + *     public void setGreeting(String s) { greeting = s; }
   22.54 + *     public void run() { System.out.println(greeting+", "+greetee); }
   22.55 + *     private final String greetee;
   22.56 + *     Greeter(String greetee) {
   22.57 + *         super(RUN); // alternatively, super("run")
   22.58 + *         this.greetee = greetee;
   22.59 + *     }
   22.60 + *     // the entry point function is computed once:
   22.61 + *     private static final MethodHandle RUN
   22.62 + *         = MethodHandles.lookup().findVirtual(Greeter.class, "run",
   22.63 + *               MethodType.make(void.class));
   22.64 + * }
   22.65 + * // class Main { public static void main(String... av) { ...
   22.66 + * Greeter greeter = new Greeter("world");
   22.67 + * greeter.run();  // prints "hello, world"
   22.68 + * // Statically typed method handle invocation (most direct):
   22.69 + * MethodHandle mh = greeter;
   22.70 + * mh.&lt;void&gt;invokeExact();  // also prints "hello, world"
   22.71 + * // Dynamically typed method handle invocation:
   22.72 + * MethodHandles.invokeExact(greeter);  // also prints "hello, world"
   22.73 + * greeter.setGreeting("howdy");
   22.74 + * mh.invokeExact();  // prints "howdy, world" (object-like mutable behavior)
   22.75 + * </pre></blockquote>
   22.76 + * <p>
   22.77 + * In the example of {@code Greeter}, the method {@code run} provides the entry point.
   22.78 + * The entry point need not be a constant value; it may be independently
   22.79 + * computed in each call to the constructor.  The entry point does not
   22.80 + * even need to be a method on the {@code Greeter} class, though
   22.81 + * that is the typical case.
   22.82 + * <p>
   22.83 + * The entry point may also be provided symbolically, in which case the the
   22.84 + * {@code JavaMethodHandle} constructor performs the lookup of the entry point.
   22.85 + * This makes it possible to use {@code JavaMethodHandle} to create an anonymous
   22.86 + * inner class:
   22.87 + * <p><blockquote><pre>
   22.88 + * // We can also do this with symbolic names and/or inner classes:
   22.89 + * MethodHandles.invokeExact(new JavaMethodHandle("yow") {
   22.90 + *     void yow() { System.out.println("yow, world"); }
   22.91 + * });
   22.92 + * </pre></blockquote>
   22.93 + * <p>
   22.94 + * Here is similar lower-level code which works in terms of a bound method handle.
   22.95 + * <p><blockquote><pre>
   22.96 + *     class Greeter {
   22.97 + *         public void run() { System.out.println("hello, "+greetee); }
   22.98 + *         private final String greetee;
   22.99 + *         Greeter(String greetee) { this.greetee = greetee; }
  22.100 + *         // the entry point function is computed once:
  22.101 + *         private static final MethodHandle RUN
  22.102 + *             = MethodHandles.findVirtual(Greeter.class, "run",
  22.103 + *                   MethodType.make(void.class));
  22.104 + *     }
  22.105 + *     // class Main { public static void main(String... av) { ...
  22.106 + *     Greeter greeter = new Greeter("world");
  22.107 + *     greeter.run();  // prints "hello, world"
  22.108 + *     MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
  22.109 + *     mh.invokeExact();  // also prints "hello, world"
  22.110 + * </pre></blockquote>
  22.111 + * Note that the method handle must be separately created as a view on the base object.
  22.112 + * This increases footprint, complexity, and dynamic indirections.
  22.113 + * <p>
  22.114 + * Here is a pure functional value expressed most concisely as an anonymous inner class:
  22.115 + * <p><blockquote><pre>
  22.116 + *     // class Main { public static void main(String... av) { ...
  22.117 + *     final String greetee = "world";
  22.118 + *     MethodHandle greeter = new JavaMethodHandle("run") {
  22.119 + *         private void run() { System.out.println("hello, "+greetee); }
  22.120 + *     }
  22.121 + *     greeter.invokeExact();  // prints "hello, world"
  22.122 + * </pre></blockquote>
  22.123 + * <p>
  22.124 + * Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
  22.125 + * and instantiated as an anonymous class.  The data structure is a handle to 1-D array,
  22.126 + * with a specialized index type (long).  It is created by inner class, and uses
  22.127 + * signature-polymorphic APIs throughout.
  22.128 + * <p><blockquote><pre>
  22.129 + *     abstract class AssignableMethodHandle extends JavaMethodHandle {
  22.130 + *       private final MethodHandle setter;
  22.131 + *       public MethodHandle setter() { return setter; }
  22.132 + *       public AssignableMethodHandle(String get, String set) {
  22.133 + *         super(get);
  22.134 + *         MethodType getType = this.type();
  22.135 + *         MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
  22.136 + *         this.setter = MethodHandles.publicLookup().bind(this, set, setType);
  22.137 + *       }
  22.138 + *     }
  22.139 + *     // class Main { public static void main(String... av) { ...
  22.140 + *     final Number[] stuff = { 123, 456 };
  22.141 + *     AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
  22.142 + *         public Number get(long i)           { return stuff[(int)i]; }
  22.143 + *         public void   set(long i, Object x) {        stuff[(int)i] = x; }
  22.144 + *     }
  22.145 + *     int x = (Integer) stuffPtr.&lt;Number&gt;invokeExact(1L);  // 456
  22.146 + *     stuffPtr.setter().&lt;void&gt;invokeExact(0L, (Number) 789);  // replaces 123 with 789
  22.147 + * </pre></blockquote>
  22.148 + * @see MethodHandle
  22.149 + * @deprecated The JSR 292 EG intends to replace {@code JavaMethodHandle} with
  22.150 + * an interface-based API for mixing method handle behavior with other classes.
  22.151 + * @author John Rose, JSR 292 EG
  22.152 + */
  22.153 +public abstract class JavaMethodHandle
  22.154 +        // Note: This is an implementation inheritance hack, and will be removed
  22.155 +        // with a JVM change which moves the required hidden behavior onto this class.
  22.156 +        extends sun.dyn.BoundMethodHandle
  22.157 +{
  22.158 +    private static final Access IMPL_TOKEN = Access.getToken();
  22.159 +
  22.160 +    /**
  22.161 +     * When creating a {@code JavaMethodHandle}, the actual method handle
  22.162 +     * invocation behavior will be delegated to the specified {@code entryPoint}.
  22.163 +     * This may be any method handle which can take the newly constructed object
  22.164 +     * as a leading parameter.
  22.165 +     * <p>
  22.166 +     * The method handle type of {@code this} (i.e, the fully constructed object)
  22.167 +     * will be {@code entryPoint}, minus the leading argument.
  22.168 +     * The leading argument will be bound to {@code this} on every method
  22.169 +     * handle invocation.
  22.170 +     * @param entryPoint the method handle to handle calls
  22.171 +     */
  22.172 +    protected JavaMethodHandle(MethodHandle entryPoint) {
  22.173 +        super(entryPoint);
  22.174 +    }
  22.175 +}
    23.1 --- a/src/share/classes/sun/dyn/MemberName.java	Tue Nov 09 22:53:18 2010 -0800
    23.2 +++ b/src/share/classes/sun/dyn/MemberName.java	Wed Nov 10 20:40:19 2010 -0800
    23.3 @@ -521,6 +521,11 @@
    23.4          if (lookupClass != null)  message += ", from " + lookupClass.getName();
    23.5          return new NoAccessException(message);
    23.6      }
    23.7 +    public static Error uncaughtException(Exception ex) {
    23.8 +        Error err = new InternalError("uncaught exception");
    23.9 +        err.initCause(ex);
   23.10 +        return err;
   23.11 +    }
   23.12  
   23.13      /** Actually making a query requires an access check. */
   23.14      public static Factory getFactory(Access token) {
   23.15 @@ -641,7 +646,7 @@
   23.16           *  If lookup fails or access is not permitted, a {@linkplain NoAccessException} is thrown.
   23.17           *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
   23.18           */
   23.19 -        public MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass) {
   23.20 +        public MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass) throws NoAccessException {
   23.21              MemberName result = resolveOrNull(m, searchSupers, lookupClass);
   23.22              if (result != null)
   23.23                  return result;
    24.1 --- a/src/share/classes/sun/dyn/MethodHandleImpl.java	Tue Nov 09 22:53:18 2010 -0800
    24.2 +++ b/src/share/classes/sun/dyn/MethodHandleImpl.java	Wed Nov 10 20:40:19 2010 -0800
    24.3 @@ -25,11 +25,8 @@
    24.4  
    24.5  package sun.dyn;
    24.6  
    24.7 -import java.dyn.JavaMethodHandle;
    24.8 -import java.dyn.MethodHandle;
    24.9 -import java.dyn.MethodHandles;
   24.10 +import java.dyn.*;
   24.11  import java.dyn.MethodHandles.Lookup;
   24.12 -import java.dyn.MethodType;
   24.13  import java.util.logging.Level;
   24.14  import java.util.logging.Logger;
   24.15  import sun.dyn.util.VerifyType;
   24.16 @@ -46,6 +43,7 @@
   24.17  import sun.misc.Unsafe;
   24.18  import static sun.dyn.MemberName.newIllegalArgumentException;
   24.19  import static sun.dyn.MemberName.newNoAccessException;
   24.20 +import static sun.dyn.MemberName.uncaughtException;
   24.21  
   24.22  /**
   24.23   * Base class for method handles, containing JVM-specific fields and logic.
   24.24 @@ -173,7 +171,7 @@
   24.25       */
   24.26      public static
   24.27      MethodHandle findMethod(Access token, MemberName method,
   24.28 -            boolean doDispatch, Class<?> lookupClass) {
   24.29 +            boolean doDispatch, Class<?> lookupClass) throws NoAccessException {
   24.30          Access.check(token);  // only trusted calls
   24.31          MethodType mtype = method.getMethodType();
   24.32          if (!method.isStatic()) {
   24.33 @@ -320,7 +318,7 @@
   24.34              try {
   24.35                  VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
   24.36              } catch (NoAccessException ex) {
   24.37 -                throw new InternalError("");
   24.38 +                throw uncaughtException(ex);
   24.39              }
   24.40          }
   24.41          // Corresponding generic constructor types:
   24.42 @@ -416,9 +414,7 @@
   24.43                  f = c.getDeclaredField(field.getName());
   24.44                  return unsafe.staticFieldBase(f);
   24.45              } catch (Exception ee) {
   24.46 -                Error e = new InternalError();
   24.47 -                e.initCause(ee);
   24.48 -                throw e;
   24.49 +                throw uncaughtException(ee);
   24.50              }
   24.51          }
   24.52  
   24.53 @@ -473,10 +469,8 @@
   24.54              MethodHandle mh;
   24.55              try {
   24.56                  mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
   24.57 -            } catch (NoAccessException ee) {
   24.58 -                Error e = new InternalError("name,type="+name+type);
   24.59 -                e.initCause(ee);
   24.60 -                throw e;
   24.61 +            } catch (NoAccessException ex) {
   24.62 +                throw uncaughtException(ex);
   24.63              }
   24.64              if (evclass != vclass || (!isStatic && ecclass != cclass)) {
   24.65                  MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
   24.66 @@ -543,10 +537,8 @@
   24.67              MethodHandle mh;
   24.68              try {
   24.69                  mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
   24.70 -            } catch (NoAccessException ee) {
   24.71 -                Error e = new InternalError("name,type="+name+type);
   24.72 -                e.initCause(ee);
   24.73 -                throw e;
   24.74 +            } catch (NoAccessException ex) {
   24.75 +                throw uncaughtException(ex);
   24.76              }
   24.77              if (caclass != null) {
   24.78                  MethodType strongType = FieldAccessor.atype(caclass, isSetter);
   24.79 @@ -1031,7 +1023,7 @@
   24.80              try {
   24.81                  VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
   24.82              } catch (NoAccessException ex) {
   24.83 -                throw new InternalError("");
   24.84 +                throw uncaughtException(ex);
   24.85              }
   24.86          }
   24.87      }
   24.88 @@ -1167,7 +1159,7 @@
   24.89              try {
   24.90                  VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
   24.91              } catch (NoAccessException ex) {
   24.92 -                throw new InternalError("");
   24.93 +                throw uncaughtException(ex);
   24.94              }
   24.95          }
   24.96      }
   24.97 @@ -1207,9 +1199,16 @@
   24.98          return AdapterMethodHandle.makeRetypeRaw(token, type, THROW_EXCEPTION);
   24.99      }
  24.100  
  24.101 -    static final MethodHandle THROW_EXCEPTION
  24.102 +    static final MethodHandle THROW_EXCEPTION;
  24.103 +    static {
  24.104 +        try {
  24.105 +            THROW_EXCEPTION
  24.106              = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
  24.107                      MethodType.methodType(Empty.class, Throwable.class));
  24.108 +        } catch (NoAccessException ex) {
  24.109 +            throw new RuntimeException(ex);
  24.110 +        }
  24.111 +    }
  24.112      static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
  24.113  
  24.114      public static String getNameString(Access token, MethodHandle target) {
    25.1 --- a/src/share/classes/sun/dyn/MethodHandleNatives.java	Tue Nov 09 22:53:18 2010 -0800
    25.2 +++ b/src/share/classes/sun/dyn/MethodHandleNatives.java	Wed Nov 10 20:40:19 2010 -0800
    25.3 @@ -25,9 +25,7 @@
    25.4  
    25.5  package sun.dyn;
    25.6  
    25.7 -import java.dyn.CallSite;
    25.8 -import java.dyn.MethodHandle;
    25.9 -import java.dyn.MethodType;
   25.10 +import java.dyn.*;
   25.11  import java.dyn.MethodHandles.Lookup;
   25.12  import java.lang.reflect.AccessibleObject;
   25.13  import java.lang.reflect.Field;
   25.14 @@ -324,18 +322,24 @@
   25.15       */
   25.16      static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
   25.17                                                   Class<?> defc, String name, Object type) {
   25.18 -        Lookup lookup = IMPL_LOOKUP.in(callerClass);
   25.19 -        switch (refKind) {
   25.20 -        case REF_getField:          return lookup.findGetter(       defc, name, (Class<?>)   type );
   25.21 -        case REF_getStatic:         return lookup.findStaticGetter( defc, name, (Class<?>)   type );
   25.22 -        case REF_putField:          return lookup.findSetter(       defc, name, (Class<?>)   type );
   25.23 -        case REF_putStatic:         return lookup.findStaticSetter( defc, name, (Class<?>)   type );
   25.24 -        case REF_invokeVirtual:     return lookup.findVirtual(      defc, name, (MethodType) type );
   25.25 -        case REF_invokeStatic:      return lookup.findStatic(       defc, name, (MethodType) type );
   25.26 -        case REF_invokeSpecial:     return lookup.findSpecial(      defc, name, (MethodType) type, callerClass );
   25.27 -        case REF_newInvokeSpecial:  return lookup.findConstructor(  defc,       (MethodType) type );
   25.28 -        case REF_invokeInterface:   return lookup.findVirtual(      defc, name, (MethodType) type );
   25.29 +        try {
   25.30 +            Lookup lookup = IMPL_LOOKUP.in(callerClass);
   25.31 +            switch (refKind) {
   25.32 +            case REF_getField:          return lookup.findGetter(       defc, name, (Class<?>)   type );
   25.33 +            case REF_getStatic:         return lookup.findStaticGetter( defc, name, (Class<?>)   type );
   25.34 +            case REF_putField:          return lookup.findSetter(       defc, name, (Class<?>)   type );
   25.35 +            case REF_putStatic:         return lookup.findStaticSetter( defc, name, (Class<?>)   type );
   25.36 +            case REF_invokeVirtual:     return lookup.findVirtual(      defc, name, (MethodType) type );
   25.37 +            case REF_invokeStatic:      return lookup.findStatic(       defc, name, (MethodType) type );
   25.38 +            case REF_invokeSpecial:     return lookup.findSpecial(      defc, name, (MethodType) type, callerClass );
   25.39 +            case REF_newInvokeSpecial:  return lookup.findConstructor(  defc,       (MethodType) type );
   25.40 +            case REF_invokeInterface:   return lookup.findVirtual(      defc, name, (MethodType) type );
   25.41 +            }
   25.42 +            throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
   25.43 +        } catch (NoAccessException ex) {
   25.44 +            Error err = new IncompatibleClassChangeError();
   25.45 +            err.initCause(ex);
   25.46 +            throw err;
   25.47          }
   25.48 -        throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
   25.49      }
   25.50  }
    26.1 --- a/src/share/classes/sun/dyn/SpreadGeneric.java	Tue Nov 09 22:53:18 2010 -0800
    26.2 +++ b/src/share/classes/sun/dyn/SpreadGeneric.java	Wed Nov 10 20:40:19 2010 -0800
    26.3 @@ -25,11 +25,7 @@
    26.4  
    26.5  package sun.dyn;
    26.6  
    26.7 -import java.dyn.JavaMethodHandle;
    26.8 -import java.dyn.MethodHandle;
    26.9 -import java.dyn.MethodHandles;
   26.10 -import java.dyn.MethodType;
   26.11 -import java.dyn.NoAccessException;
   26.12 +import java.dyn.*;
   26.13  import java.lang.reflect.Constructor;
   26.14  import java.lang.reflect.InvocationTargetException;
   26.15  import java.util.ArrayList;
    27.1 --- a/src/share/classes/sun/dyn/ToGeneric.java	Tue Nov 09 22:53:18 2010 -0800
    27.2 +++ b/src/share/classes/sun/dyn/ToGeneric.java	Wed Nov 10 20:40:19 2010 -0800
    27.3 @@ -25,11 +25,7 @@
    27.4  
    27.5  package sun.dyn;
    27.6  
    27.7 -import java.dyn.JavaMethodHandle;
    27.8 -import java.dyn.MethodHandle;
    27.9 -import java.dyn.MethodHandles;
   27.10 -import java.dyn.MethodType;
   27.11 -import java.dyn.NoAccessException;
   27.12 +import java.dyn.*;
   27.13  import java.lang.reflect.Constructor;
   27.14  import java.lang.reflect.InvocationTargetException;
   27.15  import sun.dyn.util.ValueConversions;
    28.1 --- a/src/share/classes/sun/dyn/util/ValueConversions.java	Tue Nov 09 22:53:18 2010 -0800
    28.2 +++ b/src/share/classes/sun/dyn/util/ValueConversions.java	Wed Nov 10 20:40:19 2010 -0800
    28.3 @@ -34,6 +34,7 @@
    28.4  import sun.dyn.Access;
    28.5  import sun.dyn.AdapterMethodHandle;
    28.6  import sun.dyn.MethodHandleImpl;
    28.7 +import static sun.dyn.MemberName.uncaughtException;
    28.8  
    28.9  public class ValueConversions {
   28.10      private static final Access IMPL_TOKEN = Access.getToken();
   28.11 @@ -148,11 +149,16 @@
   28.12          // look up the method
   28.13          String name = "unbox" + wrap.simpleName() + (raw ? "Raw" : "");
   28.14          MethodType type = unboxType(wrap, raw);
   28.15 -        if (!exact)
   28.16 -            // actually, type is wrong; the Java method takes Object
   28.17 -            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
   28.18 -        else
   28.19 +        if (!exact) {
   28.20 +            try {
   28.21 +                // actually, type is wrong; the Java method takes Object
   28.22 +                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
   28.23 +            } catch (NoAccessException ex) {
   28.24 +                mh = null;
   28.25 +            }
   28.26 +        } else {
   28.27              mh = retype(type, unbox(wrap, !exact, raw));
   28.28 +        }
   28.29          if (mh != null) {
   28.30              cache.put(wrap, mh);
   28.31              return mh;
   28.32 @@ -280,10 +286,15 @@
   28.33          // look up the method
   28.34          String name = "box" + wrap.simpleName() + (raw ? "Raw" : "");
   28.35          MethodType type = boxType(wrap, raw);
   28.36 -        if (exact)
   28.37 -            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   28.38 -        else
   28.39 +        if (exact) {
   28.40 +            try {
   28.41 +                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   28.42 +            } catch (NoAccessException ex) {
   28.43 +                mh = null;
   28.44 +            }
   28.45 +        } else {
   28.46              mh = retype(type.erase(), box(wrap, !exact, raw));
   28.47 +        }
   28.48          if (mh != null) {
   28.49              cache.put(wrap, mh);
   28.50              return mh;
   28.51 @@ -394,10 +405,15 @@
   28.52          // look up the method
   28.53          String name = "reboxRaw" + wrap.simpleName();
   28.54          MethodType type = reboxType(wrap);
   28.55 -        if (exact)
   28.56 -            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   28.57 -        else
   28.58 +        if (exact) {
   28.59 +            try {
   28.60 +                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
   28.61 +            } catch (NoAccessException ex) {
   28.62 +                mh = null;
   28.63 +            }
   28.64 +        } else {
   28.65              mh = retype(IDENTITY.type(), rebox(wrap, !exact));
   28.66 +        }
   28.67          if (mh != null) {
   28.68              cache.put(wrap, mh);
   28.69              return mh;
   28.70 @@ -474,7 +490,11 @@
   28.71                  mh = EMPTY;
   28.72                  break;
   28.73              case INT: case LONG: case FLOAT: case DOUBLE:
   28.74 -                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
   28.75 +                try {
   28.76 +                    mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
   28.77 +                } catch (NoAccessException ex) {
   28.78 +                    mh = null;
   28.79 +                }
   28.80                  break;
   28.81          }
   28.82          if (mh != null) {
   28.83 @@ -549,8 +569,8 @@
   28.84              ZERO_OBJECT = IMPL_LOOKUP.findStatic(ValueConversions.class, "zeroObject", zeroObjectType);
   28.85              IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType);
   28.86              EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1));
   28.87 -        } catch (RuntimeException ex) {
   28.88 -            throw ex;
   28.89 +        } catch (Exception ex) {
   28.90 +            throw uncaughtException(ex);
   28.91          }
   28.92      }
   28.93  
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/test/java/dyn/ClassValueTest.java	Wed Nov 10 20:40:19 2010 -0800
    29.3 @@ -0,0 +1,164 @@
    29.4 +/*
    29.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    29.7 + *
    29.8 + * This code is free software; you can redistribute it and/or modify it
    29.9 + * under the terms of the GNU General Public License version 2 only, as
   29.10 + * published by the Free Software Foundation.  Oracle designates this
   29.11 + * particular file as subject to the "Classpath" exception as provided
   29.12 + * by Oracle in the LICENSE file that accompanied this code.
   29.13 + *
   29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   29.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   29.17 + * version 2 for more details (a copy is included in the LICENSE file that
   29.18 + * accompanied this code).
   29.19 + *
   29.20 + * You should have received a copy of the GNU General Public License version
   29.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   29.23 + *
   29.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   29.25 + * or visit www.oracle.com if you need additional information or have any
   29.26 + * questions.
   29.27 + */
   29.28 +
   29.29 +/* @test
   29.30 + * @summary tests for class-specific values
   29.31 + * @compile ClassValueTest.java
   29.32 + * @run junit/othervm test.java.dyn.ClassValueTest
   29.33 + */
   29.34 +
   29.35 +/*
   29.36 +  Manually:
   29.37 +   $ $JAVA7X_HOME/bin/javac -d foo -cp $JUNIT4_JAR test/java/dyn/ClassValueTest.java
   29.38 +   $ $JAVA7X_HOME/bin/java -cp foo:$JUNIT4_JAR org.junit.runner.JUnitCore test.java.dyn.ClassValueTest
   29.39 +  Output: .testAdd => 1000 : Integer
   29.40 + */
   29.41 +
   29.42 +package test.java.dyn;
   29.43 +
   29.44 +import java.util.*;
   29.45 +
   29.46 +import java.dyn.*;
   29.47 +
   29.48 +import org.junit.*;
   29.49 +import static org.junit.Assert.*;
   29.50 +
   29.51 +/**
   29.52 + * @author jrose
   29.53 + */
   29.54 +public class ClassValueTest {
   29.55 +    static String nameForCV1(Class<?> type) {
   29.56 +        return "CV1:" + type.getName();
   29.57 +    }
   29.58 +    static int countForCV1;
   29.59 +    static final ClassValue<String> CV1 = new ClassValue<String>() {
   29.60 +        protected String computeValue(Class<?> type) {
   29.61 +            countForCV1++;
   29.62 +            return nameForCV1(type);
   29.63 +        }
   29.64 +    };
   29.65 +
   29.66 +    static final Class[] CLASSES = {
   29.67 +        String.class,
   29.68 +        Integer.class,
   29.69 +        int.class,
   29.70 +        boolean[].class,
   29.71 +        char[][].class,
   29.72 +        ClassValueTest.class
   29.73 +    };
   29.74 +
   29.75 +    @Test
   29.76 +    public void testGet() {
   29.77 +        countForCV1 = 0;
   29.78 +        for (Class c : CLASSES) {
   29.79 +            assertEquals(nameForCV1(c), CV1.get(c));
   29.80 +        }
   29.81 +        assertEquals(CLASSES.length, countForCV1);
   29.82 +        for (Class c : CLASSES) {
   29.83 +            assertEquals(nameForCV1(c), CV1.get(c));
   29.84 +        }
   29.85 +        assertEquals(CLASSES.length, countForCV1);
   29.86 +    }
   29.87 +
   29.88 +    @Test
   29.89 +    public void testRemove() {
   29.90 +        for (Class c : CLASSES) {
   29.91 +            CV1.get(c);
   29.92 +        }
   29.93 +        countForCV1 = 0;
   29.94 +        int REMCOUNT = 3;
   29.95 +        for (int i = 0; i < REMCOUNT; i++) {
   29.96 +            CV1.remove(CLASSES[i]);
   29.97 +        }
   29.98 +        assertEquals(0, countForCV1);  // no change
   29.99 +        for (Class c : CLASSES) {
  29.100 +            assertEquals(nameForCV1(c), CV1.get(c));
  29.101 +        }
  29.102 +        assertEquals(REMCOUNT, countForCV1);
  29.103 +    }
  29.104 +
  29.105 +    static String nameForCVN(Class<?> type, int n) {
  29.106 +        return "CV[" + n + "]" + type.getName();
  29.107 +    }
  29.108 +    static int countForCVN;
  29.109 +    static class CVN extends ClassValue<String> {
  29.110 +        final int n;
  29.111 +        CVN(int n) { this.n = n; }
  29.112 +        protected String computeValue(Class<?> type) {
  29.113 +            countForCVN++;
  29.114 +            return nameForCVN(type, n);
  29.115 +        }
  29.116 +    };
  29.117 +
  29.118 +    @Test
  29.119 +    public void testGetMany() {
  29.120 +        int CVN_COUNT1 = 100, CVN_COUNT2 = 100;
  29.121 +        CVN cvns[] = new CVN[CVN_COUNT1 * CVN_COUNT2];
  29.122 +        for (int n = 0; n < cvns.length; n++) {
  29.123 +            cvns[n] = new CVN(n);
  29.124 +        }
  29.125 +        countForCVN = 0;
  29.126 +        for (int pass = 0; pass <= 2; pass++) {
  29.127 +            for (int i1 = 0; i1 < CVN_COUNT1; i1++) {
  29.128 +                eachClass:
  29.129 +                for (Class c : CLASSES) {
  29.130 +                    for (int i2 = 0; i2 < CVN_COUNT2; i2++) {
  29.131 +                        int n = i1*CVN_COUNT2 + i2;
  29.132 +                        assertEquals(0, countForCVN);
  29.133 +                        assertEquals(nameForCVN(c, n), cvns[n].get(c));
  29.134 +                        cvns[n].get(c);  //get it again
  29.135 +                        //System.out.println("getting "+n+":"+cvns[n].get(c));
  29.136 +                        boolean doremove = (((i1 + i2) & 3) == 0);
  29.137 +                        switch (pass) {
  29.138 +                        case 0:
  29.139 +                            assertEquals(1, countForCVN);
  29.140 +                            break;
  29.141 +                        case 1:
  29.142 +                            // remove on middle pass
  29.143 +                            assertEquals(0, countForCVN);
  29.144 +                            if (doremove) {
  29.145 +                                //System.out.println("removing "+n+":"+cvns[n].get(c));
  29.146 +                                cvns[n].remove(c);
  29.147 +                                assertEquals(0, countForCVN);
  29.148 +                            }
  29.149 +                            break;
  29.150 +                        case 2:
  29.151 +                            assertEquals(doremove ? 1 : 0, countForCVN);
  29.152 +                            break;
  29.153 +                        }
  29.154 +                        countForCVN = 0;
  29.155 +                        if (i1 > i2 && i1 < i2+5)  continue eachClass;  // leave diagonal gap
  29.156 +                    }
  29.157 +                }
  29.158 +            }
  29.159 +        }
  29.160 +        assertEquals(countForCVN, 0);
  29.161 +        for (int n = 0; n < cvns.length; n++) {
  29.162 +            for (Class c : CLASSES) {
  29.163 +                assertEquals(nameForCVN(c, n), cvns[n].get(c));
  29.164 +            }
  29.165 +        }
  29.166 +    }
  29.167 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/test/java/dyn/JavaDocExamples.java	Wed Nov 10 20:40:19 2010 -0800
    30.3 @@ -0,0 +1,128 @@
    30.4 +/*
    30.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    30.7 + *
    30.8 + * This code is free software; you can redistribute it and/or modify it
    30.9 + * under the terms of the GNU General Public License version 2 only, as
   30.10 + * published by the Free Software Foundation.  Oracle designates this
   30.11 + * particular file as subject to the "Classpath" exception as provided
   30.12 + * by Oracle in the LICENSE file that accompanied this code.
   30.13 + *
   30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   30.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   30.17 + * version 2 for more details (a copy is included in the LICENSE file that
   30.18 + * accompanied this code).
   30.19 + *
   30.20 + * You should have received a copy of the GNU General Public License version
   30.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   30.23 + *
   30.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   30.25 + * or visit www.oracle.com if you need additional information or have any
   30.26 + * questions.
   30.27 + */
   30.28 +
   30.29 +/* @test
   30.30 + * @summary example code used in javadoc for java.dyn API
   30.31 + * @compile -XDallowTransitionalJSR292=no JavaDocExamples.java
   30.32 + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.dyn.JavaDocExamples
   30.33 + */
   30.34 +
   30.35 +/*
   30.36 +---- To run outside jtreg:
   30.37 +$ $JAVA7X_HOME/bin/javac -cp $JUNIT4_JAR -d /tmp/Classes \
   30.38 +   $DAVINCI/sources/jdk/test/java/dyn/JavaDocExamples.java
   30.39 +$ $JAVA7X_HOME/bin/java   -cp $JUNIT4_JAR:/tmp/Classes \
   30.40 +   -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles \
   30.41 +   -Dtest.java.dyn.JavaDocExamples.verbosity=1 \
   30.42 +     test.java.dyn.JavaDocExamples
   30.43 +----
   30.44 +*/
   30.45 +
   30.46 +package test.java.dyn;
   30.47 +
   30.48 +import java.dyn.*;
   30.49 +import static java.dyn.MethodHandles.*;
   30.50 +import static java.dyn.MethodType.*;
   30.51 +
   30.52 +import java.lang.reflect.*;
   30.53 +import java.util.*;
   30.54 +
   30.55 +import org.junit.*;
   30.56 +import static org.junit.Assert.*;
   30.57 +import static org.junit.Assume.*;
   30.58 +
   30.59 +
   30.60 +/**
   30.61 + * @author jrose
   30.62 + */
   30.63 +public class JavaDocExamples {
   30.64 +    /** Wrapper for running the JUnit tests in this module.
   30.65 +     *  Put JUnit on the classpath!
   30.66 +     */
   30.67 +    public static void main(String... ignore) {
   30.68 +        org.junit.runner.JUnitCore.runClasses(JavaDocExamples.class);
   30.69 +    }
   30.70 +    // How much output?
   30.71 +    static int verbosity = Integer.getInteger("test.java.dyn.JavaDocExamples.verbosity", 0);
   30.72 +
   30.73 +{}
   30.74 +static final private Lookup LOOKUP = lookup();
   30.75 +// static final private MethodHandle CONCAT_1 = LOOKUP.findVirtual(String.class,
   30.76 +//     "concat", methodType(String.class, String.class));
   30.77 +// static final private MethodHandle HASHCODE_1 = LOOKUP.findVirtual(Object.class,
   30.78 +//     "hashCode", methodType(int.class));
   30.79 +
   30.80 +// form required if NoAccessException is intercepted:
   30.81 +static final private MethodHandle CONCAT_2, HASHCODE_2;
   30.82 +static {
   30.83 +  try {
   30.84 +    CONCAT_2 = LOOKUP.findVirtual(String.class,
   30.85 +      "concat", methodType(String.class, String.class));
   30.86 +    HASHCODE_2 = LOOKUP.findVirtual(Object.class,
   30.87 +      "hashCode", methodType(int.class));
   30.88 +   } catch (NoAccessException ex) {
   30.89 +     throw new RuntimeException(ex);
   30.90 +   }
   30.91 +}
   30.92 +{}
   30.93 +
   30.94 +    @Test public void testFindVirtual() throws Throwable {
   30.95 +{}
   30.96 +MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class,
   30.97 +  "concat", methodType(String.class, String.class));
   30.98 +MethodHandle HASHCODE_3 = LOOKUP.findVirtual(Object.class,
   30.99 +  "hashCode", methodType(int.class));
  30.100 +//assertEquals("xy", (String) CONCAT_1.invokeExact("x", "y"));
  30.101 +assertEquals("xy", (String) CONCAT_2.<String>invokeExact("x", "y"));
  30.102 +assertEquals("xy", (String) CONCAT_3.<String>invokeExact("x", "y"));
  30.103 +//assertEquals("xy".hashCode(), (int) HASHCODE_1.<int>invokeExact((Object)"xy"));
  30.104 +assertEquals("xy".hashCode(), (int) HASHCODE_2.<int>invokeExact((Object)"xy"));
  30.105 +assertEquals("xy".hashCode(), (int) HASHCODE_3.<int>invokeExact((Object)"xy"));
  30.106 +{}
  30.107 +    }
  30.108 +    @Test public void testDropArguments() throws Throwable {
  30.109 +        {{
  30.110 +{} /// JAVADOC
  30.111 +MethodHandle cat = lookup().findVirtual(String.class,
  30.112 +  "concat", methodType(String.class, String.class));
  30.113 +cat = cat.asType(methodType(Object.class, String.class, String.class)); /*(String)*/
  30.114 +assertEquals("xy", /*(String)*/ cat.invokeExact("x", "y"));
  30.115 +MethodHandle d0 = dropArguments(cat, 0, String.class);
  30.116 +assertEquals("yz", /*(String)*/ d0.invokeExact("x", "y", "z"));
  30.117 +MethodHandle d1 = dropArguments(cat, 1, String.class);
  30.118 +assertEquals("xz", /*(String)*/ d1.invokeExact("x", "y", "z"));
  30.119 +MethodHandle d2 = dropArguments(cat, 2, String.class);
  30.120 +assertEquals("xy", /*(String)*/ d2.invokeExact("x", "y", "z"));
  30.121 +MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
  30.122 +assertEquals("xz", /*(String)*/ d12.invokeExact("x", 12, true, "z"));
  30.123 +            }}
  30.124 +    }
  30.125 +
  30.126 +    static void assertEquals(Object exp, Object act) {
  30.127 +        if (verbosity > 0)
  30.128 +            System.out.println("result: "+act);
  30.129 +        Assert.assertEquals(exp, act);
  30.130 +    }
  30.131 +}
    31.1 --- a/test/java/dyn/MethodHandlesTest.java	Tue Nov 09 22:53:18 2010 -0800
    31.2 +++ b/test/java/dyn/MethodHandlesTest.java	Wed Nov 10 20:40:19 2010 -0800
    31.3 @@ -265,6 +265,12 @@
    31.4  //            wrap = Wrapper.forWrapperType(dst);
    31.5  //        if (wrap != Wrapper.OBJECT)
    31.6  //            return wrap.wrap(nextArg++);
    31.7 +        if (param.isInterface()) {
    31.8 +            for (Class<?> c : param.getClasses()) {
    31.9 +                if (param.isAssignableFrom(c) && !c.isInterface())
   31.10 +                    { param = c; break; }
   31.11 +            }
   31.12 +        }
   31.13          if (param.isInterface() || param.isAssignableFrom(String.class))
   31.14              return "#"+nextArg();
   31.15          else
   31.16 @@ -380,7 +386,7 @@
   31.17      }
   31.18      public static interface IntExample {
   31.19          public void            v0();
   31.20 -        static class Impl implements IntExample {
   31.21 +        public static class Impl implements IntExample {
   31.22              public void        v0()     { called("Int/v0", this); }
   31.23              final String name;
   31.24              public Impl() { name = "Impl#"+nextArg(); }
   31.25 @@ -449,7 +455,7 @@
   31.26          countTest(positive);
   31.27          MethodType type = MethodType.methodType(ret, params);
   31.28          MethodHandle target = null;
   31.29 -        RuntimeException noAccess = null;
   31.30 +        Exception noAccess = null;
   31.31          try {
   31.32              if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
   31.33              target = lookup.findStatic(defc, name, type);
   31.34 @@ -513,7 +519,7 @@
   31.35          String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
   31.36          MethodType type = MethodType.methodType(ret, params);
   31.37          MethodHandle target = null;
   31.38 -        RuntimeException noAccess = null;
   31.39 +        Exception noAccess = null;
   31.40          try {
   31.41              if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
   31.42              target = lookup.findVirtual(defc, methodName, type);
   31.43 @@ -567,7 +573,7 @@
   31.44          countTest(positive);
   31.45          MethodType type = MethodType.methodType(ret, params);
   31.46          MethodHandle target = null;
   31.47 -        RuntimeException noAccess = null;
   31.48 +        Exception noAccess = null;
   31.49          try {
   31.50              if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
   31.51              target = lookup.findSpecial(defc, name, type, specialCaller);
   31.52 @@ -623,7 +629,7 @@
   31.53          MethodType type = MethodType.methodType(ret, params);
   31.54          Object receiver = randomArg(defc);
   31.55          MethodHandle target = null;
   31.56 -        RuntimeException noAccess = null;
   31.57 +        Exception noAccess = null;
   31.58          try {
   31.59              if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
   31.60              target = lookup.bind(receiver, methodName, type);
   31.61 @@ -688,7 +694,7 @@
   31.62          MethodType type = MethodType.methodType(ret, params);
   31.63          Method rmethod = null;
   31.64          MethodHandle target = null;
   31.65 -        RuntimeException noAccess = null;
   31.66 +        Exception noAccess = null;
   31.67          try {
   31.68              rmethod = defc.getDeclaredMethod(name, params);
   31.69          } catch (NoSuchMethodException ex) {
   31.70 @@ -1088,7 +1094,11 @@
   31.71              if (rtype != Object.class)
   31.72                  pfx = rtype.getSimpleName().substring(0, 1).toLowerCase();
   31.73              String name = pfx+"id";
   31.74 -            return PRIVATE.findStatic(Callee.class, name, type);
   31.75 +            try {
   31.76 +                return PRIVATE.findStatic(Callee.class, name, type);
   31.77 +            } catch (Exception ex) {
   31.78 +                throw new RuntimeException(ex);
   31.79 +            }
   31.80          }
   31.81      }
   31.82  
   31.83 @@ -1327,7 +1337,8 @@
   31.84          MethodHandle result = MethodHandles.spreadArguments(target2, newType);
   31.85          Object[] returnValue;
   31.86          if (pos == 0) {
   31.87 -            returnValue = (Object[]) result.invokeExact(args);
   31.88 +            Object rawRetVal = result.invokeExact(args);
   31.89 +            returnValue = (Object[]) rawRetVal;
   31.90          } else {
   31.91              Object[] args1 = Arrays.copyOfRange(args, 0, pos+1);
   31.92              args1[pos] = Arrays.copyOfRange(args, pos, args.length);
   31.93 @@ -1817,8 +1828,13 @@
   31.94          testCastFailure("unbox/return", 11000);
   31.95      }
   31.96  
   31.97 -    static class Surprise extends JavaMethodHandle {
   31.98 -        Surprise() { super("value"); }
   31.99 +    static class Surprise implements MethodHandleProvider {
  31.100 +        public MethodHandle asMethodHandle() {
  31.101 +            return VALUE.bindTo(this);
  31.102 +        }
  31.103 +        public MethodHandle asMethodHandle(MethodType type) {
  31.104 +            return asMethodHandle().asType(type);
  31.105 +        }
  31.106          Object value(Object x) {
  31.107              trace("value", x);
  31.108              if (boo != null)  return boo;
  31.109 @@ -1833,22 +1849,32 @@
  31.110          static Object  refIdentity(Object x)  { trace("ref.x", x); return x; }
  31.111          static Integer boxIdentity(Integer x) { trace("box.x", x); return x; }
  31.112          static int     intIdentity(int x)     { trace("int.x", x); return x; }
  31.113 -        static MethodHandle REF_IDENTITY = PRIVATE.findStatic(
  31.114 -                Surprise.class, "refIdentity",
  31.115 -                    MethodType.methodType(Object.class, Object.class));
  31.116 -        static MethodHandle BOX_IDENTITY = PRIVATE.findStatic(
  31.117 -                Surprise.class, "boxIdentity",
  31.118 -                    MethodType.methodType(Integer.class, Integer.class));
  31.119 -        static MethodHandle INT_IDENTITY = PRIVATE.findStatic(
  31.120 -                Surprise.class, "intIdentity",
  31.121 -                    MethodType.methodType(int.class, int.class));
  31.122 +        static MethodHandle VALUE, REF_IDENTITY, BOX_IDENTITY, INT_IDENTITY;
  31.123 +        static {
  31.124 +            try {
  31.125 +                VALUE = PRIVATE.findVirtual(
  31.126 +                    Surprise.class, "value",
  31.127 +                        MethodType.methodType(Object.class, Object.class));
  31.128 +                REF_IDENTITY = PRIVATE.findStatic(
  31.129 +                    Surprise.class, "refIdentity",
  31.130 +                        MethodType.methodType(Object.class, Object.class));
  31.131 +                BOX_IDENTITY = PRIVATE.findStatic(
  31.132 +                    Surprise.class, "boxIdentity",
  31.133 +                        MethodType.methodType(Integer.class, Integer.class));
  31.134 +                INT_IDENTITY = PRIVATE.findStatic(
  31.135 +                    Surprise.class, "intIdentity",
  31.136 +                        MethodType.methodType(int.class, int.class));
  31.137 +            } catch (Exception ex) {
  31.138 +                throw new RuntimeException(ex);
  31.139 +            }
  31.140 +        }
  31.141      }
  31.142  
  31.143      void testCastFailure(String mode, int okCount) throws Throwable {
  31.144          countTest(false);
  31.145          if (verbosity > 2)  System.out.println("mode="+mode);
  31.146          Surprise boo = new Surprise();
  31.147 -        MethodHandle identity = Surprise.REF_IDENTITY, surprise = boo;
  31.148 +        MethodHandle identity = Surprise.REF_IDENTITY, surprise0 = boo.asMethodHandle(), surprise = surprise0;
  31.149          if (mode.endsWith("/return")) {
  31.150              if (mode.equals("unbox/return")) {
  31.151                  // fail on return to ((Integer)surprise).intValue
  31.152 @@ -1874,7 +1900,7 @@
  31.153                  identity = MethodHandles.filterArguments(callee, identity);
  31.154              }
  31.155          }
  31.156 -        assertNotSame(mode, surprise, boo);
  31.157 +        assertNotSame(mode, surprise, surprise0);
  31.158          identity = MethodHandles.convertArguments(identity, MethodType.genericMethodType(1));
  31.159          surprise = MethodHandles.convertArguments(surprise, MethodType.genericMethodType(1));
  31.160          Object x = 42;
  31.161 @@ -1936,6 +1962,107 @@
  31.162          mh.invokeVarargs(args);
  31.163          assertCalled(name, args);
  31.164      }
  31.165 +
  31.166 +    static void runForRunnable() {
  31.167 +        called("runForRunnable");
  31.168 +    }
  31.169 +    private interface Fooable {
  31.170 +        Object foo(Fooable x, Object y);
  31.171 +        // this is for randomArg:
  31.172 +        public class Impl implements Fooable {
  31.173 +            public Object foo(Fooable x, Object y) {
  31.174 +                throw new RuntimeException("do not call");
  31.175 +            }
  31.176 +            final String name;
  31.177 +            public Impl() { name = "Fooable#"+nextArg(); }
  31.178 +            @Override public String toString() { return name; }
  31.179 +        }
  31.180 +    }
  31.181 +    static Object fooForFooable(Fooable x, Object y) {
  31.182 +        return called("fooForFooable", x, y);
  31.183 +    }
  31.184 +    private static class MyCheckedException extends Exception {
  31.185 +    }
  31.186 +    private interface WillThrow {
  31.187 +        void willThrow() throws MyCheckedException;
  31.188 +    }
  31.189 +
  31.190 +    @Test
  31.191 +    public void testAsInstance() throws Throwable {
  31.192 +        if (CAN_SKIP_WORKING)  return;
  31.193 +        Lookup lookup = MethodHandles.lookup();
  31.194 +        {
  31.195 +            MethodType mt = MethodType.methodType(void.class);
  31.196 +            MethodHandle mh = lookup.findStatic(MethodHandlesTest.class, "runForRunnable", mt);
  31.197 +            Runnable proxy = MethodHandles.asInstance(mh, Runnable.class);
  31.198 +            proxy.run();
  31.199 +            assertCalled("runForRunnable");
  31.200 +        }
  31.201 +        {
  31.202 +            MethodType mt = MethodType.methodType(Object.class, Fooable.class, Object.class);
  31.203 +            MethodHandle mh = lookup.findStatic(MethodHandlesTest.class, "fooForFooable", mt);
  31.204 +            Fooable proxy = MethodHandles.asInstance(mh, Fooable.class);
  31.205 +            Object[] args = randomArgs(mt.parameterArray());
  31.206 +            Object result = proxy.foo((Fooable) args[0], args[1]);
  31.207 +            assertCalled("fooForFooable", args);
  31.208 +            assertEquals(result, logEntry("fooForFooable", args));
  31.209 +        }
  31.210 +        for (Throwable ex : new Throwable[] { new NullPointerException("ok"),
  31.211 +                                              new InternalError("ok"),
  31.212 +                                              new Throwable("fail"),
  31.213 +                                              new Exception("fail"),
  31.214 +                                              new MyCheckedException()
  31.215 +                                            }) {
  31.216 +            MethodHandle mh = MethodHandles.throwException(void.class, Throwable.class);
  31.217 +            mh = MethodHandles.insertArguments(mh, 0, ex);
  31.218 +            WillThrow proxy = MethodHandles.asInstance(mh, WillThrow.class);
  31.219 +            try {
  31.220 +                proxy.willThrow();
  31.221 +                System.out.println("Failed to throw: "+ex);
  31.222 +                assertTrue(false);
  31.223 +            } catch (Throwable ex1) {
  31.224 +                if (verbosity > 2) {
  31.225 +                    System.out.println("throw "+ex);
  31.226 +                    System.out.println("catch "+(ex == ex1 ? "UNWRAPPED" : ex1));
  31.227 +                }
  31.228 +                if (ex instanceof RuntimeException ||
  31.229 +                    ex instanceof Error) {
  31.230 +                    assertSame("must pass unchecked exception out without wrapping", ex, ex1);
  31.231 +                } else if (ex instanceof MyCheckedException) {
  31.232 +                    assertSame("must pass declared exception out without wrapping", ex, ex1);
  31.233 +                } else {
  31.234 +                    assertNotSame("must pass undeclared checked exception with wrapping", ex, ex1);
  31.235 +                    UndeclaredThrowableException utex = (UndeclaredThrowableException) ex1;
  31.236 +                    assertSame(ex, utex.getCause());
  31.237 +                }
  31.238 +            }
  31.239 +        }
  31.240 +        // Test error checking:
  31.241 +        MethodHandle genericMH = ValueConversions.varargsArray(0);
  31.242 +        genericMH = MethodHandles.convertArguments(genericMH, genericMH.type().generic());
  31.243 +        for (Class<?> sam : new Class[] { Runnable.class,
  31.244 +                                          Fooable.class,
  31.245 +                                          Iterable.class }) {
  31.246 +            try {
  31.247 +                // Must throw, because none of these guys has generic type.
  31.248 +                MethodHandles.asInstance(genericMH, sam);
  31.249 +                System.out.println("Failed to throw");
  31.250 +                assertTrue(false);
  31.251 +            } catch (IllegalArgumentException ex) {
  31.252 +            }
  31.253 +        }
  31.254 +        for (Class<?> nonSAM : new Class[] { Object.class,
  31.255 +                                             String.class,
  31.256 +                                             CharSequence.class,
  31.257 +                                             Example.class }) {
  31.258 +            try {
  31.259 +                MethodHandles.asInstance(ValueConversions.varargsArray(0), nonSAM);
  31.260 +                System.out.println("Failed to throw");
  31.261 +                assertTrue(false);
  31.262 +            } catch (IllegalArgumentException ex) {
  31.263 +            }
  31.264 +        }
  31.265 +    }
  31.266  }
  31.267  // Local abbreviated copy of sun.dyn.util.ValueConversions
  31.268  class ValueConversions {