nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java
changeset 33333 0bad500ce4e0
parent 33007 03119bfefbbf
child 33335 a46c85103868
--- 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<? extends Throwable> 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<? extends Throwable> 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<? extends Throwable> 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());
-        }
-    }
 }