< prev index next >

src/java.base/share/classes/java/lang/invoke/CallSite.java

Print this page




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import static java.lang.invoke.MethodHandleStatics.*;
  29 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
  30 import java.lang.reflect.Field;
  31 import sun.misc.Cleaner;
  32 
  33 /**
  34  * A {@code CallSite} is a holder for a variable {@link MethodHandle},
  35  * which is called its {@code target}.
  36  * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
  37  * all calls to the site's current target.
  38  * A {@code CallSite} may be associated with several {@code invokedynamic}
  39  * instructions, or it may be "free floating", associated with none.
  40  * In any case, it may be invoked through an associated method handle
  41  * called its {@linkplain #dynamicInvoker dynamic invoker}.
  42  * <p>
  43  * {@code CallSite} is an abstract class which does not allow
  44  * direct subclassing by users.  It has three immediate,
  45  * concrete subclasses that may be either instantiated or subclassed.
  46  * <ul>
  47  * <li>If a mutable target is not required, an {@code invokedynamic} instruction
  48  * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
  49  * <li>If a mutable target is required which has volatile variable semantics,
  50  * because updates to the target must be immediately and reliably witnessed by other threads,


 121      * Make a call site object equipped with an initial target method handle.
 122      * @param targetType the desired type of the call site
 123      * @param createTargetHook a hook which will bind the call site to the target method handle
 124      * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
 125      *         or if the target returned by the hook is not of the given {@code targetType}
 126      * @throws NullPointerException if the hook returns a null value
 127      * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
 128      * @throws Throwable anything else thrown by the hook function
 129      */
 130     /*package-private*/
 131     CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
 132         this(targetType);
 133         ConstantCallSite selfCCS = (ConstantCallSite) this;
 134         MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
 135         checkTargetChange(this.target, boundTarget);
 136         this.target = boundTarget;
 137     }
 138 
 139     /**
 140      * {@code CallSite} dependency context.
 141      * VM uses context class to store nmethod dependencies on the call site target.
 142      * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance.
 143      * Lazily initialized when CallSite instance is linked to some indy call site or VM needs
 144      * it to store dependencies. As a corollary, "null" context means there are no dependencies
 145      * registered yet. {@code Cleaner} is used in 2 roles:
 146      *   (a) context class access for VM;
 147      *   (b) stale context class cleanup.
 148      * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}).
 149      * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly
 150      * from {@code Reference.referent} field.
 151      */
 152     private volatile Cleaner context = null;
 153 
 154     /**
 155      * Default context.
 156      * VM uses it to initialize non-linked CallSite context.
 157      */
 158     private static class DefaultContext {}
 159     private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null);
 160 
 161     private static Cleaner makeContext(Class<?> referent, final CallSite holder) {
 162         return Cleaner.create(referent,
 163                 new Runnable() {
 164                     @Override public void run() {
 165                         MethodHandleNatives.invalidateDependentNMethods(holder);
 166                     }
 167                 });









 168     }
 169 
 170     /** Initialize context class used for nmethod dependency tracking */
 171     /*package-private*/
 172     void initContext(Class<?> newContext) {
 173         // If there are concurrent actions, exactly one succeeds.
 174         if (context == null) {
 175             UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this));
 176             // No need to care about failed CAS attempt.
 177             // Since initContext is called from indy call site linkage in newContext class, there's no risk
 178             // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup
 179             // action in the wrong context).
 180         }
 181     }
 182 
 183     /**
 184      * Returns the type of this call site's target.
 185      * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
 186      * The {@code setTarget} method enforces this invariant by refusing any new target that does
 187      * not have the previous target's type.
 188      * @return the type of the current target, which is also the type of any future target
 189      */
 190     public MethodType type() {
 191         // warning:  do not call getTarget here, because CCS.getTarget can throw IllegalStateException
 192         return target.type();
 193     }
 194 
 195     /**
 196      * Returns the target method of the call site, according to the
 197      * behavior defined by this call site's specific class.
 198      * The immediate subclasses of {@code CallSite} document the
 199      * class-specific behaviors of this method.




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import static java.lang.invoke.MethodHandleStatics.*;
  29 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;

  30 import sun.misc.Cleaner;
  31 
  32 /**
  33  * A {@code CallSite} is a holder for a variable {@link MethodHandle},
  34  * which is called its {@code target}.
  35  * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
  36  * all calls to the site's current target.
  37  * A {@code CallSite} may be associated with several {@code invokedynamic}
  38  * instructions, or it may be "free floating", associated with none.
  39  * In any case, it may be invoked through an associated method handle
  40  * called its {@linkplain #dynamicInvoker dynamic invoker}.
  41  * <p>
  42  * {@code CallSite} is an abstract class which does not allow
  43  * direct subclassing by users.  It has three immediate,
  44  * concrete subclasses that may be either instantiated or subclassed.
  45  * <ul>
  46  * <li>If a mutable target is not required, an {@code invokedynamic} instruction
  47  * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
  48  * <li>If a mutable target is required which has volatile variable semantics,
  49  * because updates to the target must be immediately and reliably witnessed by other threads,


 120      * Make a call site object equipped with an initial target method handle.
 121      * @param targetType the desired type of the call site
 122      * @param createTargetHook a hook which will bind the call site to the target method handle
 123      * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
 124      *         or if the target returned by the hook is not of the given {@code targetType}
 125      * @throws NullPointerException if the hook returns a null value
 126      * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
 127      * @throws Throwable anything else thrown by the hook function
 128      */
 129     /*package-private*/
 130     CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
 131         this(targetType);
 132         ConstantCallSite selfCCS = (ConstantCallSite) this;
 133         MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
 134         checkTargetChange(this.target, boundTarget);
 135         this.target = boundTarget;
 136     }
 137 
 138     /**
 139      * {@code CallSite} dependency context.
 140      * JVM uses CallSite.context to store nmethod dependencies on the call site target.









 141      */
 142     private final Context context = Context.make(this);
 143 
 144     static class Context implements Runnable {
 145         static {
 146             sun.reflect.Reflection.registerFieldsToFilter(Context.class, "dependencies");









 147         }
 148 
 149         private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket*
 150 
 151         static Context make(CallSite cs) {
 152             final Context newContext = new Context();
 153             // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context.
 154             // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is
 155             // referenced from Cleaner class) until cleanup is performed.
 156             Cleaner.create(cs, newContext);
 157             return newContext;
 158         }
 159 
 160         @Override
 161         public void run() {
 162             MethodHandleNatives.clearCallSiteContext(this);







 163         }
 164     }
 165 
 166     /**
 167      * Returns the type of this call site's target.
 168      * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
 169      * The {@code setTarget} method enforces this invariant by refusing any new target that does
 170      * not have the previous target's type.
 171      * @return the type of the current target, which is also the type of any future target
 172      */
 173     public MethodType type() {
 174         // warning:  do not call getTarget here, because CCS.getTarget can throw IllegalStateException
 175         return target.type();
 176     }
 177 
 178     /**
 179      * Returns the target method of the call site, according to the
 180      * behavior defined by this call site's specific class.
 181      * The immediate subclasses of {@code CallSite} document the
 182      * class-specific behaviors of this method.


< prev index next >