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

Print this page
rev 10755 : [mq]: 8058892.lazy_init


 618 
 619                 MH_castReference        = IMPL_LOOKUP.findStatic(MHI, "castReference",
 620                                             MethodType.methodType(Object.class, Class.class, Object.class));
 621                 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
 622                                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
 623                 MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
 624                                             MethodType.methodType(Object[].class, Object[].class));
 625                 MH_fillNewArray         = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
 626                                             MethodType.methodType(Object[].class, Integer.class, Object[].class));
 627                 MH_fillNewTypedArray    = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
 628                                             MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
 629 
 630                 MH_selectAlternative    = makeIntrinsic(
 631                         IMPL_LOOKUP.findStatic(MHI, "selectAlternative",
 632                                 MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)),
 633                         Intrinsic.SELECT_ALTERNATIVE);
 634             } catch (ReflectiveOperationException ex) {
 635                 throw newInternalError(ex);
 636             }
 637         }



 638     }
 639 
 640     /** Factory method:  Collect or filter selected argument(s). */
 641     static MethodHandle makeCollectArguments(MethodHandle target,
 642                 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
 643         MethodType targetType = target.type();          // (a..., c, [b...])=>r
 644         MethodType collectorType = collector.type();    // (b...)=>c
 645         int collectArgCount = collectorType.parameterCount();
 646         Class<?> collectValType = collectorType.returnType();
 647         int collectValCount = (collectValType == void.class ? 0 : 1);
 648         MethodType srcType = targetType                 // (a..., [b...])=>r
 649                 .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
 650         if (!retainOriginalArgs) {                      // (a..., b...)=>r
 651             srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
 652         }
 653         // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
 654         // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
 655         // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
 656 
 657         // Now build a LambdaForm.


1251                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
1252     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1253                                   Object a4, Object a5, Object a6, Object a7,
1254                                   Object a8)
1255                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
1256     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1257                                   Object a4, Object a5, Object a6, Object a7,
1258                                   Object a8, Object a9)
1259                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
1260     private static MethodHandle[] makeArrays() {
1261         ArrayList<MethodHandle> mhs = new ArrayList<>();
1262         for (;;) {
1263             MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
1264             if (mh == null)  break;
1265             mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1266             mhs.add(mh);
1267         }
1268         assert(mhs.size() == 11);  // current number of methods
1269         return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
1270     }
1271     private static final MethodHandle[] ARRAYS = makeArrays();
1272 
1273     // filling versions of the above:
1274     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
1275     private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
1276         Object[] a = new Object[len];
1277         fillWithArguments(a, 0, args);
1278         return a;
1279     }
1280     private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
1281         Object[] a = Arrays.copyOf(example, len);
1282         assert(a.getClass() != Object[].class);
1283         fillWithArguments(a, 0, args);
1284         return a;
1285     }
1286     private static void fillWithArguments(Object[] a, int pos, Object... args) {
1287         System.arraycopy(args, 0, a, pos, args.length);
1288     }
1289     // using Integer pos instead of int pos to avoid bootstrapping problems
1290     private static Object[] fillArray(Integer pos, Object[] a, Object a0)
1291                 { fillWithArguments(a, pos, a0); return a; }


1298     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1299                                   Object a4)
1300                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
1301     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1302                                   Object a4, Object a5)
1303                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
1304     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1305                                   Object a4, Object a5, Object a6)
1306                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
1307     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1308                                   Object a4, Object a5, Object a6, Object a7)
1309                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
1310     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1311                                   Object a4, Object a5, Object a6, Object a7,
1312                                   Object a8)
1313                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
1314     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1315                                   Object a4, Object a5, Object a6, Object a7,
1316                                   Object a8, Object a9)
1317                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }



1318     private static MethodHandle[] makeFillArrays() {
1319         ArrayList<MethodHandle> mhs = new ArrayList<>();
1320         mhs.add(null);  // there is no empty fill; at least a0 is required
1321         for (;;) {
1322             MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
1323             if (mh == null)  break;
1324             mhs.add(mh);
1325         }
1326         assert(mhs.size() == 11);  // current number of methods
1327         return mhs.toArray(new MethodHandle[0]);
1328     }
1329     private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
1330 
1331     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
1332         Object a = w.makeArray(boxes.length);
1333         w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
1334         return a;
1335     }
1336 
1337     /** Return a method handle that takes the indicated number of Object
1338      *  arguments and returns an Object array of them, as if for varargs.
1339      */
1340     static MethodHandle varargsArray(int nargs) {
1341         MethodHandle mh = ARRAYS[nargs];
1342         if (mh != null)  return mh;
1343         mh = findCollector("array", nargs, Object[].class);
1344         if (mh != null)  mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1345         if (mh != null)  return ARRAYS[nargs] = mh;
1346         mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
1347         assert(assertCorrectArity(mh, nargs));
1348         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1349         return ARRAYS[nargs] = mh;
1350     }
1351 
1352     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
1353         assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
1354         return true;
1355     }
1356 
1357     // Array identity function (used as Lazy.MH_arrayIdentity).
1358     static <T> T[] identity(T[] x) {
1359         return x;
1360     }
1361 
1362     private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
1363         // Build up the result mh as a sequence of fills like this:
1364         //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
1365         // The various fill(_,10*I,___*[J]) are reusable.
1366         int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
1367         int rightLen = nargs - leftLen;
1368         MethodHandle leftCollector = newArray.bindTo(nargs);
1369         leftCollector = leftCollector.asCollector(Object[].class, leftLen);
1370         MethodHandle mh = finisher;
1371         if (rightLen > 0) {
1372             MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
1373             if (mh == Lazy.MH_arrayIdentity)
1374                 mh = rightFiller;
1375             else
1376                 mh = MethodHandles.collectArguments(mh, 0, rightFiller);
1377         }
1378         if (mh == Lazy.MH_arrayIdentity)
1379             mh = leftCollector;
1380         else
1381             mh = MethodHandles.collectArguments(mh, 0, leftCollector);
1382         return mh;
1383     }
1384 
1385     private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
1386     private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
1387     /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
1388      *  fills a[L]..a[N-1] with corresponding arguments,
1389      *  and then returns a.  The value L is a global constant (LEFT_ARGS).
1390      */
1391     private static MethodHandle fillToRight(int nargs) {
1392         MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
1393         if (filler != null)  return filler;
1394         filler = buildFiller(nargs);
1395         assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
1396         return FILL_ARRAY_TO_RIGHT[nargs] = filler;
1397     }
1398     private static MethodHandle buildFiller(int nargs) {
1399         if (nargs <= LEFT_ARGS)
1400             return Lazy.MH_arrayIdentity;  // no args to fill; return the array unchanged
1401         // we need room for both mh and a in mh.invoke(a, arg*[nargs])
1402         final int CHUNK = LEFT_ARGS;
1403         int rightLen = nargs % CHUNK;
1404         int midLen = nargs - rightLen;
1405         if (rightLen == 0) {
1406             midLen = nargs - (rightLen = CHUNK);
1407             if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
1408                 // build some precursors from left to right
1409                 for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
1410                     if (j > LEFT_ARGS)  fillToRight(j);
1411             }
1412         }
1413         if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
1414         assert(rightLen > 0);
1415         MethodHandle midFill = fillToRight(midLen);  // recursive fill
1416         MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
1417         assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
1418         assert(rightFill.type().parameterCount() == 1 + rightLen);
1419 
1420         // Combine the two fills:
1421         //   right(mid(a, x10..x19), x20..x23)
1422         // The final product will look like this:
1423         //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
1424         if (midLen == LEFT_ARGS)
1425             return rightFill;
1426         else
1427             return MethodHandles.collectArguments(rightFill, 0, midFill);
1428     }
1429 
1430     // Type-polymorphic version of varargs maker.
1431     private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
1432         = new ClassValue<MethodHandle[]>() {
1433             @Override
1434             protected MethodHandle[] computeValue(Class<?> type) {
1435                 return new MethodHandle[256];
1436             }




 618 
 619                 MH_castReference        = IMPL_LOOKUP.findStatic(MHI, "castReference",
 620                                             MethodType.methodType(Object.class, Class.class, Object.class));
 621                 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
 622                                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
 623                 MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
 624                                             MethodType.methodType(Object[].class, Object[].class));
 625                 MH_fillNewArray         = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
 626                                             MethodType.methodType(Object[].class, Integer.class, Object[].class));
 627                 MH_fillNewTypedArray    = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
 628                                             MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
 629 
 630                 MH_selectAlternative    = makeIntrinsic(
 631                         IMPL_LOOKUP.findStatic(MHI, "selectAlternative",
 632                                 MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)),
 633                         Intrinsic.SELECT_ALTERNATIVE);
 634             } catch (ReflectiveOperationException ex) {
 635                 throw newInternalError(ex);
 636             }
 637         }
 638 
 639         private static final MethodHandle[] ARRAYS = makeArrays();
 640         private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
 641     }
 642 
 643     /** Factory method:  Collect or filter selected argument(s). */
 644     static MethodHandle makeCollectArguments(MethodHandle target,
 645                 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
 646         MethodType targetType = target.type();          // (a..., c, [b...])=>r
 647         MethodType collectorType = collector.type();    // (b...)=>c
 648         int collectArgCount = collectorType.parameterCount();
 649         Class<?> collectValType = collectorType.returnType();
 650         int collectValCount = (collectValType == void.class ? 0 : 1);
 651         MethodType srcType = targetType                 // (a..., [b...])=>r
 652                 .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
 653         if (!retainOriginalArgs) {                      // (a..., b...)=>r
 654             srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
 655         }
 656         // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
 657         // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
 658         // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
 659 
 660         // Now build a LambdaForm.


1254                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
1255     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1256                                   Object a4, Object a5, Object a6, Object a7,
1257                                   Object a8)
1258                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
1259     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1260                                   Object a4, Object a5, Object a6, Object a7,
1261                                   Object a8, Object a9)
1262                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
1263     private static MethodHandle[] makeArrays() {
1264         ArrayList<MethodHandle> mhs = new ArrayList<>();
1265         for (;;) {
1266             MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
1267             if (mh == null)  break;
1268             mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1269             mhs.add(mh);
1270         }
1271         assert(mhs.size() == 11);  // current number of methods
1272         return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
1273     }

1274 
1275     // filling versions of the above:
1276     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
1277     private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
1278         Object[] a = new Object[len];
1279         fillWithArguments(a, 0, args);
1280         return a;
1281     }
1282     private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
1283         Object[] a = Arrays.copyOf(example, len);
1284         assert(a.getClass() != Object[].class);
1285         fillWithArguments(a, 0, args);
1286         return a;
1287     }
1288     private static void fillWithArguments(Object[] a, int pos, Object... args) {
1289         System.arraycopy(args, 0, a, pos, args.length);
1290     }
1291     // using Integer pos instead of int pos to avoid bootstrapping problems
1292     private static Object[] fillArray(Integer pos, Object[] a, Object a0)
1293                 { fillWithArguments(a, pos, a0); return a; }


1300     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1301                                   Object a4)
1302                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
1303     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1304                                   Object a4, Object a5)
1305                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
1306     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1307                                   Object a4, Object a5, Object a6)
1308                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
1309     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1310                                   Object a4, Object a5, Object a6, Object a7)
1311                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
1312     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1313                                   Object a4, Object a5, Object a6, Object a7,
1314                                   Object a8)
1315                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
1316     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1317                                   Object a4, Object a5, Object a6, Object a7,
1318                                   Object a8, Object a9)
1319                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
1320 
1321     private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods
1322 
1323     private static MethodHandle[] makeFillArrays() {
1324         ArrayList<MethodHandle> mhs = new ArrayList<>();
1325         mhs.add(null);  // there is no empty fill; at least a0 is required
1326         for (;;) {
1327             MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
1328             if (mh == null)  break;
1329             mhs.add(mh);
1330         }
1331         assert(mhs.size() == FILL_ARRAYS_COUNT);
1332         return mhs.toArray(new MethodHandle[0]);
1333     }

1334 
1335     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
1336         Object a = w.makeArray(boxes.length);
1337         w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
1338         return a;
1339     }
1340 
1341     /** Return a method handle that takes the indicated number of Object
1342      *  arguments and returns an Object array of them, as if for varargs.
1343      */
1344     static MethodHandle varargsArray(int nargs) {
1345         MethodHandle mh = Lazy.ARRAYS[nargs];
1346         if (mh != null)  return mh;
1347         mh = findCollector("array", nargs, Object[].class);
1348         if (mh != null)  mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1349         if (mh != null)  return Lazy.ARRAYS[nargs] = mh;
1350         mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
1351         assert(assertCorrectArity(mh, nargs));
1352         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1353         return Lazy.ARRAYS[nargs] = mh;
1354     }
1355 
1356     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
1357         assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
1358         return true;
1359     }
1360 
1361     // Array identity function (used as Lazy.MH_arrayIdentity).
1362     static <T> T[] identity(T[] x) {
1363         return x;
1364     }
1365 
1366     private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
1367         // Build up the result mh as a sequence of fills like this:
1368         //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
1369         // The various fill(_,10*I,___*[J]) are reusable.
1370         int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
1371         int rightLen = nargs - leftLen;
1372         MethodHandle leftCollector = newArray.bindTo(nargs);
1373         leftCollector = leftCollector.asCollector(Object[].class, leftLen);
1374         MethodHandle mh = finisher;
1375         if (rightLen > 0) {
1376             MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
1377             if (mh == Lazy.MH_arrayIdentity)
1378                 mh = rightFiller;
1379             else
1380                 mh = MethodHandles.collectArguments(mh, 0, rightFiller);
1381         }
1382         if (mh == Lazy.MH_arrayIdentity)
1383             mh = leftCollector;
1384         else
1385             mh = MethodHandles.collectArguments(mh, 0, leftCollector);
1386         return mh;
1387     }
1388 
1389     private static final int LEFT_ARGS = FILL_ARRAYS_COUNT - 1;
1390     private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
1391     /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
1392      *  fills a[L]..a[N-1] with corresponding arguments,
1393      *  and then returns a.  The value L is a global constant (LEFT_ARGS).
1394      */
1395     private static MethodHandle fillToRight(int nargs) {
1396         MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
1397         if (filler != null)  return filler;
1398         filler = buildFiller(nargs);
1399         assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
1400         return FILL_ARRAY_TO_RIGHT[nargs] = filler;
1401     }
1402     private static MethodHandle buildFiller(int nargs) {
1403         if (nargs <= LEFT_ARGS)
1404             return Lazy.MH_arrayIdentity;  // no args to fill; return the array unchanged
1405         // we need room for both mh and a in mh.invoke(a, arg*[nargs])
1406         final int CHUNK = LEFT_ARGS;
1407         int rightLen = nargs % CHUNK;
1408         int midLen = nargs - rightLen;
1409         if (rightLen == 0) {
1410             midLen = nargs - (rightLen = CHUNK);
1411             if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
1412                 // build some precursors from left to right
1413                 for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
1414                     if (j > LEFT_ARGS)  fillToRight(j);
1415             }
1416         }
1417         if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
1418         assert(rightLen > 0);
1419         MethodHandle midFill = fillToRight(midLen);  // recursive fill
1420         MethodHandle rightFill = Lazy.FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
1421         assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
1422         assert(rightFill.type().parameterCount() == 1 + rightLen);
1423 
1424         // Combine the two fills:
1425         //   right(mid(a, x10..x19), x20..x23)
1426         // The final product will look like this:
1427         //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
1428         if (midLen == LEFT_ARGS)
1429             return rightFill;
1430         else
1431             return MethodHandles.collectArguments(rightFill, 0, midFill);
1432     }
1433 
1434     // Type-polymorphic version of varargs maker.
1435     private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
1436         = new ClassValue<MethodHandle[]>() {
1437             @Override
1438             protected MethodHandle[] computeValue(Class<?> type) {
1439                 return new MethodHandle[256];
1440             }


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