jdk/src/share/classes/java/lang/invoke/CallSite.java
changeset 13423 17843fff200d
parent 11006 734080358bec
child 14089 0a41b980d62a
equal deleted inserted replaced
13422:72b63ee33f57 13423:17843fff200d
    24  */
    24  */
    25 
    25 
    26 package java.lang.invoke;
    26 package java.lang.invoke;
    27 
    27 
    28 import sun.invoke.empty.Empty;
    28 import sun.invoke.empty.Empty;
    29 import sun.misc.Unsafe;
    29 import static java.lang.invoke.MethodHandleStatics.*;
    30 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
    30 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
    31 
    31 
    32 /**
    32 /**
    33  * A {@code CallSite} is a holder for a variable {@link MethodHandle},
    33  * A {@code CallSite} is a holder for a variable {@link MethodHandle},
    34  * which is called its {@code target}.
    34  * which is called its {@code target}.
    84  */
    84  */
    85 abstract
    85 abstract
    86 public class CallSite {
    86 public class CallSite {
    87     static { MethodHandleImpl.initStatics(); }
    87     static { MethodHandleImpl.initStatics(); }
    88 
    88 
    89     // Fields used only by the JVM.  Do not use or change.
       
    90     private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
       
    91     private int        vmindex;  // supplied by the JVM (BCI within calling method)
       
    92 
       
    93     // The actual payload of this call site:
    89     // The actual payload of this call site:
    94     /*package-private*/
    90     /*package-private*/
    95     MethodHandle target;
    91     MethodHandle target;    // Note: This field is known to the JVM.  Do not change.
    96 
    92 
    97     /**
    93     /**
    98      * Make a blank call site object with the given method type.
    94      * Make a blank call site object with the given method type.
    99      * An initial target method is supplied which will throw
    95      * An initial target method is supplied which will throw
   100      * an {@link IllegalStateException} if called.
    96      * an {@link IllegalStateException} if called.
   147      * @return the type of the current target, which is also the type of any future target
   143      * @return the type of the current target, which is also the type of any future target
   148      */
   144      */
   149     public MethodType type() {
   145     public MethodType type() {
   150         // warning:  do not call getTarget here, because CCS.getTarget can throw IllegalStateException
   146         // warning:  do not call getTarget here, because CCS.getTarget can throw IllegalStateException
   151         return target.type();
   147         return target.type();
   152     }
       
   153 
       
   154     /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
       
   155      *  The parameters are JVM-specific.
       
   156      */
       
   157     void initializeFromJVM(String name,
       
   158                            MethodType type,
       
   159                            MemberName callerMethod,
       
   160                            int        callerBCI) {
       
   161         if (this.vmmethod != null) {
       
   162             // FIXME
       
   163             throw new BootstrapMethodError("call site has already been linked to an invokedynamic instruction");
       
   164         }
       
   165         if (!this.type().equals(type)) {
       
   166             throw wrongTargetType(target, type);
       
   167         }
       
   168         this.vmindex  = callerBCI;
       
   169         this.vmmethod = callerMethod;
       
   170     }
   148     }
   171 
   149 
   172     /**
   150     /**
   173      * Returns the target method of the call site, according to the
   151      * Returns the target method of the call site, according to the
   174      * behavior defined by this call site's specific class.
   152      * behavior defined by this call site's specific class.
   231      * @return a method handle which always invokes this call site's current target
   209      * @return a method handle which always invokes this call site's current target
   232      */
   210      */
   233     public abstract MethodHandle dynamicInvoker();
   211     public abstract MethodHandle dynamicInvoker();
   234 
   212 
   235     /*non-public*/ MethodHandle makeDynamicInvoker() {
   213     /*non-public*/ MethodHandle makeDynamicInvoker() {
   236         MethodHandle getTarget = MethodHandleImpl.bindReceiver(GET_TARGET, this);
   214         MethodHandle getTarget = GET_TARGET.bindReceiver(this);
   237         MethodHandle invoker = MethodHandles.exactInvoker(this.type());
   215         MethodHandle invoker = MethodHandles.exactInvoker(this.type());
   238         return MethodHandles.foldArguments(invoker, getTarget);
   216         return MethodHandles.foldArguments(invoker, getTarget);
   239     }
   217     }
   240 
   218 
   241     private static final MethodHandle GET_TARGET;
   219     private static final MethodHandle GET_TARGET;
   253     static Empty uninitializedCallSite() {
   231     static Empty uninitializedCallSite() {
   254         throw new IllegalStateException("uninitialized call site");
   232         throw new IllegalStateException("uninitialized call site");
   255     }
   233     }
   256 
   234 
   257     // unsafe stuff:
   235     // unsafe stuff:
   258     private static final Unsafe unsafe = Unsafe.getUnsafe();
       
   259     private static final long TARGET_OFFSET;
   236     private static final long TARGET_OFFSET;
   260 
       
   261     static {
   237     static {
   262         try {
   238         try {
   263             TARGET_OFFSET = unsafe.objectFieldOffset(CallSite.class.getDeclaredField("target"));
   239             TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
   264         } catch (Exception ex) { throw new Error(ex); }
   240         } catch (Exception ex) { throw new Error(ex); }
   265     }
   241     }
   266 
   242 
   267     /*package-private*/
   243     /*package-private*/
   268     void setTargetNormal(MethodHandle newTarget) {
   244     void setTargetNormal(MethodHandle newTarget) {
   269         MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
   245         MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
   270     }
   246     }
   271     /*package-private*/
   247     /*package-private*/
   272     MethodHandle getTargetVolatile() {
   248     MethodHandle getTargetVolatile() {
   273         return (MethodHandle) unsafe.getObjectVolatile(this, TARGET_OFFSET);
   249         return (MethodHandle) UNSAFE.getObjectVolatile(this, TARGET_OFFSET);
   274     }
   250     }
   275     /*package-private*/
   251     /*package-private*/
   276     void setTargetVolatile(MethodHandle newTarget) {
   252     void setTargetVolatile(MethodHandle newTarget) {
   277         MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
   253         MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
   278     }
   254     }
   282                              // Callee information:
   258                              // Callee information:
   283                              String name, MethodType type,
   259                              String name, MethodType type,
   284                              // Extra arguments for BSM, if any:
   260                              // Extra arguments for BSM, if any:
   285                              Object info,
   261                              Object info,
   286                              // Caller information:
   262                              // Caller information:
   287                              MemberName callerMethod, int callerBCI) {
   263                              Class<?> callerClass) {
   288         Class<?> callerClass = callerMethod.getDeclaringClass();
       
   289         Object caller = IMPL_LOOKUP.in(callerClass);
   264         Object caller = IMPL_LOOKUP.in(callerClass);
   290         CallSite site;
   265         CallSite site;
   291         try {
   266         try {
   292             Object binding;
   267             Object binding;
   293             info = maybeReBox(info);
   268             info = maybeReBox(info);