src/share/classes/java/lang/invoke/MethodHandleImpl.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/MethodHandleImpl.java

Print this page
rev 10351 : 8037209: Improvements and cleanups to bytecode assembly for lambda forms
Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
rev 10352 : 8038261: JSR292: cache and reuse typed array accessors
Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
rev 10353 : 8049555: Move varargsArray from sun.invoke.util package to java.lang.invoke
Reviewed-by: ?
rev 10354 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?
rev 10356 : 8050166: Get rid of some package-private methods on arguments in j.l.i.MethodHandle
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10357 : 8050173: Add j.l.i.MethodHandle.copyWith(MethodType, LambdaForm)
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10358 : 8050174: Support overriding of isInvokeSpecial flag in WrappedMember
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10359 : 8050057: Improve caching of MethodHandle reinvokers
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10360 : 8050200: Make LambdaForm intrinsics detection more robust
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10361 : imported patch 11.8050877.conv
rev 10362 : imported patch 12.8050884.identity
rev 10363 : imported patch 13.8050887.zero
rev 10366 : imported patch 16.constraint
rev 10367 : imported patch 17.gwt


 623         inputArgPos += chunk;
 624         chunk = targetArgs.length - targetArgPos;  // all the rest
 625         System.arraycopy(names, inputArgPos, targetArgs, targetArgPos, chunk);
 626         assert(inputArgPos + chunk == collectNamePos);  // use of rest of input args also
 627         names[targetNamePos] = new Name(target, (Object[]) targetArgs);
 628 
 629         LambdaForm form = new LambdaForm("collect", lambdaType.parameterCount(), names);
 630         return SimpleMethodHandle.make(srcType, form);
 631     }
 632 
 633     @LambdaForm.Hidden
 634     static
 635     MethodHandle selectAlternative(boolean testResult, MethodHandle target, MethodHandle fallback) {
 636         return testResult ? target : fallback;
 637     }
 638 
 639     static
 640     MethodHandle makeGuardWithTest(MethodHandle test,
 641                                    MethodHandle target,
 642                                    MethodHandle fallback) {
 643         MethodType basicType = target.type().basicType();
 644         MethodHandle invokeBasic = MethodHandles.basicInvoker(basicType);
 645         int arity = basicType.parameterCount();
 646         int extraNames = 3;





























 647         MethodType lambdaType = basicType.invokerType();
 648         Name[] names = arguments(extraNames, lambdaType);
 649 
 650         Object[] testArgs   = Arrays.copyOfRange(names, 1, 1 + arity, Object[].class);
 651         Object[] targetArgs = Arrays.copyOfRange(names, 0, 1 + arity, Object[].class);





 652 
 653         // call test
 654         names[arity + 1] = new Name(test, testArgs);


 655 
 656         // call selectAlternative
 657         Object[] selectArgs = { names[arity + 1], target, fallback };
 658         names[arity + 2] = new Name(Lazy.MH_selectAlternative, selectArgs);
 659         targetArgs[0] = names[arity + 2];
 660 
 661         // call target or fallback
 662         names[arity + 3] = new Name(new NamedFunction(invokeBasic), targetArgs);



 663 
 664         LambdaForm form = new LambdaForm("guard", lambdaType.parameterCount(), names);
 665         return SimpleMethodHandle.make(target.type(), form);
 666     }
 667 
 668     /**
 669      * The LambaForm shape for catchException combinator is the following:
 670      * <blockquote><pre>{@code
 671      *  guardWithCatch=Lambda(a0:L,a1:L,a2:L)=>{
 672      *    t3:L=BoundMethodHandle$Species_LLLLL.argL0(a0:L);
 673      *    t4:L=BoundMethodHandle$Species_LLLLL.argL1(a0:L);
 674      *    t5:L=BoundMethodHandle$Species_LLLLL.argL2(a0:L);
 675      *    t6:L=BoundMethodHandle$Species_LLLLL.argL3(a0:L);
 676      *    t7:L=BoundMethodHandle$Species_LLLLL.argL4(a0:L);
 677      *    t8:L=MethodHandle.invokeBasic(t6:L,a1:L,a2:L);
 678      *    t9:L=MethodHandleImpl.guardWithCatch(t3:L,t4:L,t5:L,t8:L);
 679      *   t10:I=MethodHandle.invokeBasic(t7:L,t9:L);t10:I}
 680      * }</pre></blockquote>
 681      *
 682      * argL0 and argL2 are target and catcher method handles. argL1 is exception class.
 683      * argL3 and argL4 are auxiliary method handles: argL3 boxes arguments and wraps them into Object[]
 684      * (ValueConversions.array()) and argL4 unboxes result if necessary (ValueConversions.unbox()).
 685      *




 623         inputArgPos += chunk;
 624         chunk = targetArgs.length - targetArgPos;  // all the rest
 625         System.arraycopy(names, inputArgPos, targetArgs, targetArgPos, chunk);
 626         assert(inputArgPos + chunk == collectNamePos);  // use of rest of input args also
 627         names[targetNamePos] = new Name(target, (Object[]) targetArgs);
 628 
 629         LambdaForm form = new LambdaForm("collect", lambdaType.parameterCount(), names);
 630         return SimpleMethodHandle.make(srcType, form);
 631     }
 632 
 633     @LambdaForm.Hidden
 634     static
 635     MethodHandle selectAlternative(boolean testResult, MethodHandle target, MethodHandle fallback) {
 636         return testResult ? target : fallback;
 637     }
 638 
 639     static
 640     MethodHandle makeGuardWithTest(MethodHandle test,
 641                                    MethodHandle target,
 642                                    MethodHandle fallback) {
 643         MethodType type = target.type();
 644         assert(test.type().equals(type.changeReturnType(boolean.class)) && fallback.type().equals(type));
 645         MethodType basicType = type.basicType();
 646         LambdaForm form = makeGuardWithTestForm(basicType);
 647         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
 648         BoundMethodHandle mh;
 649         try {
 650             mh = (BoundMethodHandle)
 651                     data.constructor().invokeBasic(type, form,
 652                         (Object) test, (Object) target, (Object) fallback);
 653         } catch (Throwable ex) {
 654             throw uncaughtException(ex);
 655         }
 656         assert(mh.type() == type);
 657         return mh;
 658     }
 659 
 660     static
 661     LambdaForm makeGuardWithTestForm(MethodType basicType) {
 662         LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_GWT);
 663         if (lform != null)  return lform;
 664         final int THIS_MH      = 0;  // the BMH_LLL
 665         final int ARG_BASE     = 1;  // start of incoming arguments
 666         final int ARG_LIMIT    = ARG_BASE + basicType.parameterCount();
 667         int nameCursor = ARG_LIMIT;
 668         final int GET_TEST     = nameCursor++;
 669         final int GET_TARGET   = nameCursor++;
 670         final int GET_FALLBACK = nameCursor++;
 671         final int CALL_TEST    = nameCursor++;
 672         final int SELECT_ALT   = nameCursor++;
 673         final int CALL_TARGET  = nameCursor++;
 674         assert(CALL_TARGET == SELECT_ALT+1);  // must be true to trigger IBG.emitSelectAlternative
 675 
 676         MethodType lambdaType = basicType.invokerType();
 677         Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
 678 
 679         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
 680         names[THIS_MH] = names[THIS_MH].withConstraint(data);
 681         names[GET_TEST]     = new Name(data.getterFunction(0), names[THIS_MH]);
 682         names[GET_TARGET]   = new Name(data.getterFunction(1), names[THIS_MH]);
 683         names[GET_FALLBACK] = new Name(data.getterFunction(2), names[THIS_MH]);
 684 
 685         Object[] invokeArgs = Arrays.copyOfRange(names, 0, ARG_LIMIT, Object[].class);
 686 
 687         // call test
 688         MethodType testType = basicType.changeReturnType(boolean.class).basicType();
 689         invokeArgs[0] = names[GET_TEST];
 690         names[CALL_TEST] = new Name(testType, invokeArgs);
 691 
 692         // call selectAlternative
 693         names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[CALL_TEST],
 694                                      names[GET_TARGET], names[GET_FALLBACK]);

 695 
 696         // call target or fallback
 697         invokeArgs[0] = names[SELECT_ALT];
 698         names[CALL_TARGET] = new Name(basicType, invokeArgs);
 699 
 700         lform = new LambdaForm("guard", lambdaType.parameterCount(), names);
 701 
 702         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);

 703     }
 704 
 705     /**
 706      * The LambaForm shape for catchException combinator is the following:
 707      * <blockquote><pre>{@code
 708      *  guardWithCatch=Lambda(a0:L,a1:L,a2:L)=>{
 709      *    t3:L=BoundMethodHandle$Species_LLLLL.argL0(a0:L);
 710      *    t4:L=BoundMethodHandle$Species_LLLLL.argL1(a0:L);
 711      *    t5:L=BoundMethodHandle$Species_LLLLL.argL2(a0:L);
 712      *    t6:L=BoundMethodHandle$Species_LLLLL.argL3(a0:L);
 713      *    t7:L=BoundMethodHandle$Species_LLLLL.argL4(a0:L);
 714      *    t8:L=MethodHandle.invokeBasic(t6:L,a1:L,a2:L);
 715      *    t9:L=MethodHandleImpl.guardWithCatch(t3:L,t4:L,t5:L,t8:L);
 716      *   t10:I=MethodHandle.invokeBasic(t7:L,t9:L);t10:I}
 717      * }</pre></blockquote>
 718      *
 719      * argL0 and argL2 are target and catcher method handles. argL1 is exception class.
 720      * argL3 and argL4 are auxiliary method handles: argL3 boxes arguments and wraps them into Object[]
 721      * (ValueConversions.array()) and argL4 unboxes result if necessary (ValueConversions.unbox()).
 722      *


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