< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 575         }
 576         target = target.asType(targetType);
 577 
 578         MethodType srcType = targetType
 579                 .replaceParameterTypes(spreadArgPos, spreadArgPos + spreadArgCount, spreadArgType);
 580         // Now build a LambdaForm.
 581         MethodType lambdaType = srcType.invokerType();
 582         Name[] names = arguments(spreadArgCount + 2, lambdaType);
 583         int nameCursor = lambdaType.parameterCount();
 584         int[] indexes = new int[targetType.parameterCount()];
 585 
 586         for (int i = 0, argIndex = 1; i < targetType.parameterCount() + 1; i++, argIndex++) {
 587             Class<?> src = lambdaType.parameterType(i);
 588             if (i == spreadArgPos) {
 589                 // Spread the array.
 590                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
 591                 Name array = names[argIndex];
 592                 names[nameCursor++] = new Name(getFunction(NF_checkSpreadArgument), array, spreadArgCount);
 593                 for (int j = 0; j < spreadArgCount; i++, j++) {
 594                     indexes[i] = nameCursor;
 595                     names[nameCursor++] = new Name(aload, array, j);
 596                 }
 597             } else if (i < indexes.length) {
 598                 indexes[i] = argIndex;
 599             }
 600         }
 601         assert(nameCursor == names.length-1);  // leave room for the final call
 602 
 603         // Build argument array for the call.
 604         Name[] targetArgs = new Name[targetType.parameterCount()];
 605         for (int i = 0; i < targetType.parameterCount(); i++) {
 606             int idx = indexes[i];
 607             targetArgs[i] = names[idx];
 608         }
 609         names[names.length - 1] = new Name(target, (Object[]) targetArgs);
 610 
 611         LambdaForm form = new LambdaForm(lambdaType.parameterCount(), names, Kind.SPREAD);
 612         return SimpleMethodHandle.make(srcType, form);
 613     }
 614 
 615     static void checkSpreadArgument(Object av, int n) {


 920                                      : BoundMethodHandle.speciesData_LLL();
 921         names[THIS_MH] = names[THIS_MH].withConstraint(data);
 922         names[GET_TEST]     = new Name(data.getterFunction(0), names[THIS_MH]);
 923         names[GET_TARGET]   = new Name(data.getterFunction(1), names[THIS_MH]);
 924         names[GET_FALLBACK] = new Name(data.getterFunction(2), names[THIS_MH]);
 925         if (GET_COUNTERS != -1) {
 926             names[GET_COUNTERS] = new Name(data.getterFunction(3), names[THIS_MH]);
 927         }
 928         Object[] invokeArgs = Arrays.copyOfRange(names, 0, ARG_LIMIT, Object[].class);
 929 
 930         // call test
 931         MethodType testType = basicType.changeReturnType(boolean.class).basicType();
 932         invokeArgs[0] = names[GET_TEST];
 933         names[CALL_TEST] = new Name(testType, invokeArgs);
 934 
 935         // profile branch
 936         if (PROFILE != -1) {
 937             names[PROFILE] = new Name(getFunction(NF_profileBoolean), names[CALL_TEST], names[GET_COUNTERS]);
 938         }
 939         // call selectAlternative
 940         names[SELECT_ALT] = new Name(getConstantHandle(MH_selectAlternative), names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
 941 
 942         // call target or fallback
 943         invokeArgs[0] = names[SELECT_ALT];
 944         names[CALL_TARGET] = new Name(basicType, invokeArgs);
 945 
 946         lform = new LambdaForm(lambdaType.parameterCount(), names, /*forceInline=*/true, Kind.GUARD);
 947 
 948         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);
 949     }
 950 
 951     /**
 952      * The LambdaForm shape for catchException combinator is the following:
 953      * <blockquote><pre>{@code
 954      *  guardWithCatch=Lambda(a0:L,a1:L,a2:L)=>{
 955      *    t3:L=BoundMethodHandle$Species_LLLLL.argL0(a0:L);
 956      *    t4:L=BoundMethodHandle$Species_LLLLL.argL1(a0:L);
 957      *    t5:L=BoundMethodHandle$Species_LLLLL.argL2(a0:L);
 958      *    t6:L=BoundMethodHandle$Species_LLLLL.argL3(a0:L);
 959      *    t7:L=BoundMethodHandle$Species_LLLLL.argL4(a0:L);
 960      *    t8:L=MethodHandle.invokeBasic(t6:L,a1:L,a2:L);


 991         final int UNBOX_RESULT     = nameCursor++;
 992 
 993         Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
 994 
 995         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
 996         names[THIS_MH]          = names[THIS_MH].withConstraint(data);
 997         names[GET_TARGET]       = new Name(data.getterFunction(0), names[THIS_MH]);
 998         names[GET_CLASS]        = new Name(data.getterFunction(1), names[THIS_MH]);
 999         names[GET_CATCHER]      = new Name(data.getterFunction(2), names[THIS_MH]);
1000         names[GET_COLLECT_ARGS] = new Name(data.getterFunction(3), names[THIS_MH]);
1001         names[GET_UNBOX_RESULT] = new Name(data.getterFunction(4), names[THIS_MH]);
1002 
1003         // FIXME: rework argument boxing/result unboxing logic for LF interpretation
1004 
1005         // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...);
1006         MethodType collectArgsType = basicType.changeReturnType(Object.class);
1007         MethodHandle invokeBasic = MethodHandles.basicInvoker(collectArgsType);
1008         Object[] args = new Object[invokeBasic.type().parameterCount()];
1009         args[0] = names[GET_COLLECT_ARGS];
1010         System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT-ARG_BASE);
1011         names[BOXED_ARGS] = new Name(makeIntrinsic(invokeBasic, Intrinsic.GUARD_WITH_CATCH), args);
1012 
1013         // t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
1014         Object[] gwcArgs = new Object[] {names[GET_TARGET], names[GET_CLASS], names[GET_CATCHER], names[BOXED_ARGS]};
1015         names[TRY_CATCH] = new Name(getFunction(NF_guardWithCatch), gwcArgs);
1016 
1017         // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
1018         MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
1019         Object[] unboxArgs  = new Object[] {names[GET_UNBOX_RESULT], names[TRY_CATCH]};
1020         names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
1021 
1022         lform = new LambdaForm(lambdaType.parameterCount(), names, Kind.GUARD_WITH_CATCH);
1023 
1024         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform);
1025     }
1026 
1027     static
1028     MethodHandle makeGuardWithCatch(MethodHandle target,
1029                                     Class<? extends Throwable> exType,
1030                                     MethodHandle catcher) {
1031         MethodType type = target.type();


1879         final int BOXED_ARGS = nameCursor++;
1880         final int LOOP = nameCursor++;
1881         final int UNBOX_RESULT = nameCursor++;
1882 
1883         LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_LOOP);
1884         if (lform == null) {
1885             Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
1886 
1887             BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
1888             names[THIS_MH] = names[THIS_MH].withConstraint(data);
1889             names[GET_CLAUSE_DATA] = new Name(data.getterFunction(0), names[THIS_MH]);
1890             names[GET_COLLECT_ARGS] = new Name(data.getterFunction(1), names[THIS_MH]);
1891             names[GET_UNBOX_RESULT] = new Name(data.getterFunction(2), names[THIS_MH]);
1892 
1893             // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...);
1894             MethodType collectArgsType = basicType.changeReturnType(Object.class);
1895             MethodHandle invokeBasic = MethodHandles.basicInvoker(collectArgsType);
1896             Object[] args = new Object[invokeBasic.type().parameterCount()];
1897             args[0] = names[GET_COLLECT_ARGS];
1898             System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT - ARG_BASE);
1899             names[BOXED_ARGS] = new Name(makeIntrinsic(invokeBasic, Intrinsic.LOOP), args);
1900 
1901             // t_{i+1}:L=MethodHandleImpl.loop(localTypes:L,clauses:L,t_{i}:L);
1902             Object[] lArgs =
1903                     new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor
1904                             names[GET_CLAUSE_DATA], names[BOXED_ARGS]};
1905             names[LOOP] = new Name(getFunction(NF_loop), lArgs);
1906 
1907             // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
1908             MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
1909             Object[] unboxArgs = new Object[]{names[GET_UNBOX_RESULT], names[LOOP]};
1910             names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
1911 
1912             lform = basicType.form().setCachedLambdaForm(MethodTypeForm.LF_LOOP,
1913                     new LambdaForm(lambdaType.parameterCount(), names, Kind.LOOP));
1914         }
1915 
1916         // BOXED_ARGS is the index into the names array where the loop idiom starts
1917         return lform.editor().noteLoopLocalTypesForm(BOXED_ARGS, localVarTypes);
1918     }
1919 


2116         final int GET_UNBOX_RESULT = nameCursor++;
2117         final int BOXED_ARGS       = nameCursor++;
2118         final int TRY_FINALLY      = nameCursor++;
2119         final int UNBOX_RESULT     = nameCursor++;
2120 
2121         Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
2122 
2123         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLL();
2124         names[THIS_MH]          = names[THIS_MH].withConstraint(data);
2125         names[GET_TARGET]       = new Name(data.getterFunction(0), names[THIS_MH]);
2126         names[GET_CLEANUP]      = new Name(data.getterFunction(1), names[THIS_MH]);
2127         names[GET_COLLECT_ARGS] = new Name(data.getterFunction(2), names[THIS_MH]);
2128         names[GET_UNBOX_RESULT] = new Name(data.getterFunction(3), names[THIS_MH]);
2129 
2130         // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...);
2131         MethodType collectArgsType = basicType.changeReturnType(Object.class);
2132         MethodHandle invokeBasic = MethodHandles.basicInvoker(collectArgsType);
2133         Object[] args = new Object[invokeBasic.type().parameterCount()];
2134         args[0] = names[GET_COLLECT_ARGS];
2135         System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT-ARG_BASE);
2136         names[BOXED_ARGS] = new Name(makeIntrinsic(invokeBasic, Intrinsic.TRY_FINALLY), args);
2137 
2138         // t_{i+1}:L=MethodHandleImpl.tryFinally(target:L,exType:L,catcher:L,t_{i}:L);
2139         Object[] tfArgs = new Object[] {names[GET_TARGET], names[GET_CLEANUP], names[BOXED_ARGS]};
2140         names[TRY_FINALLY] = new Name(getFunction(NF_tryFinally), tfArgs);
2141 
2142         // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
2143         MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
2144         Object[] unboxArgs  = new Object[] {names[GET_UNBOX_RESULT], names[TRY_FINALLY]};
2145         names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
2146 
2147         lform = new LambdaForm(lambdaType.parameterCount(), names, Kind.TRY_FINALLY);
2148 
2149         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_TF, lform);
2150     }
2151 
2152     /**
2153      * Intrinsified during LambdaForm compilation
2154      * (see {@link InvokerBytecodeGenerator#emitTryFinally emitTryFinally}).
2155      */
2156     @LambdaForm.Hidden


2208 
2209     private static MethodHandle makeConstantHandle(int idx) {
2210         try {
2211             switch (idx) {
2212                 case MH_cast:
2213                     return IMPL_LOOKUP.findVirtual(Class.class, "cast",
2214                             MethodType.methodType(Object.class, Object.class));
2215                 case MH_copyAsPrimitiveArray:
2216                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "copyAsPrimitiveArray",
2217                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
2218                 case MH_arrayIdentity:
2219                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "identity",
2220                             MethodType.methodType(Object[].class, Object[].class));
2221                 case MH_fillNewArray:
2222                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "fillNewArray",
2223                             MethodType.methodType(Object[].class, Integer.class, Object[].class));
2224                 case MH_fillNewTypedArray:
2225                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "fillNewTypedArray",
2226                             MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
2227                 case MH_selectAlternative:
2228                     return makeIntrinsic(IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "selectAlternative",
2229                             MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)),
2230                         Intrinsic.SELECT_ALTERNATIVE);
2231                 case MH_countedLoopPred:
2232                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "countedLoopPredicate",
2233                             MethodType.methodType(boolean.class, int.class, int.class));
2234                 case MH_countedLoopStep:
2235                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "countedLoopStep",
2236                             MethodType.methodType(int.class, int.class, int.class));
2237                 case MH_initIterator:
2238                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "initIterator",
2239                             MethodType.methodType(Iterator.class, Iterable.class));
2240                 case MH_iteratePred:
2241                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "iteratePredicate",
2242                             MethodType.methodType(boolean.class, Iterator.class));
2243                 case MH_iterateNext:
2244                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "iterateNext",
2245                             MethodType.methodType(Object.class, Iterator.class));
2246                 case MH_Array_newInstance:
2247                     return IMPL_LOOKUP.findStatic(Array.class, "newInstance",
2248                             MethodType.methodType(Object.class, Class.class, int.class));
2249             }
2250         } catch (ReflectiveOperationException ex) {
   1 /*
   2  * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 575         }
 576         target = target.asType(targetType);
 577 
 578         MethodType srcType = targetType
 579                 .replaceParameterTypes(spreadArgPos, spreadArgPos + spreadArgCount, spreadArgType);
 580         // Now build a LambdaForm.
 581         MethodType lambdaType = srcType.invokerType();
 582         Name[] names = arguments(spreadArgCount + 2, lambdaType);
 583         int nameCursor = lambdaType.parameterCount();
 584         int[] indexes = new int[targetType.parameterCount()];
 585 
 586         for (int i = 0, argIndex = 1; i < targetType.parameterCount() + 1; i++, argIndex++) {
 587             Class<?> src = lambdaType.parameterType(i);
 588             if (i == spreadArgPos) {
 589                 // Spread the array.
 590                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
 591                 Name array = names[argIndex];
 592                 names[nameCursor++] = new Name(getFunction(NF_checkSpreadArgument), array, spreadArgCount);
 593                 for (int j = 0; j < spreadArgCount; i++, j++) {
 594                     indexes[i] = nameCursor;
 595                     names[nameCursor++] = new Name(new NamedFunction(aload, Intrinsic.ARRAY_LOAD), array, j);
 596                 }
 597             } else if (i < indexes.length) {
 598                 indexes[i] = argIndex;
 599             }
 600         }
 601         assert(nameCursor == names.length-1);  // leave room for the final call
 602 
 603         // Build argument array for the call.
 604         Name[] targetArgs = new Name[targetType.parameterCount()];
 605         for (int i = 0; i < targetType.parameterCount(); i++) {
 606             int idx = indexes[i];
 607             targetArgs[i] = names[idx];
 608         }
 609         names[names.length - 1] = new Name(target, (Object[]) targetArgs);
 610 
 611         LambdaForm form = new LambdaForm(lambdaType.parameterCount(), names, Kind.SPREAD);
 612         return SimpleMethodHandle.make(srcType, form);
 613     }
 614 
 615     static void checkSpreadArgument(Object av, int n) {


 920                                      : BoundMethodHandle.speciesData_LLL();
 921         names[THIS_MH] = names[THIS_MH].withConstraint(data);
 922         names[GET_TEST]     = new Name(data.getterFunction(0), names[THIS_MH]);
 923         names[GET_TARGET]   = new Name(data.getterFunction(1), names[THIS_MH]);
 924         names[GET_FALLBACK] = new Name(data.getterFunction(2), names[THIS_MH]);
 925         if (GET_COUNTERS != -1) {
 926             names[GET_COUNTERS] = new Name(data.getterFunction(3), names[THIS_MH]);
 927         }
 928         Object[] invokeArgs = Arrays.copyOfRange(names, 0, ARG_LIMIT, Object[].class);
 929 
 930         // call test
 931         MethodType testType = basicType.changeReturnType(boolean.class).basicType();
 932         invokeArgs[0] = names[GET_TEST];
 933         names[CALL_TEST] = new Name(testType, invokeArgs);
 934 
 935         // profile branch
 936         if (PROFILE != -1) {
 937             names[PROFILE] = new Name(getFunction(NF_profileBoolean), names[CALL_TEST], names[GET_COUNTERS]);
 938         }
 939         // call selectAlternative
 940         names[SELECT_ALT] = new Name(new NamedFunction(getConstantHandle(MH_selectAlternative), Intrinsic.SELECT_ALTERNATIVE), names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
 941 
 942         // call target or fallback
 943         invokeArgs[0] = names[SELECT_ALT];
 944         names[CALL_TARGET] = new Name(basicType, invokeArgs);
 945 
 946         lform = new LambdaForm(lambdaType.parameterCount(), names, /*forceInline=*/true, Kind.GUARD);
 947 
 948         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);
 949     }
 950 
 951     /**
 952      * The LambdaForm shape for catchException combinator is the following:
 953      * <blockquote><pre>{@code
 954      *  guardWithCatch=Lambda(a0:L,a1:L,a2:L)=>{
 955      *    t3:L=BoundMethodHandle$Species_LLLLL.argL0(a0:L);
 956      *    t4:L=BoundMethodHandle$Species_LLLLL.argL1(a0:L);
 957      *    t5:L=BoundMethodHandle$Species_LLLLL.argL2(a0:L);
 958      *    t6:L=BoundMethodHandle$Species_LLLLL.argL3(a0:L);
 959      *    t7:L=BoundMethodHandle$Species_LLLLL.argL4(a0:L);
 960      *    t8:L=MethodHandle.invokeBasic(t6:L,a1:L,a2:L);


 991         final int UNBOX_RESULT     = nameCursor++;
 992 
 993         Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
 994 
 995         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
 996         names[THIS_MH]          = names[THIS_MH].withConstraint(data);
 997         names[GET_TARGET]       = new Name(data.getterFunction(0), names[THIS_MH]);
 998         names[GET_CLASS]        = new Name(data.getterFunction(1), names[THIS_MH]);
 999         names[GET_CATCHER]      = new Name(data.getterFunction(2), names[THIS_MH]);
1000         names[GET_COLLECT_ARGS] = new Name(data.getterFunction(3), names[THIS_MH]);
1001         names[GET_UNBOX_RESULT] = new Name(data.getterFunction(4), names[THIS_MH]);
1002 
1003         // FIXME: rework argument boxing/result unboxing logic for LF interpretation
1004 
1005         // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...);
1006         MethodType collectArgsType = basicType.changeReturnType(Object.class);
1007         MethodHandle invokeBasic = MethodHandles.basicInvoker(collectArgsType);
1008         Object[] args = new Object[invokeBasic.type().parameterCount()];
1009         args[0] = names[GET_COLLECT_ARGS];
1010         System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT-ARG_BASE);
1011         names[BOXED_ARGS] = new Name(new NamedFunction(invokeBasic, Intrinsic.GUARD_WITH_CATCH), args);
1012 
1013         // t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
1014         Object[] gwcArgs = new Object[] {names[GET_TARGET], names[GET_CLASS], names[GET_CATCHER], names[BOXED_ARGS]};
1015         names[TRY_CATCH] = new Name(getFunction(NF_guardWithCatch), gwcArgs);
1016 
1017         // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
1018         MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
1019         Object[] unboxArgs  = new Object[] {names[GET_UNBOX_RESULT], names[TRY_CATCH]};
1020         names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
1021 
1022         lform = new LambdaForm(lambdaType.parameterCount(), names, Kind.GUARD_WITH_CATCH);
1023 
1024         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform);
1025     }
1026 
1027     static
1028     MethodHandle makeGuardWithCatch(MethodHandle target,
1029                                     Class<? extends Throwable> exType,
1030                                     MethodHandle catcher) {
1031         MethodType type = target.type();


1879         final int BOXED_ARGS = nameCursor++;
1880         final int LOOP = nameCursor++;
1881         final int UNBOX_RESULT = nameCursor++;
1882 
1883         LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_LOOP);
1884         if (lform == null) {
1885             Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
1886 
1887             BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
1888             names[THIS_MH] = names[THIS_MH].withConstraint(data);
1889             names[GET_CLAUSE_DATA] = new Name(data.getterFunction(0), names[THIS_MH]);
1890             names[GET_COLLECT_ARGS] = new Name(data.getterFunction(1), names[THIS_MH]);
1891             names[GET_UNBOX_RESULT] = new Name(data.getterFunction(2), names[THIS_MH]);
1892 
1893             // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...);
1894             MethodType collectArgsType = basicType.changeReturnType(Object.class);
1895             MethodHandle invokeBasic = MethodHandles.basicInvoker(collectArgsType);
1896             Object[] args = new Object[invokeBasic.type().parameterCount()];
1897             args[0] = names[GET_COLLECT_ARGS];
1898             System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT - ARG_BASE);
1899             names[BOXED_ARGS] = new Name(new NamedFunction(invokeBasic, Intrinsic.LOOP), args);
1900 
1901             // t_{i+1}:L=MethodHandleImpl.loop(localTypes:L,clauses:L,t_{i}:L);
1902             Object[] lArgs =
1903                     new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor
1904                             names[GET_CLAUSE_DATA], names[BOXED_ARGS]};
1905             names[LOOP] = new Name(getFunction(NF_loop), lArgs);
1906 
1907             // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
1908             MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
1909             Object[] unboxArgs = new Object[]{names[GET_UNBOX_RESULT], names[LOOP]};
1910             names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
1911 
1912             lform = basicType.form().setCachedLambdaForm(MethodTypeForm.LF_LOOP,
1913                     new LambdaForm(lambdaType.parameterCount(), names, Kind.LOOP));
1914         }
1915 
1916         // BOXED_ARGS is the index into the names array where the loop idiom starts
1917         return lform.editor().noteLoopLocalTypesForm(BOXED_ARGS, localVarTypes);
1918     }
1919 


2116         final int GET_UNBOX_RESULT = nameCursor++;
2117         final int BOXED_ARGS       = nameCursor++;
2118         final int TRY_FINALLY      = nameCursor++;
2119         final int UNBOX_RESULT     = nameCursor++;
2120 
2121         Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
2122 
2123         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLL();
2124         names[THIS_MH]          = names[THIS_MH].withConstraint(data);
2125         names[GET_TARGET]       = new Name(data.getterFunction(0), names[THIS_MH]);
2126         names[GET_CLEANUP]      = new Name(data.getterFunction(1), names[THIS_MH]);
2127         names[GET_COLLECT_ARGS] = new Name(data.getterFunction(2), names[THIS_MH]);
2128         names[GET_UNBOX_RESULT] = new Name(data.getterFunction(3), names[THIS_MH]);
2129 
2130         // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...);
2131         MethodType collectArgsType = basicType.changeReturnType(Object.class);
2132         MethodHandle invokeBasic = MethodHandles.basicInvoker(collectArgsType);
2133         Object[] args = new Object[invokeBasic.type().parameterCount()];
2134         args[0] = names[GET_COLLECT_ARGS];
2135         System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT-ARG_BASE);
2136         names[BOXED_ARGS] = new Name(new NamedFunction(invokeBasic, Intrinsic.TRY_FINALLY), args);
2137 
2138         // t_{i+1}:L=MethodHandleImpl.tryFinally(target:L,exType:L,catcher:L,t_{i}:L);
2139         Object[] tfArgs = new Object[] {names[GET_TARGET], names[GET_CLEANUP], names[BOXED_ARGS]};
2140         names[TRY_FINALLY] = new Name(getFunction(NF_tryFinally), tfArgs);
2141 
2142         // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
2143         MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
2144         Object[] unboxArgs  = new Object[] {names[GET_UNBOX_RESULT], names[TRY_FINALLY]};
2145         names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
2146 
2147         lform = new LambdaForm(lambdaType.parameterCount(), names, Kind.TRY_FINALLY);
2148 
2149         return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_TF, lform);
2150     }
2151 
2152     /**
2153      * Intrinsified during LambdaForm compilation
2154      * (see {@link InvokerBytecodeGenerator#emitTryFinally emitTryFinally}).
2155      */
2156     @LambdaForm.Hidden


2208 
2209     private static MethodHandle makeConstantHandle(int idx) {
2210         try {
2211             switch (idx) {
2212                 case MH_cast:
2213                     return IMPL_LOOKUP.findVirtual(Class.class, "cast",
2214                             MethodType.methodType(Object.class, Object.class));
2215                 case MH_copyAsPrimitiveArray:
2216                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "copyAsPrimitiveArray",
2217                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
2218                 case MH_arrayIdentity:
2219                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "identity",
2220                             MethodType.methodType(Object[].class, Object[].class));
2221                 case MH_fillNewArray:
2222                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "fillNewArray",
2223                             MethodType.methodType(Object[].class, Integer.class, Object[].class));
2224                 case MH_fillNewTypedArray:
2225                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "fillNewTypedArray",
2226                             MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
2227                 case MH_selectAlternative:
2228                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "selectAlternative",
2229                             MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class));

2230                 case MH_countedLoopPred:
2231                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "countedLoopPredicate",
2232                             MethodType.methodType(boolean.class, int.class, int.class));
2233                 case MH_countedLoopStep:
2234                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "countedLoopStep",
2235                             MethodType.methodType(int.class, int.class, int.class));
2236                 case MH_initIterator:
2237                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "initIterator",
2238                             MethodType.methodType(Iterator.class, Iterable.class));
2239                 case MH_iteratePred:
2240                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "iteratePredicate",
2241                             MethodType.methodType(boolean.class, Iterator.class));
2242                 case MH_iterateNext:
2243                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "iterateNext",
2244                             MethodType.methodType(Object.class, Iterator.class));
2245                 case MH_Array_newInstance:
2246                     return IMPL_LOOKUP.findStatic(Array.class, "newInstance",
2247                             MethodType.methodType(Object.class, Class.class, int.class));
2248             }
2249         } catch (ReflectiveOperationException ex) {
< prev index next >