jdk/src/java.base/share/classes/sun/invoke/util/ValueConversions.java
changeset 26466 3bbb6a284bd4
parent 25859 3317bb8137f4
child 26474 655d08549e43
--- a/jdk/src/java.base/share/classes/sun/invoke/util/ValueConversions.java	Wed Sep 10 19:19:47 2014 +0400
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/ValueConversions.java	Wed Sep 10 19:19:47 2014 +0400
@@ -29,30 +29,10 @@
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.EnumMap;
-import java.util.List;
 
 public class ValueConversions {
     private static final Class<?> THIS_CLASS = ValueConversions.class;
-    // Do not adjust this except for special platforms:
-    private static final int MAX_ARITY;
-    static {
-        final Object[] values = { 255 };
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                @Override
-                public Void run() {
-                    values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
-                    return null;
-                }
-            });
-        MAX_ARITY = (Integer) values[0];
-    }
-
     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
 
     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
@@ -443,12 +423,7 @@
         return x;
     }
 
-    private static ClassCastException newClassCastException(Class<?> t, Object obj) {
-        return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
-    }
-
-    private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
-            ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY;
+    private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY;
     static {
         try {
             MethodType idType = MethodType.genericMethodType(1);
@@ -459,33 +434,11 @@
             ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
             IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
             EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
-            ARRAY_IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class));
-            FILL_NEW_ARRAY = IMPL_LOOKUP
-                    .findStatic(THIS_CLASS, "fillNewArray",
-                          MethodType.methodType(Object[].class, Integer.class, Object[].class));
-            FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP
-                    .findStatic(THIS_CLASS, "fillNewTypedArray",
-                          MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
         } catch (NoSuchMethodException | IllegalAccessException ex) {
             throw newInternalError("uncaught exception", ex);
         }
     }
 
-    // Varargs methods need to be in a separately initialized class, to avoid bootstrapping problems.
-    static class LazyStatics {
-        private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
-        static {
-            try {
-                //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class));
-                COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class));
-                COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class));
-                MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class));
-            } catch (ReflectiveOperationException ex) {
-                throw newInternalError("uncaught exception", ex);
-            }
-        }
-    }
-
     private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
             = newWrapperCaches(1);
 
@@ -808,363 +761,6 @@
         return Character.toUpperCase(x.charAt(0))+x.substring(1);
     }
 
-    /// Collection of multiple arguments.
-
-    public static Object convertArrayElements(Class<?> arrayType, Object array) {
-        Class<?> src = array.getClass().getComponentType();
-        Class<?> dst = arrayType.getComponentType();
-        if (src == null || dst == null)  throw new IllegalArgumentException("not array type");
-        Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null);
-        Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null);
-        int length;
-        if (sw == null) {
-            Object[] a = (Object[]) array;
-            length = a.length;
-            if (dw == null)
-                return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class));
-            Object res = dw.makeArray(length);
-            dw.copyArrayUnboxing(a, 0, res, 0, length);
-            return res;
-        }
-        length = java.lang.reflect.Array.getLength(array);
-        Object[] res;
-        if (dw == null) {
-            res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class));
-        } else {
-            res = new Object[length];
-        }
-        sw.copyArrayBoxing(array, 0, res, 0, length);
-        if (dw == null)  return res;
-        Object a = dw.makeArray(length);
-        dw.copyArrayUnboxing(res, 0, a, 0, length);
-        return a;
-    }
-
-    private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
-        MethodType type = MethodType.genericMethodType(nargs)
-                .changeReturnType(rtype)
-                .insertParameterTypes(0, ptypes);
-        try {
-            return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
-        } catch (ReflectiveOperationException ex) {
-            return null;
-        }
-    }
-
-    private static final Object[] NO_ARGS_ARRAY = {};
-    private static Object[] makeArray(Object... args) { return args; }
-    private static Object[] array() { return NO_ARGS_ARRAY; }
-    private static Object[] array(Object a0)
-                { return makeArray(a0); }
-    private static Object[] array(Object a0, Object a1)
-                { return makeArray(a0, a1); }
-    private static Object[] array(Object a0, Object a1, Object a2)
-                { return makeArray(a0, a1, a2); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3)
-                { return makeArray(a0, a1, a2, a3); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
-                                  Object a4)
-                { return makeArray(a0, a1, a2, a3, a4); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5)
-                { return makeArray(a0, a1, a2, a3, a4, a5); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6)
-                { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6, Object a7)
-                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6, Object a7,
-                                  Object a8)
-                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6, Object a7,
-                                  Object a8, Object a9)
-                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-    private static MethodHandle[] makeArrays() {
-        ArrayList<MethodHandle> mhs = new ArrayList<>();
-        for (;;) {
-            MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
-            if (mh == null)  break;
-            mhs.add(mh);
-        }
-        assert(mhs.size() == 11);  // current number of methods
-        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
-    }
-    private static final MethodHandle[] ARRAYS = makeArrays();
-
-    // filling versions of the above:
-    // using Integer len instead of int len and no varargs to avoid bootstrapping problems
-    private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
-        Object[] a = new Object[len];
-        fillWithArguments(a, 0, args);
-        return a;
-    }
-    private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
-        Object[] a = Arrays.copyOf(example, len);
-        fillWithArguments(a, 0, args);
-        return a;
-    }
-    private static void fillWithArguments(Object[] a, int pos, Object... args) {
-        System.arraycopy(args, 0, a, pos, args.length);
-    }
-    // using Integer pos instead of int pos to avoid bootstrapping problems
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0)
-                { fillWithArguments(a, pos, a0); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
-                { fillWithArguments(a, pos, a0, a1); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
-                { fillWithArguments(a, pos, a0, a1, a2); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
-                { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
-                                  Object a4)
-                { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5)
-                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6)
-                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6, Object a7)
-                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6, Object a7,
-                                  Object a8)
-                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
-    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
-                                  Object a4, Object a5, Object a6, Object a7,
-                                  Object a8, Object a9)
-                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
-    private static MethodHandle[] makeFillArrays() {
-        ArrayList<MethodHandle> mhs = new ArrayList<>();
-        mhs.add(null);  // there is no empty fill; at least a0 is required
-        for (;;) {
-            MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
-            if (mh == null)  break;
-            mhs.add(mh);
-        }
-        assert(mhs.size() == 11);  // current number of methods
-        return mhs.toArray(new MethodHandle[0]);
-    }
-    private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
-
-    private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
-        return Arrays.copyOf(a, a.length, arrayType);
-    }
-    private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
-        Object a = w.makeArray(boxes.length);
-        w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
-        return a;
-    }
-
-    /** Return a method handle that takes the indicated number of Object
-     *  arguments and returns an Object array of them, as if for varargs.
-     */
-    public static MethodHandle varargsArray(int nargs) {
-        MethodHandle mh = ARRAYS[nargs];
-        if (mh != null)  return mh;
-        mh = findCollector("array", nargs, Object[].class);
-        if (mh != null)  return ARRAYS[nargs] = mh;
-        mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs);
-        assert(assertCorrectArity(mh, nargs));
-        return ARRAYS[nargs] = mh;
-    }
-
-    private static boolean assertCorrectArity(MethodHandle mh, int arity) {
-        assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
-        return true;
-    }
-
-    private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
-        // Build up the result mh as a sequence of fills like this:
-        //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
-        // The various fill(_,10*I,___*[J]) are reusable.
-        int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
-        int rightLen = nargs - leftLen;
-        MethodHandle leftCollector = newArray.bindTo(nargs);
-        leftCollector = leftCollector.asCollector(Object[].class, leftLen);
-        MethodHandle mh = finisher;
-        if (rightLen > 0) {
-            MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
-            if (mh == ARRAY_IDENTITY)
-                mh = rightFiller;
-            else
-                mh = MethodHandles.collectArguments(mh, 0, rightFiller);
-        }
-        if (mh == ARRAY_IDENTITY)
-            mh = leftCollector;
-        else
-            mh = MethodHandles.collectArguments(mh, 0, leftCollector);
-        return mh;
-    }
-
-    private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
-    private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
-    /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
-     *  fills a[L]..a[N-1] with corresponding arguments,
-     *  and then returns a.  The value L is a global constant (LEFT_ARGS).
-     */
-    private static MethodHandle fillToRight(int nargs) {
-        MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
-        if (filler != null)  return filler;
-        filler = buildFiller(nargs);
-        assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
-        return FILL_ARRAY_TO_RIGHT[nargs] = filler;
-    }
-    private static MethodHandle buildFiller(int nargs) {
-        if (nargs <= LEFT_ARGS)
-            return ARRAY_IDENTITY;  // no args to fill; return the array unchanged
-        // we need room for both mh and a in mh.invoke(a, arg*[nargs])
-        final int CHUNK = LEFT_ARGS;
-        int rightLen = nargs % CHUNK;
-        int midLen = nargs - rightLen;
-        if (rightLen == 0) {
-            midLen = nargs - (rightLen = CHUNK);
-            if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
-                // build some precursors from left to right
-                for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
-                    if (j > LEFT_ARGS)  fillToRight(j);
-            }
-        }
-        if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
-        assert(rightLen > 0);
-        MethodHandle midFill = fillToRight(midLen);  // recursive fill
-        MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
-        assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
-        assert(rightFill.type().parameterCount() == 1 + rightLen);
-
-        // Combine the two fills:
-        //   right(mid(a, x10..x19), x20..x23)
-        // The final product will look like this:
-        //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
-        if (midLen == LEFT_ARGS)
-            return rightFill;
-        else
-            return MethodHandles.collectArguments(rightFill, 0, midFill);
-    }
-
-    // Type-polymorphic version of varargs maker.
-    private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
-        = new ClassValue<MethodHandle[]>() {
-            @Override
-            protected MethodHandle[] computeValue(Class<?> type) {
-                return new MethodHandle[256];
-            }
-    };
-
-    static final int MAX_JVM_ARITY = 255;  // limit imposed by the JVM
-
-    /** Return a method handle that takes the indicated number of
-     *  typed arguments and returns an array of them.
-     *  The type argument is the array type.
-     */
-    public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
-        Class<?> elemType = arrayType.getComponentType();
-        if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
-        // FIXME: Need more special casing and caching here.
-        if (nargs >= MAX_JVM_ARITY/2 - 1) {
-            int slots = nargs;
-            final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1;  // 1 for receiver MH
-            if (arrayType == double[].class || arrayType == long[].class)
-                slots *= 2;
-            if (slots > MAX_ARRAY_SLOTS)
-                throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
-        }
-        if (elemType == Object.class)
-            return varargsArray(nargs);
-        // other cases:  primitive arrays, subtypes of Object[]
-        MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
-        MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
-        if (mh != null)  return mh;
-        if (elemType.isPrimitive()) {
-            MethodHandle builder = FILL_NEW_ARRAY;
-            MethodHandle producer = buildArrayProducer(arrayType);
-            mh = buildVarargsArray(builder, producer, nargs);
-        } else {
-            @SuppressWarnings("unchecked")
-            Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
-            Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
-            MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
-            MethodHandle producer = ARRAY_IDENTITY;
-            mh = buildVarargsArray(builder, producer, nargs);
-        }
-        mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
-        assert(assertCorrectArity(mh, nargs));
-        if (nargs < cache.length)
-            cache[nargs] = mh;
-        return mh;
-    }
-
-    private static MethodHandle buildArrayProducer(Class<?> arrayType) {
-        Class<?> elemType = arrayType.getComponentType();
-        if (elemType.isPrimitive())
-            return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType));
-        else
-            return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType);
-    }
-
-    // List version of varargs maker.
-
-    private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
-    private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
-    private static List<Object> list() { return NO_ARGS_LIST; }
-    private static List<Object> list(Object a0)
-                { return makeList(a0); }
-    private static List<Object> list(Object a0, Object a1)
-                { return makeList(a0, a1); }
-    private static List<Object> list(Object a0, Object a1, Object a2)
-                { return makeList(a0, a1, a2); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
-                { return makeList(a0, a1, a2, a3); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
-                                     Object a4)
-                { return makeList(a0, a1, a2, a3, a4); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
-                                     Object a4, Object a5)
-                { return makeList(a0, a1, a2, a3, a4, a5); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
-                                     Object a4, Object a5, Object a6)
-                { return makeList(a0, a1, a2, a3, a4, a5, a6); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
-                                     Object a4, Object a5, Object a6, Object a7)
-                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
-                                     Object a4, Object a5, Object a6, Object a7,
-                                     Object a8)
-                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
-                                     Object a4, Object a5, Object a6, Object a7,
-                                     Object a8, Object a9)
-                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-    private static MethodHandle[] makeLists() {
-        ArrayList<MethodHandle> mhs = new ArrayList<>();
-        for (;;) {
-            MethodHandle mh = findCollector("list", mhs.size(), List.class);
-            if (mh == null)  break;
-            mhs.add(mh);
-        }
-        assert(mhs.size() == 11);  // current number of methods
-        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
-    }
-    private static final MethodHandle[] LISTS = makeLists();
-
-    /** Return a method handle that takes the indicated number of Object
-     *  arguments and returns a List.
-     */
-    public static MethodHandle varargsList(int nargs) {
-        MethodHandle mh = LISTS[nargs];
-        if (mh != null)  return mh;
-        mh = findCollector("list", nargs, List.class);
-        if (mh != null)  return LISTS[nargs] = mh;
-        return LISTS[nargs] = buildVarargsList(nargs);
-    }
-    private static MethodHandle buildVarargsList(int nargs) {
-        return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);
-    }
-
     // handy shared exception makers (they simplify the common case code)
     private static InternalError newInternalError(String message, Throwable cause) {
         return new InternalError(message, cause);