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

src/share/classes/java/lang/invoke/Invokers.java

Print this page
rev 10274 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?


 291         final int CALL_MH      = THIS_MH + (isLinker ? 0 : 1);
 292         final int ARG_BASE     = CALL_MH + 1;
 293         final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
 294         final int INARG_LIMIT  = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
 295         int nameCursor = OUTARG_LIMIT;
 296         final int MTYPE_ARG    = customized ? -1 : nameCursor++;  // might be last in-argument
 297         final int CHECK_TYPE   = nameCursor++;
 298         final int LINKER_CALL  = nameCursor++;
 299         MethodType invokerFormType = mtype.invokerType();
 300         if (isLinker) {
 301             if (!customized)
 302                 invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
 303         } else {
 304             invokerFormType = invokerFormType.invokerType();
 305         }
 306         Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
 307         assert(names.length == nameCursor)
 308                 : Arrays.asList(mtype, customized, which, nameCursor, names.length);
 309         if (MTYPE_ARG >= INARG_LIMIT) {
 310             assert(names[MTYPE_ARG] == null);
 311             NamedFunction getter = BoundMethodHandle.getSpeciesData("L").getterFunction(0);
 312             names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
 313             // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
 314         }
 315 
 316         // Make the final call.  If isGeneric, then prepend the result of type checking.
 317         MethodType outCallType = mtype.basicType();
 318         Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
 319         Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
 320         if (!isGeneric) {
 321             names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
 322             // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
 323         } else {
 324             names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
 325             // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
 326             outArgs[0] = names[CHECK_TYPE];
 327         }
 328         names[LINKER_CALL] = new Name(outCallType, outArgs);
 329         lform = new LambdaForm(debugName, INARG_LIMIT, names);
 330         if (isLinker)
 331             lform.compileToBytecode();  // JVM needs a real methodOop


 343     /** Static definition of MethodHandle.invokeExact checking code. */
 344     /*non-public*/ static
 345     @ForceInline
 346     void checkExactType(Object mhObj, Object expectedObj) {
 347         MethodHandle mh = (MethodHandle) mhObj;
 348         MethodType expected = (MethodType) expectedObj;
 349         MethodType actual = mh.type();
 350         if (actual != expected)
 351             throw newWrongMethodTypeException(expected, actual);
 352     }
 353 
 354     /** Static definition of MethodHandle.invokeGeneric checking code.
 355      * Directly returns the type-adjusted MH to invoke, as follows:
 356      * {@code (R)MH.invoke(a*) => MH.asType(TYPEOF(a*:R)).invokeBasic(a*)}
 357      */
 358     /*non-public*/ static
 359     @ForceInline
 360     Object checkGenericType(Object mhObj, Object expectedObj) {
 361         MethodHandle mh = (MethodHandle) mhObj;
 362         MethodType expected = (MethodType) expectedObj;
 363         if (mh.type() == expected)  return mh;
 364         MethodHandle atc = mh.asTypeCache;
 365         if (atc != null && atc.type() == expected)  return atc;
 366         return mh.asType(expected);
 367         /* Maybe add more paths here.  Possible optimizations:
 368          * for (R)MH.invoke(a*),
 369          * let MT0 = TYPEOF(a*:R), MT1 = MH.type
 370          *
 371          * if MT0==MT1 or MT1 can be safely called by MT0
 372          *  => MH.invokeBasic(a*)
 373          * if MT1 can be safely called by MT0[R := Object]
 374          *  => MH.invokeBasic(a*) & checkcast(R)
 375          * if MT1 can be safely called by MT0[* := Object]
 376          *  => checkcast(A)* & MH.invokeBasic(a*) & checkcast(R)
 377          * if a big adapter BA can be pulled out of (MT0,MT1)
 378          *  => BA.invokeBasic(MT0,MH,a*)
 379          * if a local adapter LA can cached on static CS0 = new GICS(MT0)
 380          *  => CS0.LA.invokeBasic(MH,a*)
 381          * else
 382          *  => MH.asType(MT0).invokeBasic(A*)
 383          */
 384     }
 385 


 419         final int PREPEND_MH = 0, PREPEND_COUNT = 1;
 420         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
 421         // prepend MH argument:
 422         System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
 423         outArgs[PREPEND_MH] = names[CALL_MH];
 424         names[LINKER_CALL] = new Name(mtype, outArgs);
 425         lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names);
 426         lform.compileToBytecode();  // JVM needs a real methodOop
 427         lform = mtype.form().setCachedLambdaForm(which, lform);
 428         return lform;
 429     }
 430 
 431     /** Static definition of MethodHandle.invokeGeneric checking code. */
 432     /*non-public*/ static
 433     @ForceInline
 434     Object getCallSiteTarget(Object site) {
 435         return ((CallSite)site).getTarget();
 436     }
 437 
 438     // Local constant functions:
 439     private static final NamedFunction NF_checkExactType;
 440     private static final NamedFunction NF_checkGenericType;
 441     private static final NamedFunction NF_asType;
 442     private static final NamedFunction NF_getCallSiteTarget;
 443     static {
 444         try {

 445             NF_checkExactType = new NamedFunction(Invokers.class
 446                     .getDeclaredMethod("checkExactType", Object.class, Object.class));
 447             NF_checkGenericType = new NamedFunction(Invokers.class
 448                     .getDeclaredMethod("checkGenericType", Object.class, Object.class));
 449             NF_asType = new NamedFunction(MethodHandle.class
 450                     .getDeclaredMethod("asType", MethodType.class));
 451             NF_getCallSiteTarget = new NamedFunction(Invokers.class
 452                     .getDeclaredMethod("getCallSiteTarget", Object.class));
 453             NF_checkExactType.resolve();
 454             NF_checkGenericType.resolve();
 455             NF_getCallSiteTarget.resolve();
 456             // bound


 457         } catch (ReflectiveOperationException ex) {
 458             throw newInternalError(ex);
 459         }
 460     }
 461 
 462 }


 291         final int CALL_MH      = THIS_MH + (isLinker ? 0 : 1);
 292         final int ARG_BASE     = CALL_MH + 1;
 293         final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
 294         final int INARG_LIMIT  = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
 295         int nameCursor = OUTARG_LIMIT;
 296         final int MTYPE_ARG    = customized ? -1 : nameCursor++;  // might be last in-argument
 297         final int CHECK_TYPE   = nameCursor++;
 298         final int LINKER_CALL  = nameCursor++;
 299         MethodType invokerFormType = mtype.invokerType();
 300         if (isLinker) {
 301             if (!customized)
 302                 invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
 303         } else {
 304             invokerFormType = invokerFormType.invokerType();
 305         }
 306         Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
 307         assert(names.length == nameCursor)
 308                 : Arrays.asList(mtype, customized, which, nameCursor, names.length);
 309         if (MTYPE_ARG >= INARG_LIMIT) {
 310             assert(names[MTYPE_ARG] == null);
 311             NamedFunction getter = BoundMethodHandle.speciesData_L().getterFunction(0);
 312             names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
 313             // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
 314         }
 315 
 316         // Make the final call.  If isGeneric, then prepend the result of type checking.
 317         MethodType outCallType = mtype.basicType();
 318         Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
 319         Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
 320         if (!isGeneric) {
 321             names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
 322             // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
 323         } else {
 324             names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
 325             // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
 326             outArgs[0] = names[CHECK_TYPE];
 327         }
 328         names[LINKER_CALL] = new Name(outCallType, outArgs);
 329         lform = new LambdaForm(debugName, INARG_LIMIT, names);
 330         if (isLinker)
 331             lform.compileToBytecode();  // JVM needs a real methodOop


 343     /** Static definition of MethodHandle.invokeExact checking code. */
 344     /*non-public*/ static
 345     @ForceInline
 346     void checkExactType(Object mhObj, Object expectedObj) {
 347         MethodHandle mh = (MethodHandle) mhObj;
 348         MethodType expected = (MethodType) expectedObj;
 349         MethodType actual = mh.type();
 350         if (actual != expected)
 351             throw newWrongMethodTypeException(expected, actual);
 352     }
 353 
 354     /** Static definition of MethodHandle.invokeGeneric checking code.
 355      * Directly returns the type-adjusted MH to invoke, as follows:
 356      * {@code (R)MH.invoke(a*) => MH.asType(TYPEOF(a*:R)).invokeBasic(a*)}
 357      */
 358     /*non-public*/ static
 359     @ForceInline
 360     Object checkGenericType(Object mhObj, Object expectedObj) {
 361         MethodHandle mh = (MethodHandle) mhObj;
 362         MethodType expected = (MethodType) expectedObj;



 363         return mh.asType(expected);
 364         /* Maybe add more paths here.  Possible optimizations:
 365          * for (R)MH.invoke(a*),
 366          * let MT0 = TYPEOF(a*:R), MT1 = MH.type
 367          *
 368          * if MT0==MT1 or MT1 can be safely called by MT0
 369          *  => MH.invokeBasic(a*)
 370          * if MT1 can be safely called by MT0[R := Object]
 371          *  => MH.invokeBasic(a*) & checkcast(R)
 372          * if MT1 can be safely called by MT0[* := Object]
 373          *  => checkcast(A)* & MH.invokeBasic(a*) & checkcast(R)
 374          * if a big adapter BA can be pulled out of (MT0,MT1)
 375          *  => BA.invokeBasic(MT0,MH,a*)
 376          * if a local adapter LA can cached on static CS0 = new GICS(MT0)
 377          *  => CS0.LA.invokeBasic(MH,a*)
 378          * else
 379          *  => MH.asType(MT0).invokeBasic(A*)
 380          */
 381     }
 382 


 416         final int PREPEND_MH = 0, PREPEND_COUNT = 1;
 417         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
 418         // prepend MH argument:
 419         System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
 420         outArgs[PREPEND_MH] = names[CALL_MH];
 421         names[LINKER_CALL] = new Name(mtype, outArgs);
 422         lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names);
 423         lform.compileToBytecode();  // JVM needs a real methodOop
 424         lform = mtype.form().setCachedLambdaForm(which, lform);
 425         return lform;
 426     }
 427 
 428     /** Static definition of MethodHandle.invokeGeneric checking code. */
 429     /*non-public*/ static
 430     @ForceInline
 431     Object getCallSiteTarget(Object site) {
 432         return ((CallSite)site).getTarget();
 433     }
 434 
 435     // Local constant functions:
 436     private static final NamedFunction
 437         NF_checkExactType,
 438         NF_checkGenericType,
 439         NF_getCallSiteTarget;
 440     static {
 441         try {
 442             NamedFunction nfs[] = {
 443                 NF_checkExactType = new NamedFunction(Invokers.class
 444                         .getDeclaredMethod("checkExactType", Object.class, Object.class)),
 445                 NF_checkGenericType = new NamedFunction(Invokers.class
 446                         .getDeclaredMethod("checkGenericType", Object.class, Object.class)),


 447                 NF_getCallSiteTarget = new NamedFunction(Invokers.class
 448                         .getDeclaredMethod("getCallSiteTarget", Object.class))
 449             };
 450             for (NamedFunction nf : nfs) {
 451                 // Each nf must be statically invocable or we get tied up in our bootstraps.
 452                 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
 453                 nf.resolve();
 454             }
 455         } catch (ReflectiveOperationException ex) {
 456             throw newInternalError(ex);
 457         }
 458     }
 459 
 460 }
src/share/classes/java/lang/invoke/Invokers.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File