meth: remove MT.varargs attribute
authorjrose
Wed Feb 04 20:06:52 2009 -0800 (9 months ago)
changeset 161ee47858109c
parent 15d6ba74ad1000
child 17b935492d6b25
meth: remove MT.varargs attribute
meth.patch
--- a/meth.patch Thu Jan 29 13:54:01 2009 -0800
+++ b/meth.patch Wed Feb 04 20:06:52 2009 -0800
@@ -2156,8 +2156,8 @@ new file mode 100644
+
+ public static MethodHandle convertArguments(Access token,
+ MethodHandle target,
-+ MethodType newType,
-+ MethodType oldType,
++ MethodType newType, boolean newVarargs,
++ MethodType oldType, boolean oldVarargs,
+ String permutationOrNull) {
+ Access.check(token);
+ throw new UnsupportedOperationException("Not yet implemented");
@@ -2531,7 +2531,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/impl/java/dyn/util/MethodHandleInvoker.java
-@@ -0,0 +1,455 @@
+@@ -0,0 +1,454 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -2715,7 +2715,6 @@ new file mode 100644
+ for (int i = 0; i < len; i++)
+ if (approxType.parameterType(i) != Object.class)
+ return false;
-+ if (approxType.isVarArgs()) return false;
+ return true;
+ }
+
@@ -2858,7 +2857,7 @@ new file mode 100644
+
+ static MethodType approxType(MethodType exactType) {
+ int len = exactType.parameterCount();
-+ if (len > ARGUMENT_MAX || exactType.isVarArgs())
++ if (len > ARGUMENT_MAX)
+ throw new IllegalArgumentException("too many arguments for invoker: "+exactType);
+ // The JVM can insert casts and unboxing for us in a native adapter.
+ MethodType approxType = MethodType.makeGeneric(len);
@@ -4053,7 +4052,7 @@ new file mode 100644
+ */
+ public static final MethodType BOOTSTRAP_METHOD_TYPE
+ = MethodType.make(Object.class,
-+ CallSite.class, Object[].class).changeVarArgs(true);
++ CallSite.class, Object[].class);
+
+ private static MethodHandleInvoker bootstrapMethodInvoker;
+
@@ -4427,7 +4426,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/java/dyn/MethodHandles.java
-@@ -0,0 +1,940 @@
+@@ -0,0 +1,938 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -4993,7 +4992,7 @@ new file mode 100644
+ if (oldType.equals(newType))
+ return target;
+ return MethodHandleImpl.convertArguments(IMPL_TOKEN, target,
-+ newType, target.type(), null);
++ newType,false, target.type(), false, null);
+ }
+
+ /**
@@ -5026,7 +5025,7 @@ new file mode 100644
+ MethodHandle permuteArguments(MethodHandle target, MethodType newType, String permutation) {
+ MethodType oldType = target.type();
+ return MethodHandleImpl.convertArguments(IMPL_TOKEN, target,
-+ newType, target.type(),
++ newType,false, target.type(), false,
+ permutation);
+ }
+
@@ -5068,8 +5067,7 @@ new file mode 100644
+ int numSpread = (outargs - spreadPos);
+ if (spreadPos < 0 || numSpread < 0)
+ throw newIllegalArgumentException("wrong number of arguments");
-+ newType = newType.changeVarArgs(true);
-+ return MethodHandleImpl.convertArguments(IMPL_TOKEN, target, newType, oldType, null);
++ return MethodHandleImpl.convertArguments(IMPL_TOKEN, target, newType, true, oldType, false, null);
+ }
+
+ /**
@@ -5100,8 +5098,7 @@ new file mode 100644
+ int numCollect = (inargs - collectPos);
+ if (collectPos < 0 || numCollect < 0)
+ throw newIllegalArgumentException("wrong number of arguments");
-+ oldType = oldType.changeVarArgs(true);
-+ return MethodHandleImpl.convertArguments(IMPL_TOKEN, target, newType, oldType, null);
++ return MethodHandleImpl.convertArguments(IMPL_TOKEN, target, newType, false, oldType, true, null);
+ }
+
+ /**
@@ -5372,7 +5369,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/java/dyn/MethodType.java
-@@ -0,0 +1,579 @@
+@@ -0,0 +1,529 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -5414,7 +5411,7 @@ new file mode 100644
+ * The types (primitive, void, and reference) are represented by Class objects.
+ * All instances of <code>MethodType</code> are immutable.
+ * Two instances are completely interchangeable if they compare equal.
-+ * Equality depends exactly on the return and parameter types, plus the varargs bit.
++ * Equality depends exactly on the return and parameter types.
+ * <p>
+ * This type can be created only by factory methods, which manage interning.
+ *
@@ -5429,18 +5426,11 @@ new file mode 100644
+
+ private static final Access IMPL_TOKEN = Access.getToken();
+
-+ private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean varargs) {
++ private MethodType(Class<?> rtype, Class<?>[] ptypes) {
+ checkRtype(rtype);
+ checkPtypes(ptypes);
+ this.rtype = rtype;
+ this.ptypes = ptypes;
-+ if (!varargs) {
-+ this.form = MethodTypeForm.FAKE[0];
-+ } else {
-+ this.form = MethodTypeForm.FAKE[1];
-+ checkVarargs(ptypes);
-+ }
-+ assert(this.isVarArgs() == varargs);
+ }
+
+ private void checkRtype(Class<?> rtype) {
@@ -5453,10 +5443,6 @@ new file mode 100644
+ throw newIllegalArgumentException("void parameter: "+this);
+ }
+ }
-+ private void checkVarargs(Class<?>[] ptypes) {
-+ if (ptypes.length == 0 || !ptypes[ptypes.length-1].isArray())
-+ throw newIllegalArgumentException("not varargs: "+this);
-+ }
+
+ static final HashMap<MethodType,MethodType> internTable
+ = new HashMap<MethodType, MethodType>();
@@ -5468,31 +5454,17 @@ new file mode 100644
+ * @param ptypes the parameter types
+ * @return the interned method type with the given parts
+ * @throws NullPointerException if rtype or any ptype is null
-+ * @throws IllegalArgumentException if any of the ptypes is void,
++ * @throws IllegalArgumentException if any of the ptypes is void
+ */
+ public static
+ MethodType make(Class<?> rtype, Class<?>[] ptypes) {
-+ return makeImpl(rtype, ptypes, false, false);
-+ }
-+
-+ /** Find or create an instance of the given method type.
-+ * @param rtype the return type
-+ * @param ptypes the parameter types
-+ * @param varargs whether the method type will be varargs
-+ * @return the interned method type with the given parts
-+ * @throws NullPointerException if rtype or any ptype is null
-+ * @throws IllegalArgumentException if any of the ptypes is void,
-+ * or if varargs is true and the last parameter type is not an array
-+ */
-+ public static
-+ MethodType make(Class<?> rtype, Class<?>[] ptypes, boolean varargs) {
-+ return makeImpl(rtype, ptypes, varargs, false);
++ return makeImpl(rtype, ptypes, false);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}. */
+ public static
+ MethodType make(Class<?> rtype, List<Class<?>> ptypes) {
-+ return makeImpl(rtype, ptypes.toArray(NO_PTYPES), false, true);
++ return makeImpl(rtype, ptypes.toArray(NO_PTYPES), true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
@@ -5503,7 +5475,7 @@ new file mode 100644
+ Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
+ ptypes1[0] = ptype0;
+ System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
-+ return makeImpl(rtype, ptypes1, false, true);
++ return makeImpl(rtype, ptypes1, true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
@@ -5511,7 +5483,7 @@ new file mode 100644
+ */
+ public static
+ MethodType make(Class<?> rtype) {
-+ return makeImpl(rtype, NO_PTYPES, false, true);
++ return makeImpl(rtype, NO_PTYPES, true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
@@ -5519,7 +5491,7 @@ new file mode 100644
+ */
+ public static
+ MethodType make(Class<?> rtype, Class<?> ptype0) {
-+ return makeImpl(rtype, new Class<?>[]{ ptype0 }, false, true);
++ return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
@@ -5528,23 +5500,22 @@ new file mode 100644
+ */
+ public static
+ MethodType make(Class<?> rtype, MethodType ptypes) {
-+ return makeImpl(rtype, ptypes.ptypes, false, true);
++ return makeImpl(rtype, ptypes.ptypes, true);
+ }
+
+ /**
+ * Sole factory method to find or create an interned method type.
+ * @param rtype desired return type
+ * @param ptypes desired parameter types
-+ * @param varargs whether the method type will be varargs
+ * @param trusted whether the ptypes can be used without cloning
+ * @return the unique method type of the desired structure
+ */
+ static
-+ MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean varargs, boolean trusted) {
++ MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
+ if (ptypes == null || ptypes.length == 0) {
+ ptypes = NO_PTYPES; trusted = true;
+ }
-+ MethodType mt1 = new MethodType(rtype, ptypes, varargs);
++ MethodType mt1 = new MethodType(rtype, ptypes);
+ MethodType mt0;
+ synchronized (internTable) {
+ mt0 = internTable.get(mt1);
@@ -5553,12 +5524,11 @@ new file mode 100644
+ }
+ if (!trusted)
+ // defensively copy the array passed in by the user
-+ mt1 = new MethodType(rtype, ptypes.clone(), varargs);
++ mt1 = new MethodType(rtype, ptypes.clone());
+ // promote the object to the Real Thing, and reprobe
-+ mt1.form = MethodTypeForm.findForm(mt1, varargs);
++ mt1.form = MethodTypeForm.findForm(mt1);
+ if (mt1.form.erasedType == mt1)
+ MethodHandleImpl.init(IMPL_TOKEN, mt1);
-+ assert(mt1.isVarArgs() == varargs);
+ synchronized (internTable) {
+ mt0 = internTable.get(mt1);
+ if (mt0 != null)
@@ -5575,7 +5545,8 @@ new file mode 100644
+ * All parameters and the return type will be Object, except the final varargs parameter if any.
+ * @param objectArgCount number of parameters (excluding the varargs parameter if any)
+ * @param varargs whether there will be a varargs parameter
-+ * @return a totally generic method type, given only its count of parameters and varargs.
++ * @return a totally generic method type, given only its count of parameters and varargs
++ * @see #makeGeneric(int)
+ */
+ public static
+ MethodType makeGeneric(int objectArgCount, boolean varargs) {
@@ -5589,7 +5560,7 @@ new file mode 100644
+ Class<?>[] ptypes = new Class<?>[objectArgCount + ivarargs];
+ Arrays.fill(ptypes, Object.class);
+ if (ivarargs != 0) ptypes[objectArgCount] = Object[].class;
-+ mt = makeImpl(Object.class, ptypes, varargs, true);
++ mt = makeImpl(Object.class, ptypes, true);
+ if (ootIndex < objectOnlyTypes.length) {
+ objectOnlyTypes[ootIndex] = mt; // cache it here also!
+ }
@@ -5597,7 +5568,10 @@ new file mode 100644
+ }
+
+ /**
-+ * Convenience method for {@link #makeGeneric(int, boolean)}, defaulting {@code varargs} to false.
++ * All parameters and the return type will be Object.
++ * @param objectArgCount number of parameters
++ * @return a totally generic method type, given only its count of parameters
++ * @see #makeGeneric(int, boolean)
+ */
+ public static
+ MethodType makeGeneric(int objectArgCount) {
@@ -5613,7 +5587,7 @@ new file mode 100644
+ if (parameterType(num) == nptype) return this;
+ Class<?>[] nptypes = ptypes.clone();
+ nptypes[num] = nptype;
-+ return makeImpl(rtype, nptypes, isVarArgs(), true);
++ return makeImpl(rtype, nptypes, true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
@@ -5626,7 +5600,7 @@ new file mode 100644
+ Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+1);
+ System.arraycopy(nptypes, num, nptypes, num+1, len-num);
+ nptypes[num] = nptype;
-+ return makeImpl(rtype, nptypes, isVarArgs(), true);
++ return makeImpl(rtype, nptypes, true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
@@ -5642,7 +5616,7 @@ new file mode 100644
+ nptypes = Arrays.copyOfRange(ptypes, 0, len-1);
+ System.arraycopy(ptypes, num+1, nptypes, num, (len-1)-num);
+ }
-+ return makeImpl(rtype, nptypes, isVarArgs(), true);
++ return makeImpl(rtype, nptypes, true);
+ }
+
+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
@@ -5651,17 +5625,7 @@ new file mode 100644
+ */
+ public MethodType changeReturnType(Class<?> nrtype) {
+ if (returnType() == nrtype) return this;
-+ return makeImpl(nrtype, ptypes, isVarArgs(), true);
-+ }
-+
-+ /** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
-+ * @param varargs a new setting of the varargs flag
-+ * @return the same type, except with the varargs change
-+ * @throws IllegalArgumentException if varargs is true and the last parameter type is not an array
-+ */
-+ public MethodType changeVarArgs(boolean varargs) {
-+ if (isVarArgs() == varargs) return this;
-+ return makeImpl(rtype, ptypes, varargs, true);
++ return makeImpl(nrtype, ptypes, true);
+ }
+
+ /** Convenience method.
@@ -5762,10 +5726,6 @@ new file mode 100644
+ public Class<?> returnType() {
+ return rtype;
+ }
-+ /** @return whether this is a varargs type */
-+ public boolean isVarArgs() {
-+ return form.varargs;
-+ }
+
+ /**
+ * Convenience method to present the arguments as a list.
@@ -5786,8 +5746,7 @@ new file mode 100644
+ /**
+ * Compares the specified object with this type for equality.
+ * That is, it returns <tt>true</tt> if and only if the specified object
-+ * is also a method type with exactly the same parameters and return type,
-+ * and agree on their varargs flag.
++ * is also a method type with exactly the same parameters and return type.
+ * @param x object to compare
+ * @see Object#equals(Object)
+ */
@@ -5798,7 +5757,6 @@ new file mode 100644
+
+ private boolean equals(MethodType that) {
+ return this.rtype == that.rtype
-+ && this.isVarArgs() == that.isVarArgs()
+ && Arrays.equals(this.ptypes, that.ptypes);
+ }
+
@@ -5806,7 +5764,7 @@ new file mode 100644
+ * Returns the hash code value for this method type.
+ * It is defined to be the same as the hashcode of a List
+ * whose elements are the return type followed by the
-+ * parameter types, plus an additional void type if varargs is set.
++ * parameter types.
+ * @return the hash code value for this method type
+ * @see Object#hashCode()
+ * @see #equals(Object)
@@ -5817,8 +5775,6 @@ new file mode 100644
+ int hashCode = 31 + rtype.hashCode();
+ for (Class<?> ptype : ptypes)
+ hashCode = 31*hashCode + ptype.hashCode();
-+ if (isVarArgs())
-+ hashCode = 31*hashCode + void.class.hashCode();
+ return hashCode;
+ }
+
@@ -5826,8 +5782,6 @@ new file mode 100644
+ * The string representation of a method type is a
+ * parenthesis enclosed, comma separated list of type names,
+ * followed immediately by the return type.
-+ * The last argument type name is followed by "..."
-+ * if the type is vararags.
+ * <p>
+ * If a type name is array, it the base type followed
+ * by [], rather than the Class.getName of the array type.
@@ -5836,15 +5790,8 @@ new file mode 100644
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
-+ int vanum = isVarArgs() ? ptypes.length-1 : -1 ;
+ for (int i = 0; i < ptypes.length; i++) {
+ if (i > 0) sb.append(",");
-+ if (i == vanum) {
-+ putName(sb, ptypes[i].getComponentType());
-+ sb.append("...");
-+ break;
-+ }
-+ putName(sb, ptypes[i]);
+ }
+ sb.append(")");
+ putName(sb, rtype);
@@ -5938,7 +5885,7 @@ new file mode 100644
+ List<Class<?>> types = Signatures.parseMethod(bytecodeSignature, loader);
+ Class<?> rtype = types.remove(types.size() - 1);
+ Class<?>[] ptypes = types.toArray(NO_PTYPES);
-+ return makeImpl(rtype, ptypes, false, true);
++ return makeImpl(rtype, ptypes, true);
+ }
+
+ /**
@@ -5956,7 +5903,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/java/dyn/MethodTypeForm.java
-@@ -0,0 +1,270 @@
+@@ -0,0 +1,249 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -6003,7 +5950,6 @@ new file mode 100644
+ final int[] argToSlotTable, slotToArgTable;
+ final long argCounts; // packed slot & value counts
+ final long primCounts; // packed prim & double counts
-+ final boolean varargs; // is this a "..." type?
+ final int vmslots; // total number of parameter slots
+ final MethodType erasedType; // the canonical erasure
+ final MethodType wrappedType; // erasure, with primitives wrapped
@@ -6012,9 +5958,8 @@ new file mode 100644
+ return type.form;
+ }
+
-+ private MethodTypeForm(MethodType erase, boolean varargs) {
++ private MethodTypeForm(MethodType erase) {
+ this.erasedType = erase;
-+ this.varargs = varargs;
+ MethodType wt = canonType(erase, WRAP);
+ this.wrappedType = (wt == null) ? erase : wt;
+
@@ -6022,8 +5967,6 @@ new file mode 100644
+ int pslotCount = ptypeCount; // temp. estimate
+ int rtypeCount = 1; // temp. estimate
+ int rslotCount = 1; // temp. estimate
-+
-+ assert(varargs == (ptypeCount != 0 && erase.ptypes[ptypeCount-1].isArray()));
+
+ int[] argToSlotTab = null, slotToArgTab = null;
+
@@ -6103,19 +6046,6 @@ new file mode 100644
+ return (char)(packed >> ((3-word) * 16));
+ }
+
-+ // used only for bootstrapping:
-+ static final MethodTypeForm[] FAKE = {
-+ new MethodTypeForm(false), new MethodTypeForm(true)
-+ };
-+ // used only for making FAKE[]:
-+ private MethodTypeForm(boolean varargs) {
-+ this.varargs = varargs;
-+ primCounts = argCounts = -1;
-+ erasedType = wrappedType = null;
-+ vmslots = -1;
-+ argToSlotTable = slotToArgTable = null;
-+ }
-+
+ public int parameterCount() { // # outgoing values
+ return unpack(argCounts, 3);
+ }
@@ -6150,13 +6080,13 @@ new file mode 100644
+ return slotToArgTable[argSlot] - 1;
+ }
+
-+ static final int ERASE = 1, WRAP = 2, UNWRAP = 4, ARGS_ONLY = 8, KEEP_VARARG = 16;
-+
-+ static MethodTypeForm findForm(MethodType mt, boolean varargs) {
-+ MethodType erased = canonType(mt, ERASE | (varargs ? KEEP_VARARG : 0));
++ static final int ERASE = 1, WRAP = 2, UNWRAP = 4, ARGS_ONLY = 8;
++
++ static MethodTypeForm findForm(MethodType mt) {
++ MethodType erased = canonType(mt, ERASE);
+ if (erased == null) {
+ // It is already erased. Make a new MethodTypeForm.
-+ return new MethodTypeForm(mt, varargs);
++ return new MethodTypeForm(mt);
+ } else {
+ // Share the MethodTypeForm with the erased version.
+ return erased.form;
@@ -6179,7 +6109,7 @@ new file mode 100644
+ // Find the erased version of the method type:
+ if (rtc == null) rtc = mt.rtype;
+ if (ptc == null) ptc = mt.ptypes;
-+ return MethodType.makeImpl(rtc, ptc, mt.isVarArgs(), true);
++ return MethodType.makeImpl(rtc, ptc, true);
+ }
+
+ /** Canonicalize the given return or param type.
@@ -6215,10 +6145,6 @@ new file mode 100644
+ for (int imax = ts.length, i = 0; i < imax; i++) {
+ Class<?> c = canonType(ts[i], how);
+ if (c != null) {
-+ if ((how & KEEP_VARARG) != 0) {
-+ // if this is a final 'vararg', stop canonicalizing now
-+ if (i+1 == imax && ts[i].isArray()) break;
-+ }
+ if (cs == null)
+ cs = ts.clone();
+ cs[i] = c;