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

Print this page
rev 10923 : 8062180: MethodHandleImpl.makeArrays throws and swallows java.lang.NoSuchFieldError in normal flow
Reviewed-by: duke


1371     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1372                                   Object a4)
1373                 { return makeArray(a0, a1, a2, a3, a4); }
1374     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1375                                   Object a4, Object a5)
1376                 { return makeArray(a0, a1, a2, a3, a4, a5); }
1377     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1378                                   Object a4, Object a5, Object a6)
1379                 { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
1380     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1381                                   Object a4, Object a5, Object a6, Object a7)
1382                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
1383     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1384                                   Object a4, Object a5, Object a6, Object a7,
1385                                   Object a8)
1386                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
1387     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1388                                   Object a4, Object a5, Object a6, Object a7,
1389                                   Object a8, Object a9)
1390                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }



1391     private static MethodHandle[] makeArrays() {
1392         ArrayList<MethodHandle> mhs = new ArrayList<>();
1393         for (;;) {
1394             MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
1395             if (mh == null)  break;
1396             mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1397             mhs.add(mh);
1398         }
1399         assert(mhs.size() == 11);  // current number of methods
1400         return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
1401     }
1402 
1403     // filling versions of the above:
1404     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
1405     private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
1406         Object[] a = new Object[len];
1407         fillWithArguments(a, 0, args);
1408         return a;
1409     }
1410     private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
1411         Object[] a = Arrays.copyOf(example, len);
1412         assert(a.getClass() != Object[].class);
1413         fillWithArguments(a, 0, args);
1414         return a;
1415     }
1416     private static void fillWithArguments(Object[] a, int pos, Object... args) {
1417         System.arraycopy(args, 0, a, pos, args.length);
1418     }
1419     // using Integer pos instead of int pos to avoid bootstrapping problems
1420     private static Object[] fillArray(Integer pos, Object[] a, Object a0)


1432                                   Object a4, Object a5)
1433                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
1434     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1435                                   Object a4, Object a5, Object a6)
1436                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
1437     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1438                                   Object a4, Object a5, Object a6, Object a7)
1439                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
1440     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1441                                   Object a4, Object a5, Object a6, Object a7,
1442                                   Object a8)
1443                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
1444     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1445                                   Object a4, Object a5, Object a6, Object a7,
1446                                   Object a8, Object a9)
1447                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
1448 
1449     private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods
1450 
1451     private static MethodHandle[] makeFillArrays() {
1452         ArrayList<MethodHandle> mhs = new ArrayList<>();
1453         mhs.add(null);  // there is no empty fill; at least a0 is required
1454         for (;;) {
1455             MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
1456             if (mh == null)  break;
1457             mhs.add(mh);
1458         }
1459         assert(mhs.size() == FILL_ARRAYS_COUNT);
1460         return mhs.toArray(new MethodHandle[0]);
1461     }
1462 
1463     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
1464         Object a = w.makeArray(boxes.length);
1465         w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
1466         return a;
1467     }
1468 
1469     /** Return a method handle that takes the indicated number of Object
1470      *  arguments and returns an Object array of them, as if for varargs.
1471      */
1472     static MethodHandle varargsArray(int nargs) {
1473         MethodHandle mh = Lazy.ARRAYS[nargs];
1474         if (mh != null)  return mh;
1475         mh = findCollector("array", nargs, Object[].class);
1476         if (mh != null)  mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1477         if (mh != null)  return Lazy.ARRAYS[nargs] = mh;
1478         mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
1479         assert(assertCorrectArity(mh, nargs));
1480         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1481         return Lazy.ARRAYS[nargs] = mh;
1482     }
1483 
1484     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
1485         assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
1486         return true;
1487     }
1488 
1489     // Array identity function (used as Lazy.MH_arrayIdentity).
1490     static <T> T[] identity(T[] x) {
1491         return x;
1492     }
1493 
1494     private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
1495         // Build up the result mh as a sequence of fills like this:
1496         //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
1497         // The various fill(_,10*I,___*[J]) are reusable.




1371     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1372                                   Object a4)
1373                 { return makeArray(a0, a1, a2, a3, a4); }
1374     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1375                                   Object a4, Object a5)
1376                 { return makeArray(a0, a1, a2, a3, a4, a5); }
1377     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1378                                   Object a4, Object a5, Object a6)
1379                 { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
1380     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1381                                   Object a4, Object a5, Object a6, Object a7)
1382                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
1383     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1384                                   Object a4, Object a5, Object a6, Object a7,
1385                                   Object a8)
1386                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
1387     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
1388                                   Object a4, Object a5, Object a6, Object a7,
1389                                   Object a8, Object a9)
1390                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
1391 
1392     private static final int ARRAYS_COUNT = 11;
1393 
1394     private static MethodHandle[] makeArrays() {
1395         MethodHandle[] mhs = new MethodHandle[MAX_ARITY + 1];
1396         for (int i = 0; i < ARRAYS_COUNT; i++) {
1397             MethodHandle mh = findCollector("array", i, Object[].class);
1398             if (mh == null)  break;
1399             mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1400             mhs[i] = mh;
1401         }
1402         assert(mhs[ARRAYS_COUNT - 1] != null);  // current number of methods
1403         return mhs;
1404     }
1405 
1406     // filling versions of the above:
1407     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
1408     private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
1409         Object[] a = new Object[len];
1410         fillWithArguments(a, 0, args);
1411         return a;
1412     }
1413     private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
1414         Object[] a = Arrays.copyOf(example, len);
1415         assert(a.getClass() != Object[].class);
1416         fillWithArguments(a, 0, args);
1417         return a;
1418     }
1419     private static void fillWithArguments(Object[] a, int pos, Object... args) {
1420         System.arraycopy(args, 0, a, pos, args.length);
1421     }
1422     // using Integer pos instead of int pos to avoid bootstrapping problems
1423     private static Object[] fillArray(Integer pos, Object[] a, Object a0)


1435                                   Object a4, Object a5)
1436                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
1437     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1438                                   Object a4, Object a5, Object a6)
1439                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
1440     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1441                                   Object a4, Object a5, Object a6, Object a7)
1442                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
1443     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1444                                   Object a4, Object a5, Object a6, Object a7,
1445                                   Object a8)
1446                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
1447     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
1448                                   Object a4, Object a5, Object a6, Object a7,
1449                                   Object a8, Object a9)
1450                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
1451 
1452     private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods
1453 
1454     private static MethodHandle[] makeFillArrays() {
1455         MethodHandle[] mhs = new MethodHandle[FILL_ARRAYS_COUNT];
1456         mhs[0] = null;  // there is no empty fill; at least a0 is required
1457         for (int i = 1; i < FILL_ARRAYS_COUNT; i++) {
1458             MethodHandle mh = findCollector("fillArray", i, Object[].class, Integer.class, Object[].class);
1459             if (mh == null)  break;
1460             mhs[i] = mh;
1461         }
1462         assert(mhs[FILL_ARRAYS_COUNT - 1] != null);
1463         return mhs;
1464     }
1465 
1466     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
1467         Object a = w.makeArray(boxes.length);
1468         w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
1469         return a;
1470     }
1471 
1472     /** Return a method handle that takes the indicated number of Object
1473      *  arguments and returns an Object array of them, as if for varargs.
1474      */
1475     static MethodHandle varargsArray(int nargs) {
1476         MethodHandle mh = Lazy.ARRAYS[nargs];
1477         if (mh != null)  return mh;



1478         mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
1479         assert(assertCorrectArity(mh, nargs));
1480         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
1481         return Lazy.ARRAYS[nargs] = mh;
1482     }
1483 
1484     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
1485         assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
1486         return true;
1487     }
1488 
1489     // Array identity function (used as Lazy.MH_arrayIdentity).
1490     static <T> T[] identity(T[] x) {
1491         return x;
1492     }
1493 
1494     private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
1495         // Build up the result mh as a sequence of fills like this:
1496         //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
1497         // The various fill(_,10*I,___*[J]) are reusable.