# HG changeset patch # User attila # Date 1445237129 -7200 # Node ID 0bad500ce4e0f3d8d2420ba61cc5708dc7892604 # Parent f180be6368d825ec6db098d872b204d67f35acc2 8139590: Improve Dynalink JavaDoc Reviewed-by: hannesw, lagergren diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/CallSiteDescriptor.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/CallSiteDescriptor.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/CallSiteDescriptor.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,6 +83,7 @@ package jdk.internal.dynalink; +import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; @@ -93,64 +94,79 @@ import jdk.internal.dynalink.support.NameCodec; /** - * An immutable descriptor of a call site. It is an immutable object that contains all the information about a call - * site: the class performing the lookups, the name of the method being invoked, and the method signature. Call site descriptors are used in this library in place of passing a real call site to - * guarding linkers so they aren't tempted to directly manipulate the call sites. The constructors of built-in - * {@link RelinkableCallSite} implementations all need a call site descriptor. Even if you create your own call site - * descriptors consider using {@link CallSiteDescriptor#tokenizeName(String)} in your implementation. + * Interface for objects describing a call site. A call site descriptor contains + * all the information about a call site necessary for linking it: the class + * performing the lookups, the name of the method being invoked, and the method + * signature. Call site descriptors are used in Dynalink in place of passing + * {@link CallSite} objects to linkers so they can't directly manipulate them. + * The constructors of built-in {@link RelinkableCallSite} implementations all + * take a call site descriptor. Call site descriptors must be immutable. */ public interface CallSiteDescriptor { /** - * A permission to invoke the {@link #getLookup()} method. It is named {@code "dynalink.getLookup"}. + * A runtime permission to invoke the {@link #getLookup()} method. It is + * named {@code "dynalink.getLookup"}. */ - public static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission("dynalink.getLookup"); + public static final RuntimePermission GET_LOOKUP_PERMISSION = + new RuntimePermission("dynalink.getLookup"); /** - * The index of the name token that will carry the operation scheme prefix (usually, "dyn"). + * The index of the name token that will carry the operation scheme prefix, + * e.g. {@code "dyn"} for operations specified by Dynalink itself. */ public static final int SCHEME = 0; + /** - * The index of the name token that will usually carry the operation name. + * The index of the name token that carries the operation name, at least + * when using the {@code "dyn"} scheme. */ - public static final int OPERATOR=1; - /** - * The index of the name token that will usually carry a name of an operand (of a property, method, etc.) - */ - - public static final int NAME_OPERAND=2; + public static final int OPERATOR = 1; /** - * Character used to delimit tokens in an call site name. + * The index of the name token that carries the name of an operand (e.g. a + * property or a method), at least when using the {@code "dyn"} scheme. + */ + public static final int NAME_OPERAND = 2; + + /** + * String used to delimit tokens in a call site name; its value is + * {@code ":"}, that is the colon character. */ public static final String TOKEN_DELIMITER = ":"; /** - * Character used to delimit operation names in a composite operation specification. + * String used to delimit operation names in a composite operation name; + * its value is {@code "|"}, that is the pipe character. */ public static final String OPERATOR_DELIMITER = "|"; /** - * Returns the number of tokens in the name of the method at the call site. Method names are tokenized with the - * colon ":" character, i.e. "dyn:getProp:color" would be the name used to describe a method that retrieves the - * property named "color" on the object it is invoked on. + * Returns the number of tokens in the name of the method at the call site. + * Method names are tokenized with the {@link #TOKEN_DELIMITER} character + * character, e.g. {@code "dyn:getProp:color"} would be the name used to + * describe a method that retrieves the property named "color" on the object + * it is invoked on. * @return the number of tokens in the name of the method at the call site. */ public int getNameTokenCount(); /** - * Returns the ith token in the method name at the call site. Method names are tokenized with the - * colon ":" character. - * @param i the index of the token. Must be between 0 (inclusive) and {@link #getNameTokenCount()} (exclusive) - * @throws IllegalArgumentException if the index is outside the allowed range. - * @return the ith token in the method name at the call site. The returned strings are interned. + * Returns the ith token in the method name at the call + * site. Method names are tokenized with the {@link #TOKEN_DELIMITER} + * character. + * @param i the index of the token. Must be between 0 (inclusive) and + * {@link #getNameTokenCount()} (exclusive). + * @throws IllegalArgumentException if the index is outside the allowed + * range. + * @return the ith token in the method name at the call + * site. */ public String getNameToken(int i); /** - * Returns the name of the method at the call site. Note that the object internally only stores the tokenized name, - * and has to reconstruct the full name from tokens on each invocation. - * @return the name of the method at the call site. + * Returns the full (untokenized) name of the method at the call site. + * @return the full (untokenized) name of the method at the call site. */ public String getName(); @@ -162,17 +178,25 @@ public MethodType getMethodType(); /** - * Returns the lookup passed to the bootstrap method. - * @return the lookup passed to the bootstrap method. - * @throws SecurityException if the lookup isn't the {@link MethodHandles#publicLookup()} and a security - * manager is present, and a check for {@code RuntimePermission("dynalink.getLookup")} (available as + * Returns the lookup that should be used to find method handles to set as + * targets of the call site described by this descriptor. When creating + * descriptors from a {@link java.lang.invoke} bootstrap method, it should + * be the lookup passed to the bootstrap. An implementation should use + * {@link #checkLookup(MethodHandles.Lookup)} to ensure the necessary + * security properties. + * @return the lookup that should be used to find method handles to set as + * targets of the call site described by this descriptor. + * @throws SecurityException if the lookup isn't the + * {@link MethodHandles#publicLookup()} and a security manager is present, + * and a check for {@code RuntimePermission("dynalink.getLookup")} + * (a canonical instance of which is available as * {@link #GET_LOOKUP_PERMISSION}) fails. */ public Lookup getLookup(); /** - * Creates a new call site descriptor from this descriptor, which is identical to this, except it changes the method - * type. + * Creates a new call site descriptor from this descriptor, which is + * identical to this, except it changes the method type. * * @param newMethodType the new method type * @return a new call site descriptor, with the method type changed. @@ -181,9 +205,11 @@ /** - * Tokenizes a composite operation name along pipe characters. I.e. if you have a "dyn:getElem|getProp|getMethod" - * operation, returns a list of ["getElem", "getProp", "getMethod"]. The tokens are not interned. - * @return a list of tokens + * Tokenizes a composite operation name of this descriptor along + * {@link #OPERATOR_DELIMITER} characters. E.g. if this descriptor's name is + * {@code "dyn:getElem|getProp|getMethod"}, then it returns a list of + * {@code ["getElem", "getProp", "getMethod"]}. + * @return a list of operator tokens. */ public default List tokenizeOperators() { final String ops = getNameToken(CallSiteDescriptor.OPERATOR); @@ -200,15 +226,19 @@ } /** - * Checks if the current access context is granted the {@code RuntimePermission("dynalink.getLookup")} - * permission, if the system contains a security manager, and the passed lookup is not the - * {@link MethodHandles#publicLookup()}. + * Checks if the current access context is granted the + * {@code RuntimePermission("dynalink.getLookup")} permission, if the + * system contains a security manager, and the passed lookup is not the + * {@link MethodHandles#publicLookup()}. This method should be used in all + * implementations of {@link #getLookup()} method to ensure that only + * code with permission can retrieve the lookup object. * @param lookup the lookup being checked for access - * @return the passed in lookup if there's either no security manager in the system, or the passed lookup - * is the public lookup, or the current access context is granted the relevant permission. - * @throws SecurityException if the system contains a security manager, and the passed lookup is not the - * {@link MethodHandles#publicLookup()}, and the current access context is not granted the relevant - * permission. + * @return the passed in lookup if there's either no security manager in + * the system, or the passed lookup is the public lookup, or the current + * access context is granted the relevant permission. + * @throws SecurityException if the system contains a security manager, and + * the passed lookup is not the public lookup, and the current access + * context is not granted the relevant permission. */ public static Lookup checkLookup(final Lookup lookup) { final SecurityManager sm = System.getSecurityManager(); @@ -219,11 +249,14 @@ } /** - * Tokenizes the composite name along colons, as well as {@link NameCodec#decode(String) demangles} and interns - * the tokens. The first two tokens are not demangled as they are supposed to be the naming scheme and the name of - * the operation which can be expected to consist of just alphabetical characters. - * @param name the composite name consisting of colon-separated, possibly mangled tokens. - * @return an array of tokens + * Tokenizes the composite name along {@link #TOKEN_DELIMITER} characters, + * as well as {@link NameCodec#decode(String) demangles} and interns the + * tokens. The first two tokens are not demangled as they are supposed to + * be the naming scheme and the name of the operation which can be expected + * to consist of just alphabetical characters. + * @param name the composite name consisting of + * {@link #TOKEN_DELIMITER}-separated, possibly mangled tokens. + * @return an array of unmangled, interned tokens. */ public static String[] tokenizeName(final String name) { final StringTokenizer tok = new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java Mon Oct 19 08:45:29 2015 +0200 @@ -93,14 +93,21 @@ import jdk.internal.dynalink.support.Lookup; /** - * A relinkable call site that maintains a chain of linked method handles. In the default implementation, up to 8 method - * handles can be chained, cascading from one to the other through - * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. When this call site has to link a new - * method handle and the length of the chain is already at the maximum, it will throw away the oldest method handle. - * Switchpoint-invalidated handles in the chain are removed eagerly (on each linking request, and whenever a - * switchpoint-invalidated method handle is traversed during invocation). There is currently no profiling - * attached to the handles in the chain, so they are never reordered based on usage; the most recently linked method - * handle is always at the start of the chain. + * A relinkable call site that implements a polymorphic inline caching strategy. + * It remembers up to 8 {@link GuardedInvocation}s it was linked with, and on + * each relink request builds a cascading chain of method handles of one + * invocation falling back to the next one. The number of remembered invocations + * can be customized by overriding {@link #getMaxChainLength()} in a subclass. + * When this call site is relinked with a new invocation and the length of the + * chain is already at the maximum, it will throw away the oldest invocation. + * Invocations with invalidated switch points and ones for which their + * invalidating exception triggered are removed eagerly from the chain. The + * invocations are never reordered; the most recently linked method handle is + * always at the start of the chain and the least recently linked at its end. + * The call site can be safely relinked on more than one thread concurrently. + * Race conditions in linking are resolved by throwing away the + * {@link GuardedInvocation} produced on the losing thread without incorporating + * it into the chain, so it can lead to repeated linking for the same arguments. */ public class ChainedCallSite extends AbstractRelinkableCallSite { private static final MethodHandle PRUNE_CATCHES; @@ -130,22 +137,24 @@ } /** - * The maximum number of method handles in the chain. Defaults to 8. You can override it in a subclass if you need - * to change the value. If your override returns a value less than 1, the code will break. - * @return the maximum number of method handles in the chain. + * The maximum number of method handles in the chain. Defaults to 8. You can + * override it in a subclass if you need to change the value. + * @return the maximum number of method handles in the chain. The return + * value is checked, and if your override returns a value less than 1, a + * {@link RuntimeException} will be thrown. */ protected int getMaxChainLength() { return 8; } @Override - public void relink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) { - relinkInternal(guardedInvocation, fallback, false, false); + public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) { + relinkInternal(guardedInvocation, relinkAndInvoke, false, false); } @Override - public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) { - relinkInternal(guardedInvocation, fallback, true, false); + public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) { + relinkInternal(guardedInvocation, relinkAndInvoke, true, false); } private MethodHandle relinkInternal(final GuardedInvocation invocation, final MethodHandle relink, final boolean reset, final boolean removeCatches) { @@ -216,12 +225,12 @@ /** * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that * chain. - * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink). + * @param relinkAndInvoke the ultimate fallback for the chain passed from the dynamic linker. * @return a method handle for prune-and-invoke */ - private MethodHandle makePruneAndInvokeMethod(final MethodHandle relink, final MethodHandle prune) { + private MethodHandle makePruneAndInvokeMethod(final MethodHandle relinkAndInvoke, final MethodHandle prune) { // Bind prune to (this, relink) - final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relink); + final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relinkAndInvoke); // Make it ignore all incoming arguments final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList()); // Invoke prune, then invoke the call site target with original arguments diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java Mon Oct 19 08:45:29 2015 +0200 @@ -97,14 +97,13 @@ import jdk.internal.dynalink.support.SimpleLinkRequest; /** - * The linker for {@link RelinkableCallSite} objects. Users of it (scripting - * frameworks and language runtimes) have to create a linker using the - * {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic - * bootstrap methods to set the target of all the call sites in the code they - * generate. Usual usage would be to create one class per language runtime to - * contain one linker instance as: + * The linker for {@link RelinkableCallSite} objects. Users of Dynalink have to + * create a linker using the {@link DynamicLinkerFactory} and invoke its + * {@link #link(RelinkableCallSite)} method from the invokedynamic bootstrap + * methods to let it manage all the call sites they create. Usual usage would be + * to create one class per language runtime to contain one linker instance as: + *
  *
- * 
  * class MyLanguageRuntime {
  *     private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
  *     private static final DynamicLinker dynamicLinker = createDynamicLinker();
@@ -116,7 +115,7 @@
  *     }
  *
  *     public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
- *         return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(lookup, name, type)));
+ *         return dynamicLinker.link(new MonomorphicCallSite(new SimpleCallSiteDescriptor(lookup, name, type)));
  *     }
  * }
  * 
@@ -148,8 +147,8 @@ */ public final class DynamicLinker { /** - * A permission to invoke the {@link #getCurrentLinkRequest()} method. It is named - * {@code "dynalink.getCurrentLinkRequest"}. + * A permission to invoke the {@link #getCurrentLinkRequest()} method. It is + * named {@code "dynalink.getCurrentLinkRequest"}. */ public static final RuntimePermission GET_CURRENT_LINK_REQUEST_PERMISSION = new RuntimePermission("dynalink.getCurrentLinkRequest"); @@ -202,8 +201,8 @@ } /** - * Returns the object representing the lower level linker services of this - * class that are normally exposed to individual language-specific linkers. + * Returns the object representing the linker services of this class that + * are normally exposed to individual language-specific linkers. * While as a user of this class you normally only care about the * {@link #link(RelinkableCallSite)} method, in certain circumstances you * might want to use the lower level services directly; either to lookup @@ -275,11 +274,11 @@ } /** - * Returns a stack trace element describing the location of the call site - * currently being linked on the current thread. The operation internally - * creates a Throwable object and inspects its stack trace, so it's - * potentially expensive. The recommended usage for it is in writing - * diagnostics code. + * Returns a stack trace element describing the location of the + * {@code invokedynamic} call site currently being linked on the current + * thread. The operation is potentially expensive and is intended for use in + * diagnostics code. For "free-floating" call sites (not associated with an + * {@code invokedynamic} instruction), the result is not well-defined. * * @return a stack trace element describing the location of the call site * currently being linked, or null if it is not invoked while a call @@ -304,10 +303,12 @@ } /** - * Returns the currently processed link request, or null if the method is invoked outside of the linking process. + * Returns the currently processed link request, or null if the method is + * invoked outside of the linking process. * @return the currently processed link request, or null. - * @throws SecurityException if the calling code doesn't have the {@code "dynalink.getCurrentLinkRequest"} - * runtime permission (available as {@link #GET_CURRENT_LINK_REQUEST_PERMISSION}). + * @throws SecurityException if the calling code doesn't have the + * {@code "dynalink.getCurrentLinkRequest"} runtime permission (available as + * {@link #GET_CURRENT_LINK_REQUEST_PERMISSION}). */ public static LinkRequest getCurrentLinkRequest() { return LinkerServicesImpl.getCurrentLinkRequest(); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Oct 19 08:45:29 2015 +0200 @@ -107,16 +107,19 @@ import jdk.internal.dynalink.support.TypeUtilities; /** - * A factory class for creating {@link DynamicLinker}s. The usual dynamic linker is a linker composed of all - * {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any - * guarding linkers automatically discovered as declared in - * {@code /META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker} resources in the classpath (see - * {@link ServiceLoader} for the description of this mechanism), and the standard fallback {@link BeansLinker}. + * A factory class for creating {@link DynamicLinker} objects. The usual dynamic + * linker is a linker composed of all {@link GuardingDynamicLinker} objects + * known and pre-created by the caller as well as any guarding linkers + * automatically discovered as declared in + * {@code /META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker} + * resources in the classpath (see {@link ServiceLoader} for the description of + * this mechanism), and the standard fallback {@link BeansLinker}. * See {@link DynamicLinker} documentation for tips on how to use this class. */ public final class DynamicLinkerFactory { /** - * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}. + * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink + * threshold}. */ public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8; @@ -132,10 +135,21 @@ private MethodHandleTransformer internalObjectsFilter; /** - * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread - * context class loader at the time of {@link #createLinker()} invocation will be used. + * Creates a new dynamic linker factory with default configuration. Upon + * creation, the factory can be configured using various {@code setXxx()} + * methods and used to create one or more dynamic linkers according to its + * current configuration using {@link #createLinker()}. + */ + public DynamicLinkerFactory() { + } + + /** + * Sets the class loader for automatic discovery of available linkers. If + * not set explicitly, then the thread context class loader of the thread + * invoking {@link #createLinker()} invocation will be used. * - * @param classLoader the class loader used for the autodiscovery of available linkers. + * @param classLoader the class loader used for the automatic discovery of + * available linkers. */ public void setClassLoader(final ClassLoader classLoader) { this.classLoader = classLoader; diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/GuardedInvocationFilter.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/GuardedInvocationFilter.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/GuardedInvocationFilter.java Mon Oct 19 08:45:29 2015 +0200 @@ -88,19 +88,28 @@ import jdk.internal.dynalink.linker.LinkerServices; /** - * Interface for objects that are used to transform one guarded invocation into another one. Typical usage is for - * implementing {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter) pre-link filters}. + * Interface for objects that are used to transform one guarded invocation into + * another one. Typical usage is for implementing + * {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter) + * pre-link filters}. */ @FunctionalInterface public interface GuardedInvocationFilter { /** - * Given a guarded invocation, return a potentially different guarded invocation. - * @param inv the original guarded invocation. Null is never passed. - * @param linkRequest the link request for which the invocation was generated (usually by some linker). - * @param linkerServices the linker services that can be used during creation of a new invocation. - * @return either the passed guarded invocation or a different one, with the difference usually determined based on - * information in the link request and the differing invocation created with the assistance of the linker services. - * Whether or not {@code null} is an accepted return value is dependent on the user of the filter. + * Given a guarded invocation, return either the same or potentially + * different guarded invocation. + * @param inv the original guarded invocation. + * @param linkRequest the link request for which the invocation was + * generated (usually by some linker). + * @param linkerServices the linker services that can be used during + * creation of a new invocation. + * @return either the passed guarded invocation or a different one, with + * the difference usually determined based on information in the link + * request and the differing invocation created with the assistance of the + * linker services. Whether or not {@code null} is an accepted return value + * is dependent on the user of the filter. + * @throws NullPointerException is allowed if any of the passed arguments + * is null. */ public GuardedInvocation filter(GuardedInvocation inv, LinkRequest linkRequest, LinkerServices linkerServices); } diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/MonomorphicCallSite.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/MonomorphicCallSite.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/MonomorphicCallSite.java Mon Oct 19 08:45:29 2015 +0200 @@ -88,9 +88,10 @@ import jdk.internal.dynalink.support.AbstractRelinkableCallSite; /** - * A relinkable call site that implements monomorphic inline caching strategy. After it linked a method, it will keep it - * until either its guard evaluates to false, or its switchpoint is invalidated, at which time it will throw away the - * previous linkage, and trigger relinking with its associated {@link DynamicLinker}. + * A relinkable call site that implements monomorphic inline caching strategy, + * only being linked to a single {@link GuardedInvocation}. If that invocation + * is invalidated, it will throw it away and ask its associated + * {@link DynamicLinker} to relink it. */ public class MonomorphicCallSite extends AbstractRelinkableCallSite { /** @@ -102,12 +103,12 @@ } @Override - public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relink) { - setTarget(guardedInvocation.compose(relink)); + public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) { + setTarget(guardedInvocation.compose(relinkAndInvoke)); } @Override - public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relink) { - relink(guardedInvocation, relink); + public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) { + relink(guardedInvocation, relinkAndInvoke); } } diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/RelinkableCallSite.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/RelinkableCallSite.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/RelinkableCallSite.java Mon Oct 19 08:45:29 2015 +0200 @@ -85,23 +85,35 @@ import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MutableCallSite; -import java.lang.invoke.VolatileCallSite; import jdk.internal.dynalink.linker.GuardedInvocation; /** - * Interface for relinkable call sites. Language runtimes wishing to use this framework must use subclasses of - * {@link CallSite} that also implement this interface as their call sites. There is a readily usable - * {@link MonomorphicCallSite} subclass that implements monomorphic inline caching strategy as well as a - * {@link ChainedCallSite} that retains a chain of already linked method handles. The reason this is defined as an - * interface instead of a concrete, albeit abstract class is that it allows independent implementations to choose - * between {@link MutableCallSite} and {@link VolatileCallSite} as they see fit. + * Interface for call sites managed by a {@link DynamicLinker}. Users of + * Dynalink must use subclasses of {@link CallSite} that also implement this + * interface as their call site implementations. There is a readily usable + * {@link MonomorphicCallSite} subclass that implements monomorphic inline + * caching strategy as well as {@link ChainedCallSite} that implements a + * polymorphic inline caching strategy and retains a chain of previously linked + * method handles. A relinkable call site will be managed by a + * {@link DynamicLinker} object after being associated with it using its + * {@link DynamicLinker#link(RelinkableCallSite)} method. */ public interface RelinkableCallSite { /** - * Initializes the relinkable call site by setting a relink-and-invoke method handle. The call site - * implementation is supposed to set this method handle as its target. - * @param relinkAndInvoke a relink-and-invoke method handle supplied by the {@link DynamicLinker}. + * Invoked by dynamic linker to initialize the relinkable call site by + * setting a relink-and-invoke method handle. The call site implementation + * is supposed to set this method handle as its target using + * {@link CallSite#setTarget(MethodHandle)}. Relink-and-invoke is the + * initial method handle set by + * {@link DynamicLinker#link(RelinkableCallSite)} that will cause the call + * site to be relinked to an appropriate target on its first invocation + * based on its arguments, and that linked target will then be invoked + * (hence the name). This linking protocol effectively delays linking until + * the call site is invoked with actual arguments and thus ensures that + * linkers can make nuanced linking decisions based on those arguments and + * not just on the static method type of the call site. + * @param relinkAndInvoke a relink-and-invoke method handle supplied by + * Dynalink. */ public void initialize(MethodHandle relinkAndInvoke); @@ -113,33 +125,52 @@ public CallSiteDescriptor getDescriptor(); /** - * This method will be called by the dynamic linker every time the call site is normally relinked. It will be passed - * a {@code GuardedInvocation} that the call site should incorporate into its target method handle. When this method - * is called, the call site is allowed to keep other non-invalidated invocations around for implementation of - * polymorphic inline caches and compose them with this invocation to form its final target. + * This method will be called by the dynamic linker every time the call site + * is relinked (but see + * {@link #resetAndRelink(GuardedInvocation, MethodHandle)} for an + * exception). It will be passed a {@code GuardedInvocation} that the call + * site should incorporate into its target method handle. When this method + * is called, the call site is allowed to keep other non-invalidated + * invocations around for implementation of polymorphic inline caches and + * compose them with this invocation to form its final target. * - * @param guardedInvocation the guarded invocation that the call site should incorporate into its target method - * handle. - * @param fallback the fallback method. This is a method matching the method type of the call site that is supplied - * by the {@link DynamicLinker} to be used by this call site as a fallback when it can't invoke its target with the - * passed arguments. The fallback method is such that when it's invoked, it'll try to discover the adequate target - * for the invocation, subsequently invoke {@link #relink(GuardedInvocation, MethodHandle)} or - * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally invoke the target. + * @param guardedInvocation the guarded invocation that the call site should + * incorporate into its target method handle. + * @param relinkAndInvoke a relink-and-invoke method handle. This is a + * method handle matching the method type of the call site that is supplied + * by the {@link DynamicLinker} as a callback. It should be used by this + * call site as the ultimate fallback when it can't invoke its target with + * the passed arguments. The fallback method is such that when it's invoked, + * it'll try to obtain an adequate target {@link GuardedInvocation} for the + * invocation, and subsequently invoke + * {@link #relink(GuardedInvocation, MethodHandle)} or + * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally + * invoke the target. */ - public void relink(GuardedInvocation guardedInvocation, MethodHandle fallback); + public void relink(GuardedInvocation guardedInvocation, MethodHandle relinkAndInvoke); /** - * This method will be called by the dynamic linker every time the call site is relinked and the linker wishes the - * call site to throw away any prior linkage state. It will be passed a {@code GuardedInvocation} that the call site - * should use to build its target method handle. When this method is called, the call site is discouraged from - * keeping previous state around, and is supposed to only link the current invocation. + * This method will be called by the dynamic linker every time the call site + * is relinked and the linker wishes the call site to throw away any + * prior linkage state (that is how it differs from + * {@link #relink(GuardedInvocation, MethodHandle)}). It will be passed a + * {@code GuardedInvocation} that the call site should use to build its new + * target method handle. When this method is called, the call site is + * discouraged from keeping any previous state, and is supposed to only + * link the current invocation. * - * @param guardedInvocation the guarded invocation that the call site should use to build its target method handle. - * @param fallback the fallback method. This is a method matching the method type of the call site that is supplied - * by the {@link DynamicLinker} to be used by this call site as a fallback when it can't invoke its target with the - * passed arguments. The fallback method is such that when it's invoked, it'll try to discover the adequate target - * for the invocation, subsequently invoke {@link #relink(GuardedInvocation, MethodHandle)} or - * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally invoke the target. + * @param guardedInvocation the guarded invocation that the call site should + * use to build its target method handle. + * @param relinkAndInvoke a relink-and-invoke method handle. This is a + * method handle matching the method type of the call site that is supplied + * by the {@link DynamicLinker} as a callback. It should be used by this + * call site as the ultimate fallback when it can't invoke its target with + * the passed arguments. The fallback method is such that when it's invoked, + * it'll try to obtain an adequate target {@link GuardedInvocation} for the + * invocation, and subsequently invoke + * {@link #relink(GuardedInvocation, MethodHandle)} or + * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally + * invoke the target. */ - public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle fallback); + public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle relinkAndInvoke); } diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/TypeConverterFactory.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/TypeConverterFactory.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/TypeConverterFactory.java Mon Oct 19 08:45:29 2015 +0200 @@ -382,7 +382,6 @@ if(next != null) { cacheable = cacheable && next.isCacheable(); final GuardedInvocation conversionInvocation = next.getConversionInvocation(); - conversionInvocation.assertType(type); last = conversionInvocation.compose(last); } } diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeansLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeansLinker.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeansLinker.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,7 +83,7 @@ package jdk.internal.dynalink.beans; -import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; import java.util.Collection; import java.util.Collections; import jdk.internal.dynalink.CallSiteDescriptor; @@ -95,36 +95,59 @@ import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; /** - * A linker for POJOs. Normally used as the ultimate fallback linker by the {@link DynamicLinkerFactory} so it is given - * the chance to link calls to all objects that no other language runtime recognizes. Specifically, this linker will: + * A linker for ordinary Java objects. Normally used as the ultimate fallback + * linker by the {@link DynamicLinkerFactory} so it is given the chance to link + * calls to all objects that no other linker recognized. Specifically, this + * linker will: * - *

Overloaded method resolution is performed automatically for property setters, methods, and - * constructors. Additionally, manual overloaded method selection is supported by having a call site specify a name for - * a method that contains an explicit signature, i.e. {@code dyn:getMethod:parseInt(String,int)}. You can use - * non-qualified class names in such signatures regardless of those classes' packages, they will match any class with - * the same non-qualified name. You only have to use a fully qualified class name in case non-qualified class names - * would cause selection ambiguity (that is extremely rare).

- *

Variable argument invocation is handled for both methods and constructors.

- *

Currently, only public fields and methods are supported. Any Lookup objects passed in the - * {@link LinkRequest}s are ignored and {@link MethodHandles#publicLookup()} is used instead.

+ *

Overloaded method resolution is performed automatically + * for property setters, methods, and constructors. Additionally, manual + * overloaded method selection is supported by having a call site specify a name + * for a method that contains an explicit signature, i.e. + * {@code dyn:getMethod:parseInt(String,int)}. You can use non-qualified class + * names in such signatures regardless of those classes' packages, they will + * match any class with the same non-qualified name. You only have to use a + * fully qualified class name in case non-qualified class names would cause + * selection ambiguity (that is extremely rare). Overloaded resolution for + * constructors is not automatic as there is no logical place to attach that + * functionality to but if a language wishes to provide this functionality, it + * can use {@link #getConstructorMethod(Class, String)} as a useful building + * block for it.

+ *

Variable argument invocation is handled for both methods + * and constructors.

+ *

Caller sensitive methods can be linked as long as they + * are otherwise public and link requests have call site descriptors carrying + * full-strength {@link Lookup} objects and not weakened lookups or the public + * lookup.

+ *

The class also exposes various static methods for discovery of available + * property and method names on classes and class instances, as well as access + * to per-class linkers using the {@link #getLinkerForClass(Class)} + * method.

*/ public class BeansLinker implements GuardingDynamicLinker { private static final ClassValue linkers = new ClassValue() { @@ -140,15 +163,16 @@ }; /** - * Creates a new POJO linker. + * Creates a new beans linker. */ public BeansLinker() { } /** - * Returns a bean linker for a particular single class. Useful when you need to override or extend the behavior of - * linking for some classes in your language runtime's linker, but still want to delegate to the default behavior in - * some cases. + * Returns a bean linker for a particular single class. Useful when you need + * to override or extend the behavior of linking for some classes in your + * language runtime's linker, but still want to delegate to the default + * behavior in some cases. * @param clazz the class * @return a bean linker for that class */ @@ -157,9 +181,12 @@ } /** - * Returns true if the object is a Dynalink Java dynamic method. + * Returns true if the object is a Java dynamic method (e.g., one + * obtained through a {@code dyn:getMethod} call on a Java object or + * {@link StaticClass} or through + * {@link #getConstructorMethod(Class, String)}. * - * @param obj the object we want to test for being a dynamic method + * @param obj the object we want to test for being a Java dynamic method. * @return true if it is a dynamic method, false otherwise. */ public static boolean isDynamicMethod(final Object obj) { @@ -167,9 +194,10 @@ } /** - * Returns true if the object is a Dynalink Java constructor. + * Returns true if the object is a Java constructor (obtained through + * {@link #getConstructorMethod(Class, String)}}. * - * @param obj the object we want to test for being a constructor + * @param obj the object we want to test for being a Java constructor. * @return true if it is a constructor, false otherwise. */ public static boolean isDynamicConstructor(final Object obj) { @@ -177,10 +205,15 @@ } /** - * Return the dynamic method of constructor of the given class and the given signature. + * Return the dynamic method of constructor of the given class and the given + * signature. This method is useful for exposing a functionality for + * selecting an overloaded constructor based on an explicit signature, as + * this functionality is not otherwise exposed by Dynalink as + * {@link StaticClass} objects act as overloaded constructors without + * explicit signature selection. * @param clazz the class * @param signature full signature of the constructor - * @return DynamicMethod for the constructor + * @return dynamic method for the constructor */ public static Object getConstructorMethod(final Class clazz, final String signature) { return StaticClassLinker.getConstructorMethod(clazz, signature); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/StaticClass.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/StaticClass.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/StaticClass.java Mon Oct 19 08:45:29 2015 +0200 @@ -87,12 +87,22 @@ import java.util.Objects; /** - * Object that represents the static facet of a class (its static methods, properties, and fields, as well as - * construction of instances using "dyn:new"). Objects of this class are recognized by the {@link BeansLinker} as being - * special, and operations on them will be linked against the represented class' static facet. The "class" synthetic - * property is additionally recognized and returns the Java {@link Class} object, as per {@link #getRepresentedClass()} - * method. Conversely, {@link Class} objects exposed through {@link BeansLinker} expose the "static" synthetic property - * which returns an instance of this class. + * Object that represents the static aspect of a class (its static methods, + * properties, and fields, as well as construction of instances using + * {@code "dyn:new"} operation). Objects of this class are recognized by the + * {@link BeansLinker} as being special, and operations on them will be linked + * against the represented class' static aspect. The {@code "class"} synthetic + * property is additionally recognized and returns the Java {@link Class} + * object, as per {@link #getRepresentedClass()} method. Conversely, + * {@link Class} objects exposed through {@link BeansLinker} expose the + * {@code "static"} synthetic property which returns an instance of this class. + * Instances of this class act as namespaces for static members and as + * constructors for classes, much the same way as specifying a class name in + * Java does, except that in Dynalink they are expressed as actual objects + * exposing static methods and properties of classes. As a special case, + * {@code StaticClass} objects representing Java array types will act as + * constructors taking a single int argument and create an array of the + * specified size. */ public class StaticClass implements Serializable { private static final ClassValue staticClasses = new ClassValue() { diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/ConversionComparator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/ConversionComparator.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/ConversionComparator.java Mon Oct 19 08:45:29 2015 +0200 @@ -85,11 +85,14 @@ /** - * Optional interface to be implemented by {@link GuardingTypeConverterFactory} implementers. Language-specific - * conversions can cause increased overloaded method resolution ambiguity, as many methods can become applicable because - * of additional conversions. The static way of selecting the "most specific" method will fail more often, because there - * will be multiple maximally specific method with unrelated signatures. In these cases, language runtimes can be asked - * to resolve the ambiguity by expressing preferences for one conversion over the other. + * Optional interface to be implemented by {@link GuardingTypeConverterFactory} + * implementers. Language-specific conversions can cause increased overloaded + * method resolution ambiguity, as many methods can become applicable because of + * additional conversions. The static way of selecting the "most specific" + * method will fail more often, because there will be multiple maximally + * specific method with unrelated signatures. In these cases, language runtimes + * can be asked to resolve the ambiguity by expressing preferences for one + * conversion over the other. */ public interface ConversionComparator { /** @@ -105,12 +108,13 @@ } /** - * Determines which of the two target types is the preferred conversion target from a source type. + * Determines which of the two target types is the preferred conversion + * target from a source type. * @param sourceType the source type. * @param targetType1 one potential target type * @param targetType2 another potential target type. - * @return one of Comparison constants that establish which - if any - of the target types is preferred for the - * conversion. + * @return one of Comparison constants that establish which - if any - of + * the target types is preferred for the conversion. */ public Comparison compareConversion(Class sourceType, Class targetType1, Class targetType2); } diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,24 +83,30 @@ package jdk.internal.dynalink.linker; -import static jdk.nashorn.internal.lookup.Lookup.MH; - import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.invoke.SwitchPoint; -import java.lang.invoke.WrongMethodTypeException; import java.util.List; import java.util.Objects; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.support.Guards; /** - * Represents a conditionally valid method handle. It is an immutable triple of an invocation method handle, a guard - * method handle that defines the applicability of the invocation handle, and a switch point that can be used for - * external invalidation of the invocation handle. The invocation handle is suitable for invocation if the guard - * handle returns true for its arguments, and as long as the switch point is not invalidated. Both the guard and the - * switch point are optional; neither, one, or both can be present. + * Represents a conditionally valid method handle. Usually produced as a return + * value of + * {@link GuardingDynamicLinker#getGuardedInvocation(LinkRequest, LinkerServices)} + * and {@link GuardingTypeConverterFactory#convertToType(Class, Class)}. It is + * an immutable tuple of an invocation method handle, a guard method handle that + * defines the applicability of the invocation handle, zero or more switch + * points that can be used for external invalidation of the invocation handle, + * and an exception type that if thrown during an invocation of the method + * handle also invalidates it. The invocation handle is suitable for invocation + * if the guard handle returns true for its arguments, and as long as any of the + * switch points are not invalidated, and as long as it does not throw an + * exception of the designated type. The guard, the switch point, and the + * exception type are all optional (a guarded invocation having none of them is + * unconditionally valid). */ public class GuardedInvocation { private final MethodHandle invocation; @@ -109,9 +115,11 @@ private final SwitchPoint[] switchPoints; /** - * Creates a new guarded invocation. This invocation is unconditional as it has no invalidations. + * Creates a new unconditional guarded invocation. It is unconditional as it + * has no invalidations. * - * @param invocation the method handle representing the invocation. Must not be null. + * @param invocation the method handle representing the invocation. Must not + * be null. * @throws NullPointerException if invocation is null. */ public GuardedInvocation(final MethodHandle invocation) { @@ -119,12 +127,15 @@ } /** - * Creates a new guarded invocation. + * Creates a new guarded invocation, with a guard method handle. * - * @param invocation the method handle representing the invocation. Must not be null. - * @param guard the method handle representing the guard. Must have the same method type as the invocation, except - * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null to represent - * an unconditional invocation, although that is unusual. + * @param invocation the method handle representing the invocation. Must not + * be null. + * @param guard the method handle representing the guard. Must have be + * compatible with the {@code invocation} handle as per + * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. + * For some useful guards, check out the {@link Guards} class. It can be + * null to represent an unconditional invocation. * @throws NullPointerException if invocation is null. */ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard) { @@ -132,10 +143,14 @@ } /** - * Creates a new guarded invocation. + * Creates a new guarded invocation that can be invalidated by a switch + * point. * - * @param invocation the method handle representing the invocation. Must not be null. - * @param switchPoint the optional switch point that can be used to invalidate this linkage. + * @param invocation the method handle representing the invocation. Must + * not be null. + * @param switchPoint the optional switch point that can be used to + * invalidate this linkage. It can be null. If it is null, this represents + * an unconditional invocation. * @throws NullPointerException if invocation is null. */ public GuardedInvocation(final MethodHandle invocation, final SwitchPoint switchPoint) { @@ -143,13 +158,19 @@ } /** - * Creates a new guarded invocation. + * Creates a new guarded invocation, with both a guard method handle and a + * switch point that can be used to invalidate it. * - * @param invocation the method handle representing the invocation. Must not be null. - * @param guard the method handle representing the guard. Must have the same method type as the invocation, except - * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it - * and the switch point are null, this represents an unconditional invocation, which is legal but unusual. - * @param switchPoint the optional switch point that can be used to invalidate this linkage. + * @param invocation the method handle representing the invocation. Must + * not be null. + * @param guard the method handle representing the guard. Must have be + * compatible with the {@code invocation} handle as per + * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. + * For some useful guards, check out the {@link Guards} class. It can be + * null. If both it and the switch point are null, this represents an + * unconditional invocation. + * @param switchPoint the optional switch point that can be used to + * invalidate this linkage. * @throws NullPointerException if invocation is null. */ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint) { @@ -157,15 +178,22 @@ } /** - * Creates a new guarded invocation. + * Creates a new guarded invocation, with a guard method handle, a + * switch point that can be used to invalidate it, and an exception that if + * thrown when invoked also invalidates it. * - * @param invocation the method handle representing the invocation. Must not be null. - * @param guard the method handle representing the guard. Must have the same method type as the invocation, except - * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it - * and the switch point are null, this represents an unconditional invocation, which is legal but unusual. - * @param switchPoint the optional switch point that can be used to invalidate this linkage. - * @param exception the optional exception type that is expected to be thrown by the invocation and that also - * invalidates the linkage. + * @param invocation the method handle representing the invocation. Must not + * be null. + * @param guard the method handle representing the guard. Must have be + * compatible with the {@code invocation} handle as per + * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. + * For some useful guards, check out the {@link Guards} class. It can be + * null. If it and the switch point and the exception are all null, this + * represents an unconditional invocation. + * @param switchPoint the optional switch point that can be used to + * invalidate this linkage. + * @param exception the optional exception type that is when thrown by the + * invocation also invalidates it. * @throws NullPointerException if invocation is null. */ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint, final Class exception) { @@ -176,15 +204,22 @@ } /** - * Creates a new guarded invocation + * Creates a new guarded invocation, with a guard method handle, any number + * of switch points that can be used to invalidate it, and an exception that + * if thrown when invoked also invalidates it. * - * @param invocation the method handle representing the invocation. Must not be null. - * @param guard the method handle representing the guard. Must have the same method type as the invocation, except - * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it - * and the switch point are null, this represents an unconditional invocation, which is legal but unusual. - * @param switchPoints the optional switch points that can be used to invalidate this linkage. - * @param exception the optional exception type that is expected to be thrown by the invocation and that also - * invalidates the linkage. + * @param invocation the method handle representing the invocation. Must not + * be null. + * @param guard the method handle representing the guard. Must have be + * compatible with the {@code invocation} handle as per + * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. + * For some useful guards, check out the {@link Guards} class. It can be + * null. If it and the exception are both null, and no switch points were + * specified, this represents an unconditional invocation. + * @param switchPoints optional switch points that can be used to + * invalidate this linkage. + * @param exception the optional exception type that is when thrown by the + * invocation also invalidates it. * @throws NullPointerException if invocation is null. */ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint[] switchPoints, final Class exception) { @@ -213,26 +248,32 @@ } /** - * Returns the switch point that can be used to invalidate the invocation handle. + * Returns the switch points that can be used to invalidate the linkage of + * this invocation handle. * - * @return the switch point that can be used to invalidate the invocation handle. Can be null. + * @return the switch points that can be used to invalidate the linkage of + * this invocation handle. Can be null. */ public SwitchPoint[] getSwitchPoints() { return switchPoints == null ? null : switchPoints.clone(); } /** - * Returns the exception type that if thrown should be used to invalidate the linkage. + * Returns the exception type that if thrown by the invocation should + * invalidate the linkage of this guarded invocation. * - * @return the exception type that if thrown should be used to invalidate the linkage. Can be null. + * @return the exception type that if thrown should be used to invalidate + * the linkage. Can be null. */ public Class getException() { return exception; } /** - * Returns true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated. - * @return true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated. + * Returns true if and only if this guarded invocation has at least one + * invalidated switch point. + * @return true if and only if this guarded invocation has at least one + * invalidated switch point. */ public boolean hasBeenInvalidated() { if (switchPoints == null) { @@ -247,20 +288,6 @@ } /** - * Asserts that the invocation is of the specified type, and the guard (if present) is of the specified type with a - * boolean return type. - * - * @param type the asserted type - * @throws WrongMethodTypeException if the invocation and the guard are not of the expected method type. - */ - public void assertType(final MethodType type) { - assertType(invocation, type); - if (guard != null) { - assertType(guard, type.changeReturnType(Boolean.TYPE)); - } - } - - /** * Creates a new guarded invocation with different methods, preserving the switch point. * * @param newInvocation the new invocation @@ -272,9 +299,10 @@ } /** - * Add a switchpoint to this guarded invocation - * @param newSwitchPoint new switchpoint, or null for nop - * @return new guarded invocation with the extra switchpoint + * Create a new guarded invocation with an added switch point. + * @param newSwitchPoint new switch point. Can be null in which case this + * method return the current guarded invocation with no changes. + * @return a guarded invocation with the added switch point. */ public GuardedInvocation addSwitchPoint(final SwitchPoint newSwitchPoint) { if (newSwitchPoint == null) { @@ -301,9 +329,11 @@ } /** - * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation - * and its guard, if it has one (with return type changed to boolean, and parameter count potentially truncated for - * the guard). If the invocation already is of the required type, returns this object. + * Changes the type of the invocation, as if + * {@link MethodHandle#asType(MethodType)} was applied to its invocation + * and its guard, if it has one (with return type changed to boolean, and + * parameter count potentially truncated for the guard). If the invocation + * already is of the required type, returns this object. * @param newType the new type of the invocation. * @return a guarded invocation with the new type applied to it. */ @@ -312,9 +342,11 @@ } /** - * Changes the type of the invocation, as if {@link LinkerServices#asType(MethodHandle, MethodType)} was applied to - * its invocation and its guard, if it has one (with return type changed to boolean, and parameter count potentially - * truncated for the guard). If the invocation already is of the required type, returns this object. + * Changes the type of the invocation, as if + * {@link LinkerServices#asType(MethodHandle, MethodType)} was applied to + * its invocation and its guard, if it has one (with return type changed to + * boolean, and parameter count potentially truncated for the guard). If the + * invocation already is of the required type, returns this object. * @param linkerServices the linker services to use for the conversion * @param newType the new type of the invocation. * @return a guarded invocation with the new type applied to it. @@ -325,10 +357,13 @@ } /** - * Changes the type of the invocation, as if {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)} was - * applied to its invocation and {@link LinkerServices#asType(MethodHandle, MethodType)} applied to its guard, if it - * has one (with return type changed to boolean, and parameter count potentially truncated for the guard). If the - * invocation doesn't change its type, returns this object. + * Changes the type of the invocation, as if + * {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)} was + * applied to its invocation and + * {@link LinkerServices#asType(MethodHandle, MethodType)} applied to its + * guard, if it has one (with return type changed to boolean, and parameter + * count potentially truncated for the guard). If the invocation doesn't + * change its type, returns this object. * @param linkerServices the linker services to use for the conversion * @param newType the new type of the invocation. * @return a guarded invocation with the new type applied to it. @@ -339,9 +374,11 @@ } /** - * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation - * and its guard, if it has one (with return type changed to boolean for guard). If the invocation already is of the - * required type, returns this object. + * Changes the type of the invocation, as if + * {@link MethodHandle#asType(MethodType)} was applied to its invocation + * and its guard, if it has one (with return type changed to boolean for + * guard). If the invocation already is of the required type, returns this + * object. * @param desc a call descriptor whose method type is adapted. * @return a guarded invocation with the new type applied to it. */ @@ -350,7 +387,8 @@ } /** - * Applies argument filters to both the invocation and the guard (if there is one). + * Applies argument filters to both the invocation and the guard (if there + * is one) with {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}. * @param pos the position of the first argument being filtered * @param filters the argument filters * @return a filtered invocation @@ -361,7 +399,8 @@ } /** - * Makes an invocation that drops arguments in both the invocation and the guard (if there is one). + * Makes an invocation that drops arguments in both the invocation and the + * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, List)}. * @param pos the position of the first argument being dropped * @param valueTypes the types of the values being dropped * @return an invocation that drops arguments @@ -372,7 +411,8 @@ } /** - * Makes an invocation that drops arguments in both the invocation and the guard (if there is one). + * Makes an invocation that drops arguments in both the invocation and the + * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}. * @param pos the position of the first argument being dropped * @param valueTypes the types of the values being dropped * @return an invocation that drops arguments @@ -384,8 +424,11 @@ /** - * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back. - * @param fallback the fallback method handle in case switchpoint is invalidated or guard returns false. + * Composes the invocation, guard, switch points, and the exception into a + * composite method handle that knows how to fall back when the guard fails + * or the invocation is invalidated. + * @param fallback the fallback method handle for when a switch point is + * invalidated, a guard returns false, or invalidating exception is thrown. * @return a composite method handle. */ public MethodHandle compose(final MethodHandle fallback) { @@ -393,10 +436,15 @@ } /** - * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back. - * @param switchpointFallback the fallback method handle in case switchpoint is invalidated. - * @param guardFallback the fallback method handle in case guard returns false. - * @param catchFallback the fallback method in case the exception handler triggers + * Composes the invocation, guard, switch points, and the exception into a + * composite method handle that knows how to fall back when the guard fails + * or the invocation is invalidated. + * @param switchpointFallback the fallback method handle in case a switch + * point is invalidated. + * @param guardFallback the fallback method handle in case guard returns + * false. + * @param catchFallback the fallback method in case the exception handler + * triggers. * @return a composite method handle. */ public MethodHandle compose(final MethodHandle guardFallback, final MethodHandle switchpointFallback, final MethodHandle catchFallback) { @@ -411,7 +459,7 @@ final MethodHandle catchGuarded = exception == null ? guarded : - MH.catchException( + MethodHandles.catchException( guarded, exception, MethodHandles.dropArguments( @@ -430,10 +478,4 @@ return spGuarded; } - - private static void assertType(final MethodHandle mh, final MethodType type) { - if(!mh.type().equals(type)) { - throw new WrongMethodTypeException("Expected type: " + type + " actual type: " + mh.type()); - } - } } diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedTypeConversion.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedTypeConversion.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedTypeConversion.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,17 +83,27 @@ package jdk.internal.dynalink.linker; + /** - * Guarded type conversion + * A tuple of a {@link GuardedInvocation} describing a conditional type + * conversion and a boolean flag indicating whether the result is allowed to + * be cached. While most type conversions are cacheable, some can have security + * implications. An example is converting e.g. function objects from the source + * language into implementations of Java functional interface objects, with + * adapter classes for those interfaces being created on the fly and being + * sensitive to the protection domain of their creator. Such converter + * invocation must be marked as non-cacheable so that Dynalink will know not to + * keep and reuse them in different contexts. */ public class GuardedTypeConversion { private final GuardedInvocation conversionInvocation; private final boolean cacheable; /** - * Constructor - * @param conversionInvocation guarded invocation for this type conversion - * @param cacheable is this invocation cacheable + * Creates a new guarded type conversion. + * @param conversionInvocation guarded invocation implementing this type + * conversion. + * @param cacheable true if this invocation is cacheable, false otherwise. */ public GuardedTypeConversion(final GuardedInvocation conversionInvocation, final boolean cacheable) { this.conversionInvocation = conversionInvocation; @@ -101,16 +111,18 @@ } /** - * Get the invocation - * @return invocation + * Returns the invocation implementing the type conversion. + * @return the invocation implementing the type conversion. */ public GuardedInvocation getConversionInvocation() { return conversionInvocation; } /** - * Check if invocation is cacheable - * @return true if cacheable, false otherwise + * Returns true if this conversion is allowed to be cached and reused by + * Dynalink. + * @return true if this conversion is allowed to be cached and reused by + * Dynalink. */ public boolean isCacheable() { return cacheable; diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingDynamicLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200 @@ -99,14 +99,14 @@ * @return a guarded invocation with a method handle suitable for the arguments, as well as a guard condition that * if fails should trigger relinking. Must return null if it can't resolve the invocation. If the returned * invocation is unconditional (which is actually quite rare), the guard in the return value can be null. The - * invocation can also have a switch point for asynchronous invalidation of the linkage, as well as a + * invocation can also have any number of switch points for asynchronous invalidation of the linkage, as well as a * {@link Throwable} subclass that describes an expected exception condition that also triggers relinking (often it * is faster to rely on an infrequent but expected {@link ClassCastException} than on an always evaluated * {@code instanceof} guard). While the linker must produce an * invocation with parameter types matching those in the call site descriptor of the link request, it should not try * to match the return type expected at the call site except when it can do it with only the conversions that lose * neither precision nor magnitude, see {@link LinkerServices#asTypeLosslessReturn(java.lang.invoke.MethodHandle, - * java.lang.invoke.MethodType)}. + * java.lang.invoke.MethodType)} for further explanation. * @throws Exception if the operation fails for whatever reason */ public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,14 +83,15 @@ package jdk.internal.dynalink.linker; +import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.support.TypeUtilities; /** * Optional interface that can be implemented by {@link GuardingDynamicLinker} implementations to provide * language-runtime specific implicit type conversion capabilities. Note that if you implement this interface, you will * very likely want to implement {@link ConversionComparator} interface too, as your additional language-specific - * conversions, in absence of a strategy for prioritizing these conversions, will cause more ambiguity in selecting the - * correct overload when trying to link to an overloaded POJO method. + * conversions, in absence of a strategy for prioritizing these conversions, will cause more ambiguity for + * {@link BeansLinker} in selecting the correct overload when trying to link to an overloaded Java method. */ public interface GuardingTypeConverterFactory { /** diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkRequest.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkRequest.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkRequest.java Mon Oct 19 08:45:29 2015 +0200 @@ -99,15 +99,19 @@ public CallSiteDescriptor getCallSiteDescriptor(); /** - * Returns the arguments for the invocation being linked. The returned array is a clone; modifications to it won't - * affect the arguments in this request. + * Returns the arguments for the invocation being linked. The returned array + * must be a clone; modifications to it must not affect the arguments in + * this request. * * @return the arguments for the invocation being linked. */ public Object[] getArguments(); /** - * Returns the 0th argument for the invocation being linked; this is typically the receiver object. + * Returns the first argument for the invocation being linked; this is + * typically the receiver object. This is a shorthand for + * {@code getArguments()[0]} that also avoids the cloning of the arguments + * array. * * @return the receiver object. */ @@ -117,8 +121,8 @@ * Returns true if the call site is considered unstable, that is, it has been relinked more times than was * specified in {@link DynamicLinkerFactory#setUnstableRelinkThreshold(int)}. Linkers should use this as a * hint to prefer producing linkage that is more stable (its guard fails less frequently), even if that assumption - * causes a less effective version of an operation to be linked. This is just a hint, of course, and linkers are - * free to ignore this property. + * causes a less effective version of an operation to be linked. This is just a hint, though, and linkers are + * allowed to ignore this property. * @return true if the call site is considered unstable. */ public boolean isCallSiteUnstable(); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java Mon Oct 19 08:45:29 2015 +0200 @@ -185,7 +185,8 @@ /** * Modifies the method handle so that any parameters that can receive potentially internal language runtime objects * will have a filter added on them to prevent them from escaping, potentially by wrapping them. - * It can also potentially add an unwrapping filter to the return value. + * It can also potentially add an unwrapping filter to the return value. Basically transforms the method + * handle using the transformer configured by {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)}. * @param target the target method handle * @return a method handle with parameters and/or return type potentially filtered for wrapping and unwrapping. */ diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodHandleTransformer.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodHandleTransformer.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodHandleTransformer.java Mon Oct 19 08:45:29 2015 +0200 @@ -88,6 +88,7 @@ /** * A generic interface describing operations that transform method handles. */ +@FunctionalInterface public interface MethodHandleTransformer { /** * Transforms a method handle. diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodTypeConversionStrategy.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodTypeConversionStrategy.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodTypeConversionStrategy.java Mon Oct 19 08:45:29 2015 +0200 @@ -87,8 +87,10 @@ import java.lang.invoke.MethodType; /** - * Interface for objects representing a strategy for converting a method handle to a new type. + * Interface for objects representing a strategy for converting a method handle + * to a new type. */ +@FunctionalInterface public interface MethodTypeConversionStrategy { /** * Converts a method handle to a new type. diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,11 +83,14 @@ package jdk.internal.dynalink.linker; +import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker; + /** * A guarding dynamic linker that can determine whether it can link the call site solely based on the type of the first - * argument at linking invocation time. (The first argument is usually the receiver class). Most language-specific + * argument at linking invocation time. (The first argument is usually the receiver). Most language-specific * linkers will fall into this category, as they recognize their native objects as Java objects of classes implementing - * a specific language-native interface or superclass. The linker mechanism can optimize the dispatch for these linkers. + * a specific language-native interface or superclass. The linker mechanism can optimize the dispatch for these linkers, + * see {@link CompositeTypeBasedGuardingDynamicLinker}. */ public interface TypeBasedGuardingDynamicLinker extends GuardingDynamicLinker { /** diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/package-info.java Mon Oct 19 08:45:29 2015 +0200 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + *

+ * Dynalink is a library for dynamic linking high-level operations on objects + * such as "read a property", "write a property", "invoke a function" and so on, + * expressed as {@link java.lang.invoke.CallSite call sites}. As such, it is + * closely related to, and relies on, the {@link java.lang.invoke} package. + *

+ * While {@link java.lang.invoke} provides a JVM-level foundation for + * application-specific dynamic linking of methods, it does not provide a way to + * express higher level operations on objects, nor methods that implement them. + * These operations are the usual regimen of operations in object-oriented + * environments: property access, access of elements of collections, invocation + * of constructors, invocation of named methods (potentially with multiple + * dispatch, e.g. link- and run-time equivalents of Java overloaded method + * resolution). These are all functions that are normally desired in a language + * on the JVM. When a JVM language is statically typed and its type system + * matches that of the JVM, it can accomplish this with use of the usual + * invocation bytecodes ({@code INVOKEVIRTUAL} etc.) as well as field access + * bytecodes ({@code GETFIELD}, {@code PUTFIELD}). However, if the language is + * dynamic (hence, types of some expressions are not known at the time the + * program is compiled to bytecode), or its type system doesn't match closely + * that of the JVM, then it should use {@code invokedynamic} call sites and let + * Dynalink link those. + *

+ * Dynalink lets programs have their operations on objects of unknown static + * types linked dynamically at run time. It also lets a language expose a linker + * for its own object model. Finally, it provides a default linker for ordinary + * Java objects. Two languages both exporting their linkers in the same JVM will + * even be able to cross-link their operations with each other if an object + * belonging to one language is passed to code from the other language. + *

+ *

+ * Languages that use Dynalink will create and configure a + * {@link jdk.internal.dynalink.DynamicLinkerFactory} and use it to create a + * {@link jdk.internal.dynalink.DynamicLinker}. + * The thus created dynamic linker will have to be used to link any + * {@link jdk.internal.dynalink.RelinkableCallSite}s they create, most often from a + * {@link java.lang.invoke} bootstrap method. + *

+ *

+ * Languages that wish to define and use their own linkers will also need to + * use the {@link jdk.internal.dynalink.linker} package. + *

+ * @since 1.9 + */ +@jdk.Exported +package jdk.internal.dynalink; diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/package.html --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/package.html Mon Oct 19 08:39:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ - - - - -

- Contains the main API for using the dynamic linking facilities. A - scripting framework or a language runtime that does not define its own - linker but only uses linkers available in the system will only need to - use classes and interfaces from this package. -

-

- Languages that wish to define and use their own linkers will also need to - use the {@link jdk.internal.dynalink.linker} package. -

- diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java Mon Oct 19 08:45:29 2015 +0200 @@ -89,10 +89,18 @@ import jdk.internal.dynalink.CallSiteDescriptor; /** - * A base class for call site descriptor implementations. Provides reconstruction of the name from the tokens, - * as well as generally useful {@code equals}, {@code hashCode}, and {@code toString} methods. For security - * and performance reasons, subclasses must implement {@link #lookupEquals(AbstractCallSiteDescriptor)}, + * A base class for call site descriptor implementations. Provides + * reconstruction of the name from the tokens, as well as generally useful + * {@code equals}, {@code hashCode}, and {@code toString} methods. In order to + * both prevent unprivileged access to its internal {@link MethodHandles.Lookup} + * object, and at the same time not force privileged access to it from + * {@code equals}, {@code hashCode}, and {@code toString} methods, subclasses + * must implement {@link #lookupEquals(AbstractCallSiteDescriptor)}, * {@link #lookupHashCode()} and {@link #lookupToString()} methods. + * Additionally, {@link #equalsInKind(AbstractCallSiteDescriptor)} should be + * overridden instead of {@link #equals(Object)} to compare descriptors in + * subclasses; it is only necessary if they have implementation-specific + * properties other than the standard name, type, and lookup. * @param The call site descriptor subclass */ public abstract class AbstractCallSiteDescriptor> implements CallSiteDescriptor { @@ -102,6 +110,15 @@ return appendName(new StringBuilder(getNameLength())).toString(); } + /** + * Checks if this call site descriptor is equality to another object. It is + * considered equal iff and only if they belong to the exact same class, and + * have the same name, method type, and lookup. Subclasses with additional + * properties should override + * {@link #equalsInKind(AbstractCallSiteDescriptor)} instead of this method. + * @param obj the object checked for equality + * @return true if they are equal, false otherwise + */ @SuppressWarnings("unchecked") @Override public boolean equals(final Object obj) { @@ -109,8 +126,8 @@ } /** - * Returns true if this call site descriptor is equal to the passed, non-null call site descriptor of the - * same class. + * Returns true if this call site descriptor is equal to the passed, + * non-null call site descriptor of the same class. * @param csd the other call site descriptor. * @return true if they are equal. */ @@ -134,20 +151,32 @@ } /** - * Returns true if this call site descriptor's lookup is equal to the other call site descriptor's lookup. - * Typical implementation should try to obtain the other lookup directly without going through - * {@link #getLookup()} (e.g. directly using the implementation) and then delegate to + * Returns true if this call site descriptor's lookup is equal to the other + * call site descriptor's lookup. Typical implementation should try to + * obtain the other lookup directly without going through privileged + * {@link #getLookup()} (e.g. by reading the field as the type system + * enforces that they are of the same class) and then delegate to * {@link #lookupsEqual(MethodHandles.Lookup, MethodHandles.Lookup)}. * @param other the other lookup * @return true if the lookups are equal */ protected abstract boolean lookupEquals(T other); + /** + * Compares two lookup objects for value-based equality. They are considered + * equal if they have the same + * {@link java.lang.invoke.MethodHandles.Lookup#lookupClass()} and + * {@link java.lang.invoke.MethodHandles.Lookup#lookupModes()}. + * @param l1 first lookup + * @param l2 second lookup + * @return true if the two lookups are equal, false otherwise. + */ protected static boolean lookupsEqual(final Lookup l1, final Lookup l2) { if(l1 == l2) { return true; - } - if(l1.lookupClass() != l2.lookupClass()) { + } else if (l1 == null || l2 == null) { + return false; + } else if(l1.lookupClass() != l2.lookupClass()) { return false; } return l1.lookupModes() == l2.lookupModes(); @@ -164,14 +193,24 @@ } /** - * Return the hash code of this call site descriptor's {@link Lookup} object. Typical - * implementation should delegate to {@link #lookupHashCode(MethodHandles.Lookup)}. - * @return the hash code of this call site descriptor's {@link Lookup} object. + * Return the hash code of this call site descriptor's {@link Lookup} + * object. Typical implementation should delegate to + * {@link #lookupHashCode(MethodHandles.Lookup)}. + * @return the hash code of this call site descriptor's {@link Lookup} + * object. */ protected abstract int lookupHashCode(); + /** + * Returns a value-based hash code for the passed lookup object. It is + * based on the lookup object's + * {@link java.lang.invoke.MethodHandles.Lookup#lookupClass()} and + * {@link java.lang.invoke.MethodHandles.Lookup#lookupModes()} values. + * @param lookup the lookup object. + * @return a hash code for the object. Returns 0 for null. + */ protected static int lookupHashCode(final Lookup lookup) { - return lookup.lookupClass().hashCode() + 31 * lookup.lookupModes(); + return lookup != null ? lookup.lookupClass().hashCode() + 31 * lookup.lookupModes() : 0; } @Override @@ -183,9 +222,11 @@ } /** - * Return a string representation of this call site descriptor's {@link Lookup} object. Typically will - * return {@link Lookup#toString()}. - * @return a string representation of this call site descriptor's {@link Lookup} object. + * Return a string representation of this call site descriptor's + * {@link Lookup} object. Typically will return + * {@link java.lang.invoke.MethodHandles.Lookup#toString()}. + * @return a string representation of this call site descriptor's + * {@link Lookup} object. */ protected abstract String lookupToString(); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java Mon Oct 19 08:45:29 2015 +0200 @@ -83,20 +83,31 @@ package jdk.internal.dynalink.support; +import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandle; import java.lang.invoke.MutableCallSite; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.RelinkableCallSite; +import jdk.internal.dynalink.linker.GuardedInvocation; /** - * A basic implementation of the {@link RelinkableCallSite} as a {@link MutableCallSite} subclass. + * A basic implementation of the {@link RelinkableCallSite} as a + * {@link MutableCallSite}. It carries a {@link CallSiteDescriptor} passed in + * the constructor and provides the correct implementation of the + * {@link #initialize(MethodHandle)} method. Subclasses must provide + * {@link #relink(GuardedInvocation, MethodHandle)} and + * {@link #resetAndRelink(GuardedInvocation, MethodHandle)} + * methods. */ public abstract class AbstractRelinkableCallSite extends MutableCallSite implements RelinkableCallSite { private final CallSiteDescriptor descriptor; /** - * Creates a new relinkable call site. - * @param descriptor the descriptor for this call site + * Creates a new abstract relinkable call site. + * @param descriptor the descriptor for this call site that will be returned + * from {@link #getDescriptor()}. The call site's {@link CallSite#type()} + * will be equal to descriptor's {@link CallSiteDescriptor#getMethodType()}. + * @throws NullPointerException if {@code descriptor} is null. */ protected AbstractRelinkableCallSite(final CallSiteDescriptor descriptor) { super(descriptor.getMethodType()); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200 @@ -86,15 +86,16 @@ import java.io.Serializable; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardingDynamicLinker; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; /** - * A {@link GuardingDynamicLinker} that delegates sequentially to a list of other guarding dynamic linkers. The first - * value returned from a component linker other than null is returned. If no component linker returns an invocation, - * null is returned. + * A {@link GuardingDynamicLinker} that delegates sequentially to a list of + * other guarding dynamic linkers in its + * {@link #getGuardedInvocation(LinkRequest, LinkerServices)}. */ public class CompositeGuardingDynamicLinker implements GuardingDynamicLinker, Serializable { @@ -106,15 +107,27 @@ * Creates a new composite linker. * * @param linkers a list of component linkers. + * @throws NullPointerException if {@code linkers} or any of its elements + * are null. */ public CompositeGuardingDynamicLinker(final Iterable linkers) { final List l = new LinkedList<>(); for(final GuardingDynamicLinker linker: linkers) { - l.add(linker); + l.add(Objects.requireNonNull(linker)); } this.linkers = l.toArray(new GuardingDynamicLinker[l.size()]); } + /** + * Delegates the call to its component linkers. The first non-null value + * returned from a component linker is returned. If no component linker + * returns a non-null invocation, null is returned. + * @param linkRequest the object describing the request for linking a + * particular invocation + * @param linkerServices linker services + * @return the first non-null return value from a component linker, or null + * if none of the components returned a non-null. + */ @Override public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200 @@ -87,6 +87,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardingDynamicLinker; import jdk.internal.dynalink.linker.LinkRequest; @@ -94,10 +95,12 @@ import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; /** - * A composite type-based guarding dynamic linker. When a receiver of a not yet seen class is encountered, all linkers - * are queried sequentially on their {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers - * returning true are then bound to the class, and next time a receiver of same type is encountered, the linking is - * delegated to those linkers only, speeding up dispatch. + * A composite type-based guarding dynamic linker. When a receiver of a not yet + * seen class is encountered, all linkers are queried sequentially on their + * {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers + * returning true are then bound to the class, and next time a receiver of same + * type is encountered, the linking is delegated to those linkers only, speeding + * up dispatch. */ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker, Serializable { private static final long serialVersionUID = 1L; @@ -149,15 +152,24 @@ * Creates a new composite type-based linker. * * @param linkers the component linkers + * @throws NullPointerException if {@code linkers} or any of its elements + * are null. */ public CompositeTypeBasedGuardingDynamicLinker(final Iterable linkers) { final List l = new LinkedList<>(); for(final TypeBasedGuardingDynamicLinker linker: linkers) { - l.add(linker); + l.add(Objects.requireNonNull(linker)); } this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()])); } + /** + * Returns true if any of the composite linkers return true from + * {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} for the type. + * @param type the type to link + * @return true if any of the composite linkers can link calls for the + * receiver type, false otherwise. + */ @Override public boolean canLinkType(final Class type) { return !classToLinker.get(type).isEmpty(); @@ -180,17 +192,21 @@ } /** - * Optimizes a list of type-based linkers. If a group of adjacent linkers in the list all implement - * {@link TypeBasedGuardingDynamicLinker}, they will be replaced with a single instance of + * Optimizes a list of type-based linkers. If a group of adjacent linkers in + * the list all implement {@link TypeBasedGuardingDynamicLinker}, they will + * be replaced with a single instance of * {@link CompositeTypeBasedGuardingDynamicLinker} that contains them. * * @param linkers the list of linkers to optimize * @return the optimized list + * @throws NullPointerException if {@code linkers} or any of its elements + * are null. */ public static List optimize(final Iterable linkers) { final List llinkers = new LinkedList<>(); final List tblinkers = new LinkedList<>(); for(final GuardingDynamicLinker linker: linkers) { + Objects.requireNonNull(linker); if(linker instanceof TypeBasedGuardingDynamicLinker) { tblinkers.add((TypeBasedGuardingDynamicLinker)linker); } else { diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/DefaultInternalObjectFilter.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/DefaultInternalObjectFilter.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/DefaultInternalObjectFilter.java Mon Oct 19 08:45:29 2015 +0200 @@ -90,10 +90,15 @@ import jdk.internal.dynalink.linker.MethodHandleTransformer; /** - * Default implementation for a {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)}. - * Given a method handle of {@code Object(Object)} type for filtering parameter and another one of the same type for - * filtering return values, applies them to passed method handles where their parameter types and/or return value types - * are declared to be {@link Object}. + * Default implementation for a + * {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)} + * that delegates to a pair of filtering method handles. Given a method handle + * of {@code Object(Object)} type for filtering parameter and another one of the + * same type for filtering return values, applies them to passed method handles, + * on those parameter types and/or return value types that are declared to be + * {@link Object}. Also handles {@link MethodHandle#isVarargsCollector() method + * handles that support variable arity calls} with a last {@code Object[]} + * parameter. */ public class DefaultInternalObjectFilter implements MethodHandleTransformer { private static final MethodHandle FILTER_VARARGS = new Lookup(MethodHandles.lookup()).findStatic( @@ -105,9 +110,12 @@ /** * Creates a new filter. - * @param parameterFilter the filter for method parameters. Must be of type {@code Object(Object)}, or null. - * @param returnFilter the filter for return values. Must be of type {@code Object(Object)}, or null. - * @throws IllegalArgumentException if one or both filters are not of the expected type. + * @param parameterFilter the filter for method parameters. Must be of type + * {@code Object(Object)}, or {@code null}. + * @param returnFilter the filter for return values. Must be of type + * {@code Object(Object)}, or {@code null}. + * @throws IllegalArgumentException if one or both filters are not of the + * expected type. */ public DefaultInternalObjectFilter(final MethodHandle parameterFilter, final MethodHandle returnFilter) { this.parameterFilter = checkHandle(parameterFilter, "parameterFilter"); diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/Lookup.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/Lookup.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/Lookup.java Mon Oct 19 08:45:29 2015 +0200 @@ -91,14 +91,17 @@ import java.lang.reflect.Method; /** - * A wrapper around MethodHandles.Lookup that masks checked exceptions in those cases when you're looking up methods - * within your own codebase (therefore it is an error if they are not present). + * A wrapper around {@link java.lang.invoke.MethodHandles.Lookup} that masks + * checked exceptions. It is useful in those cases when you're looking up + * methods within your own codebase (therefore it is an error if they are not + * present). */ public class Lookup { private final MethodHandles.Lookup lookup; /** - * Creates a new instance, bound to an instance of {@link java.lang.invoke.MethodHandles.Lookup}. + * Creates a new instance, bound to an instance of + * {@link java.lang.invoke.MethodHandles.Lookup}. * * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} it delegates to. */ @@ -112,23 +115,27 @@ public static final Lookup PUBLIC = new Lookup(MethodHandles.publicLookup()); /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered - * {@link IllegalAccessException} into an {@link IllegalAccessError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, + * converting any encountered {@link IllegalAccessException} into an + * {@link IllegalAccessError}. * * @param m the method to unreflect * @return the unreflected method handle. + * @throws IllegalAccessError if the method is inaccessible. */ public MethodHandle unreflect(final Method m) { return unreflect(lookup, m); } /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered - * {@link IllegalAccessException} into an {@link IllegalAccessError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, + * converting any encountered {@link IllegalAccessException} into an + * {@link IllegalAccessError}. * * @param lookup the lookup used to unreflect * @param m the method to unreflect * @return the unreflected method handle. + * @throws IllegalAccessError if the method is inaccessible. */ public static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) { try { @@ -141,11 +148,12 @@ } /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, converting any encountered - * {@link IllegalAccessException} into an {@link IllegalAccessError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, + * converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}. * * @param f the field for which a getter is unreflected * @return the unreflected field getter handle. + * @throws IllegalAccessError if the getter is inaccessible. */ public MethodHandle unreflectGetter(final Field f) { try { @@ -158,9 +166,10 @@ } /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, converting any - * encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and {@link NoSuchFieldException} - * into a {@link NoSuchFieldError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, + * converting any encountered {@link IllegalAccessException} into an + * {@link IllegalAccessError} and {@link NoSuchFieldException} into a + * {@link NoSuchFieldError}. * * @param refc the class declaring the field * @param name the name of the field @@ -186,11 +195,14 @@ } /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)}, converting any encountered - * {@link IllegalAccessException} into an {@link IllegalAccessError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)}, + * converting any encountered {@link IllegalAccessException} into an + * {@link IllegalAccessError}. * * @param f the field for which a setter is unreflected * @return the unreflected field setter handle. + * @throws IllegalAccessError if the field is inaccessible. + * @throws NoSuchFieldError if the field does not exist. */ public MethodHandle unreflectSetter(final Field f) { try { @@ -203,23 +215,27 @@ } /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any - * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, + * converting any encountered {@link IllegalAccessException} into an + * {@link IllegalAccessError}. * * @param c the constructor to unreflect * @return the unreflected constructor handle. + * @throws IllegalAccessError if the constructor is inaccessible. */ public MethodHandle unreflectConstructor(final Constructor c) { return unreflectConstructor(lookup, c); } /** - * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any - * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, + * converting any encountered {@link IllegalAccessException} into an + * {@link IllegalAccessError}. * * @param lookup the lookup used to unreflect * @param c the constructor to unreflect * @return the unreflected constructor handle. + * @throws IllegalAccessError if the constructor is inaccessible. */ public static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor c) { try { @@ -232,8 +248,10 @@ } /** - * Performs a findSpecial on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an - * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findSpecial(Class, String, MethodType, Class)} + * on the underlying lookup. Converts any encountered + * {@link IllegalAccessException} into an {@link IllegalAccessError} and + * {@link NoSuchMethodException} into a {@link NoSuchMethodError}. * * @param declaringClass class declaring the method * @param name the name of the method @@ -263,8 +281,10 @@ } /** - * Performs a findStatic on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an - * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findStatic(Class, String, MethodType)} + * on the underlying lookup. Converts any encountered + * {@link IllegalAccessException} into an {@link IllegalAccessError} and + * {@link NoSuchMethodException} into a {@link NoSuchMethodError}. * * @param declaringClass class declaring the method * @param name the name of the method @@ -290,8 +310,10 @@ } /** - * Performs a findVirtual on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an - * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}. + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findVirtual(Class, String, MethodType)} + * on the underlying lookup. Converts any encountered + * {@link IllegalAccessException} into an {@link IllegalAccessError} and + * {@link NoSuchMethodException} into a {@link NoSuchMethodError}. * * @param declaringClass class declaring the method * @param name the name of the method @@ -317,8 +339,9 @@ } /** - * Given a lookup, finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class. - * Useful in classes' code for convenient linking to their own privates. + * Given a lookup, finds using {@link #findSpecial(Class, String, MethodType)} + * a method on that lookup's class. Useful in classes' code for convenient + * linking to their own privates. * @param lookup the lookup for the class * @param name the name of the method * @param rtype the return type of the method @@ -331,9 +354,11 @@ /** - * Finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class. Useful in classes' - * code for convenient linking to their own privates. It's easier to use than {@code findSpecial} in that you can - * just list the parameter types, and don't have to specify lookup class. + * Finds using {@link #findSpecial(Class, String, MethodType)} a method on + * that lookup's class. Useful in classes' code for convenient linking to + * their own privates. It's also more convenient than {@code findSpecial} + * in that you can just list the parameter types, and don't have to specify + * lookup class. * @param name the name of the method * @param rtype the return type of the method * @param ptypes the parameter types of the method @@ -344,9 +369,11 @@ } /** - * Given a lookup, finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class. - * Useful in classes' code for convenient linking to their own privates. It's easier to use than {@code findStatic} - * in that you can just list the parameter types, and don't have to specify lookup class. + * Given a lookup, finds using {@link #findStatic(Class, String, MethodType)} + * a method on that lookup's class. Useful in classes' code for convenient + * linking to their own privates. It's easier to use than {@code findStatic} + * in that you can just list the parameter types, and don't have to specify + * lookup class. * @param lookup the lookup for the class * @param name the name of the method * @param rtype the return type of the method @@ -358,9 +385,11 @@ } /** - * Finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class. Useful in classes' - * code for convenient linking to their own privates. It's easier to use than {@code findStatic} in that you can - * just list the parameter types, and don't have to specify lookup class. + * Finds using {@link #findStatic(Class, String, MethodType)} a method on + * that lookup's class. Useful in classes' code for convenient linking to + * their own privates. It's easier to use than {@code findStatic} + * in that you can just list the parameter types, and don't have to specify + * lookup class. * @param name the name of the method * @param rtype the return type of the method * @param ptypes the parameter types of the method diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/NameCodec.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/NameCodec.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/NameCodec.java Mon Oct 19 08:45:29 2015 +0200 @@ -87,18 +87,23 @@ /** * Implements the name mangling and demangling as specified by John Rose's - * "Symbolic Freedom in the - * VM" article. It is recommended that implementers of languages on the JVM uniformly adopt this for symbolic - * interoperability between languages. Normally, you would mangle the names as you're generating bytecode, and then - * demangle them when you're creating {@link CallSiteDescriptor} objects. Note that you are expected to mangle - * individual tokens, and not the whole name at the call site, i.e. the colon character normally separating the tokens - * is never mangled. I.e. you wouldn't mangle {@code dyn:getProp:color} into {@code dyn\!getProp\!color}, but you would - * mangle {@code dyn:getProp:color$} into {@code dyn:getProp:\=color\%} (only mangling the individual token containing - * the symbol {@code color$}). {@link CallSiteDescriptor#tokenizeName(String)} (and by implication, all call site - * descriptors it creates) will automatically perform demangling on the passed names. If you use this factory, or you - * have your own way of creating call site descriptors, but you still delegate to this method of the default factory - * (it is recommended that you do), then you have demangling handled for you already, and only need to ensure that you - * mangle the names when you're emitting them in the bytecode. + * "Symbolic Freedom in the VM" article. It is recommended + * that implementers of languages on the JVM uniformly adopt this for symbolic + * interoperability between languages. Normally, you would mangle the names as + * you're generating bytecode, and then demangle them when you're creating + * {@link CallSiteDescriptor} objects. Note that you are expected to mangle + * individual tokens, and not the whole name at the call site, i.e. the colon + * character normally separating the tokens is never mangled. I.e. you wouldn't + * mangle {@code dyn:getProp:color} into {@code dyn\!getProp\!color}, but you + * would mangle {@code dyn:getProp:color$} into {@code dyn:getProp:\=color\%} + * (only mangling the individual token containing the symbol {@code color$}). + * {@link CallSiteDescriptor#tokenizeName(String)} already uses + * {@link #decode(String)} to perform demangling on the passed names. If you use + * that method when creating call site descriptors, (it is recommended that you + * do), then you have demangling handled for you already, and only need to + * ensure that you mangle the names using {@link #encode(String)} when you're + * emitting them in the bytecode. */ public class NameCodec { private static final char ESCAPE_CHAR = '\\'; diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/SimpleLinkRequest.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/SimpleLinkRequest.java Mon Oct 19 08:39:06 2015 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/SimpleLinkRequest.java Mon Oct 19 08:45:29 2015 +0200 @@ -98,8 +98,9 @@ /** * Creates a new link request. * - * @param callSiteDescriptor the descriptor for the call site being linked - * @param callSiteUnstable true if the call site being linked is considered unstable + * @param callSiteDescriptor the descriptor for the call site being linked. + * @param callSiteUnstable true if the call site being linked is considered + * unstable. * @param arguments the arguments for the invocation */ public SimpleLinkRequest(final CallSiteDescriptor callSiteDescriptor, final boolean callSiteUnstable, final Object... arguments) { diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/package-info.java Mon Oct 19 08:45:29 2015 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + *

Contains classes that make using Dynalink more convenient by providing + * basic implementations of some classes as well as various utilities. + *

+ * @since 1.9 + */ +@jdk.Exported +package jdk.internal.dynalink.support; diff -r f180be6368d8 -r 0bad500ce4e0 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/package.html --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/package.html Mon Oct 19 08:39:06 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ - - - - -

- Contains supporting classes for other packages. There is no guarantee that - any of these classes or interfaces will not change in a manner that breaks - backwards compatibility; they are not considered to be part of the public - API. -

-