< prev index next >

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

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP


 180      * the type of the old target.
 181      *
 182      * @param newTarget the new target
 183      * @throws NullPointerException if the proposed new target is null
 184      * @throws WrongMethodTypeException if the proposed new target
 185      *         has a method type that differs from the previous target
 186      * @see CallSite#getTarget
 187      * @see ConstantCallSite#setTarget
 188      * @see MutableCallSite#setTarget
 189      * @see VolatileCallSite#setTarget
 190      */
 191     public abstract void setTarget(MethodHandle newTarget);
 192 
 193     void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
 194         MethodType oldType = oldTarget.type();
 195         MethodType newType = newTarget.type();  // null check!
 196         if (!newType.equals(oldType))
 197             throw wrongTargetType(newTarget, oldType);
 198     }
 199 
 200     private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
 201         return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
 202     }
 203 
 204     /**
 205      * Produces a method handle equivalent to an invokedynamic instruction
 206      * which has been linked to this call site.
 207      * <p>
 208      * This method is equivalent to the following code:
 209      * <blockquote><pre>{@code
 210      * MethodHandle getTarget, invoker, result;
 211      * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
 212      * invoker = MethodHandles.exactInvoker(this.type());
 213      * result = MethodHandles.foldArguments(invoker, getTarget)
 214      * }</pre></blockquote>
 215      *
 216      * @return a method handle which always invokes this call site's current target
 217      */
 218     public abstract MethodHandle dynamicInvoker();
 219 
 220     /*non-public*/ MethodHandle makeDynamicInvoker() {


 276         if (offset > 0) {
 277             return offset;
 278         }
 279         offset = TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class, "target");
 280         assert(offset > 0);
 281         return offset;
 282     }
 283 
 284     /*package-private*/
 285     void setTargetNormal(MethodHandle newTarget) {
 286         MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
 287     }
 288     /*package-private*/
 289     MethodHandle getTargetVolatile() {
 290         return (MethodHandle) UNSAFE.getObjectVolatile(this, getTargetOffset());
 291     }
 292     /*package-private*/
 293     void setTargetVolatile(MethodHandle newTarget) {
 294         MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
 295     }
 296 
 297     // this implements the upcall from the JVM, MethodHandleNatives.linkCallSite:
 298     static CallSite makeSite(MethodHandle bootstrapMethod,
 299                              // Callee information:
 300                              String name, MethodType type,
 301                              // Extra arguments for BSM, if any:
 302                              Object info,
 303                              // Caller information:
 304                              Class<?> callerClass) {
 305         CallSite site;
 306         try {
 307             Object binding = BootstrapMethodInvoker.invoke(
 308                     CallSite.class, bootstrapMethod, name, type, info, callerClass);
 309             if (binding instanceof CallSite) {
 310                 site = (CallSite) binding;
 311             } else {
 312                 // See the "Linking Exceptions" section for the invokedynamic
 313                 // instruction in JVMS 6.5.
 314                 // Throws a runtime exception defining the cause that is then
 315                 // in the "catch (Throwable ex)" a few lines below wrapped in
 316                 // BootstrapMethodError
 317                 throw new ClassCastException("CallSite bootstrap method failed to produce an instance of CallSite");
 318             }
 319             if (!site.getTarget().type().equals(type)) {
 320                 // See the "Linking Exceptions" section for the invokedynamic
 321                 // instruction in JVMS 6.5.
 322                 // Throws a runtime exception defining the cause that is then
 323                 // in the "catch (Throwable ex)" a few lines below wrapped in
 324                 // BootstrapMethodError
 325                 throw wrongTargetType(site.getTarget(), type);
 326             }
 327         } catch (Error e) {
 328             // Pass through an Error, including BootstrapMethodError, any other
 329             // form of linkage error, such as IllegalAccessError if the bootstrap
 330             // method is inaccessible, or say ThreadDeath/OutOfMemoryError
 331             // See the "Linking Exceptions" section for the invokedynamic
 332             // instruction in JVMS 6.5.
 333             throw e;
 334         } catch (Throwable ex) {
 335             // Wrap anything else in BootstrapMethodError
 336             throw new BootstrapMethodError("CallSite bootstrap method initialization exception", ex);
 337         }
 338         return site;
 339     }
 340 }


 180      * the type of the old target.
 181      *
 182      * @param newTarget the new target
 183      * @throws NullPointerException if the proposed new target is null
 184      * @throws WrongMethodTypeException if the proposed new target
 185      *         has a method type that differs from the previous target
 186      * @see CallSite#getTarget
 187      * @see ConstantCallSite#setTarget
 188      * @see MutableCallSite#setTarget
 189      * @see VolatileCallSite#setTarget
 190      */
 191     public abstract void setTarget(MethodHandle newTarget);
 192 
 193     void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
 194         MethodType oldType = oldTarget.type();
 195         MethodType newType = newTarget.type();  // null check!
 196         if (!newType.equals(oldType))
 197             throw wrongTargetType(newTarget, oldType);
 198     }
 199 
 200     static WrongMethodTypeException wrongTargetType(Object target, MethodType type) {
 201         return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
 202     }
 203 
 204     /**
 205      * Produces a method handle equivalent to an invokedynamic instruction
 206      * which has been linked to this call site.
 207      * <p>
 208      * This method is equivalent to the following code:
 209      * <blockquote><pre>{@code
 210      * MethodHandle getTarget, invoker, result;
 211      * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
 212      * invoker = MethodHandles.exactInvoker(this.type());
 213      * result = MethodHandles.foldArguments(invoker, getTarget)
 214      * }</pre></blockquote>
 215      *
 216      * @return a method handle which always invokes this call site's current target
 217      */
 218     public abstract MethodHandle dynamicInvoker();
 219 
 220     /*non-public*/ MethodHandle makeDynamicInvoker() {


 276         if (offset > 0) {
 277             return offset;
 278         }
 279         offset = TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class, "target");
 280         assert(offset > 0);
 281         return offset;
 282     }
 283 
 284     /*package-private*/
 285     void setTargetNormal(MethodHandle newTarget) {
 286         MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
 287     }
 288     /*package-private*/
 289     MethodHandle getTargetVolatile() {
 290         return (MethodHandle) UNSAFE.getObjectVolatile(this, getTargetOffset());
 291     }
 292     /*package-private*/
 293     void setTargetVolatile(MethodHandle newTarget) {
 294         MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
 295     }












































 296 }
< prev index next >