src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/java.base/share/classes/java/lang/invoke

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

Print this page
rev 11258 : 8069591: Customize LambdaForms which are invoked using MH.invoke/invokeExact
Reviewed-by: ?


 417  * @see MethodType
 418  * @see MethodHandles
 419  * @author John Rose, JSR 292 EG
 420  */
 421 public abstract class MethodHandle {
 422     static { MethodHandleImpl.initStatics(); }
 423 
 424     /**
 425      * Internal marker interface which distinguishes (to the Java compiler)
 426      * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
 427      */
 428     @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
 429     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
 430     @interface PolymorphicSignature { }
 431 
 432     private final MethodType type;
 433     /*private*/ final LambdaForm form;
 434     // form is not private so that invokers can easily fetch it
 435     /*private*/ MethodHandle asTypeCache;
 436     // asTypeCache is not private so that invokers can easily fetch it


 437 
 438     /**
 439      * Reports the type of this method handle.
 440      * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
 441      * @return the method handle type
 442      */
 443     public MethodType type() {
 444         return type;
 445     }
 446 
 447     /**
 448      * Package-private constructor for the method handle implementation hierarchy.
 449      * Method handle inheritance will be contained completely within
 450      * the {@code java.lang.invoke} package.
 451      */
 452     // @param type type (permanently assigned) of the new method handle
 453     /*non-public*/ MethodHandle(MethodType type, LambdaForm form) {
 454         type.getClass();  // explicit NPE
 455         form.getClass();  // explicit NPE
 456         this.type = type;
 457         this.form = form;
 458 
 459         form.prepare();  // TO DO:  Try to delay this step until just before invocation.
 460     }
 461 
 462     /**
 463      * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
 464      * The symbolic type descriptor at the call site of {@code invokeExact} must
 465      * exactly match this method handle's {@link #type type}.
 466      * No conversions are allowed on arguments or return values.
 467      * <p>
 468      * When this method is observed via the Core Reflection API,
 469      * it will appear as a single native method, taking an object array and returning an object.
 470      * If this native method is invoked directly via
 471      * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
 472      * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
 473      * it will throw an {@code UnsupportedOperationException}.
 474      * @param args the signature-polymorphic parameter list, statically represented using varargs
 475      * @return the signature-polymorphic result, statically represented using {@code Object}
 476      * @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
 477      * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
 478      */
 479     public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;


1408     //// All these methods assume arguments are already validated.
1409 
1410     /*non-public*/
1411     abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
1412 
1413     /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
1414      *  Many transforms are implemented only for BMHs.
1415      *  @return a behaviorally equivalent BMH
1416      */
1417     abstract BoundMethodHandle rebind();
1418 
1419     /**
1420      * Replace the old lambda form of this method handle with a new one.
1421      * The new one must be functionally equivalent to the old one.
1422      * Threads may continue running the old form indefinitely,
1423      * but it is likely that the new one will be preferred for new executions.
1424      * Use with discretion.
1425      */
1426     /*non-public*/
1427     void updateForm(LambdaForm newForm) {

1428         if (form == newForm)  return;
1429         newForm.prepare();  // as in MethodHandle.<init>
1430         UNSAFE.putObject(this, FORM_OFFSET, newForm);
1431         UNSAFE.fullFence();
1432     }
1433 











1434     private static final long FORM_OFFSET;
1435     static {
1436         try {
1437             FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
1438         } catch (ReflectiveOperationException ex) {
1439             throw newInternalError(ex);
1440         }
1441     }
1442 }


 417  * @see MethodType
 418  * @see MethodHandles
 419  * @author John Rose, JSR 292 EG
 420  */
 421 public abstract class MethodHandle {
 422     static { MethodHandleImpl.initStatics(); }
 423 
 424     /**
 425      * Internal marker interface which distinguishes (to the Java compiler)
 426      * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
 427      */
 428     @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
 429     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
 430     @interface PolymorphicSignature { }
 431 
 432     private final MethodType type;
 433     /*private*/ final LambdaForm form;
 434     // form is not private so that invokers can easily fetch it
 435     /*private*/ MethodHandle asTypeCache;
 436     // asTypeCache is not private so that invokers can easily fetch it
 437     /*non-public*/ byte customizationCount;
 438     // customizationCount should be accessible from invokers
 439 
 440     /**
 441      * Reports the type of this method handle.
 442      * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
 443      * @return the method handle type
 444      */
 445     public MethodType type() {
 446         return type;
 447     }
 448 
 449     /**
 450      * Package-private constructor for the method handle implementation hierarchy.
 451      * Method handle inheritance will be contained completely within
 452      * the {@code java.lang.invoke} package.
 453      */
 454     // @param type type (permanently assigned) of the new method handle
 455     /*non-public*/ MethodHandle(MethodType type, LambdaForm form) {
 456         type.getClass();  // explicit NPE
 457         form.getClass();  // explicit NPE
 458         this.type = type;
 459         this.form = form.uncustomize();
 460 
 461         this.form.prepare();  // TO DO:  Try to delay this step until just before invocation.
 462     }
 463 
 464     /**
 465      * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
 466      * The symbolic type descriptor at the call site of {@code invokeExact} must
 467      * exactly match this method handle's {@link #type type}.
 468      * No conversions are allowed on arguments or return values.
 469      * <p>
 470      * When this method is observed via the Core Reflection API,
 471      * it will appear as a single native method, taking an object array and returning an object.
 472      * If this native method is invoked directly via
 473      * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
 474      * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
 475      * it will throw an {@code UnsupportedOperationException}.
 476      * @param args the signature-polymorphic parameter list, statically represented using varargs
 477      * @return the signature-polymorphic result, statically represented using {@code Object}
 478      * @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
 479      * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
 480      */
 481     public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;


1410     //// All these methods assume arguments are already validated.
1411 
1412     /*non-public*/
1413     abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
1414 
1415     /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
1416      *  Many transforms are implemented only for BMHs.
1417      *  @return a behaviorally equivalent BMH
1418      */
1419     abstract BoundMethodHandle rebind();
1420 
1421     /**
1422      * Replace the old lambda form of this method handle with a new one.
1423      * The new one must be functionally equivalent to the old one.
1424      * Threads may continue running the old form indefinitely,
1425      * but it is likely that the new one will be preferred for new executions.
1426      * Use with discretion.
1427      */
1428     /*non-public*/
1429     void updateForm(LambdaForm newForm) {
1430         assert(newForm.customized == null || newForm.customized == this);
1431         if (form == newForm)  return;
1432         newForm.prepare();  // as in MethodHandle.<init>
1433         UNSAFE.putObject(this, FORM_OFFSET, newForm);
1434         UNSAFE.fullFence();
1435     }
1436 
1437     /** Craft a LambdaForm customized for this particular MethodHandle */
1438     /*non-public*/
1439     void customize() {
1440         if (form.customized == null) {
1441             LambdaForm newForm = form.customize(this);
1442             updateForm(newForm);
1443         } else {
1444             assert(form.customized == this);
1445         }
1446     }
1447 
1448     private static final long FORM_OFFSET;
1449     static {
1450         try {
1451             FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
1452         } catch (ReflectiveOperationException ex) {
1453             throw newInternalError(ex);
1454         }
1455     }
1456 }
src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File