indy: pass unit tests in debug build with +VerifyMethodHandles
authorjrose
Sat Jun 20 23:58:12 2009 -0700 (9 months ago)
changeset 488b29cb752abb
parent 47006368c1d475
child 49b0513547ea0b
indy: pass unit tests in debug build with +VerifyMethodHandles
indy.patch
--- a/indy.patch Fri Jun 19 03:39:09 2009 -0700
+++ b/indy.patch Sat Jun 20 23:58:12 2009 -0700
@@ -1935,10 +1935,14 @@ diff --git a/src/share/classes/sun/dyn/A
diff --git a/src/share/classes/sun/dyn/AdapterMethodHandle.java b/src/share/classes/sun/dyn/AdapterMethodHandle.java
--- a/src/share/classes/sun/dyn/AdapterMethodHandle.java
+++ b/src/share/classes/sun/dyn/AdapterMethodHandle.java
-@@ -305,21 +305,33 @@
- return (type == T_FLOAT || type == T_DOUBLE) ? 2 : 1;
- }
-
+@@ -302,7 +302,19 @@
+ */
+ private static int type2size(int type) {
+ assert(type >= T_BOOLEAN && type <= T_OBJECT);
+- return (type == T_FLOAT || type == T_DOUBLE) ? 2 : 1;
++ return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
++ }
++
+ /** The given stackMove is the number of slots pushed.
+ * It might be negative. Scale it (multiply) by the
+ * VM's notion of how an address changes with a push,
@@ -1949,10 +1953,10 @@ diff --git a/src/share/classes/sun/dyn/A
+ // following variable must be long to avoid sign extension after '<<'
+ long spChange = stackMove * MethodHandleNatives.JVM_STACK_MOVE_UNIT;
+ return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
-+ }
-+
+ }
+
/** Construct an adapter conversion descriptor for a single-argument conversion. */
- private static long makeConv(int convOp, int argnum, int src, int dest) {
+@@ -310,16 +322,16 @@
assert(src == (src & 0xF));
assert(dest == (dest & 0xF));
assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
@@ -1991,8 +1995,9 @@ diff --git a/src/share/classes/sun/dyn/A
);
}
private static long makeConv(int convOp) {
- assert(convOp == OP_RETYPE_ONLY);
+- assert(convOp == OP_RETYPE_ONLY);
- return (long) convOp << CONV_OP_SHIFT; // stackMove, src, dst, argnum all zero
++ assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
+ return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT); // stackMove, src, dst all zero
}
private static int convCode(long conv) {
@@ -2033,8 +2038,28 @@ diff --git a/src/share/classes/sun/dyn/A
if ((!raw
? VerifyType.canPassUnchecked(src, dest)
: VerifyType.canPassRaw(src, dest)
-@@ -437,7 +449,7 @@
- if (!convOpSupported(OP_RETYPE_ONLY)) return false;
+@@ -422,7 +434,7 @@
+
+ /** Can a retyping adapter (alone) validly convert the target to newType? */
+ public static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
+- return canRetypeOnly(newType, targetType, false);
++ return canRetype(newType, targetType, false);
+ }
+ /** Can a retyping adapter (alone) convert the target to newType?
+ * It is allowed to widen subword types and void to int, to make bitwise
+@@ -430,14 +442,14 @@
+ * reference conversions on return. This last feature requires that the
+ * caller be trusted, and perform explicit cast conversions on return values.
+ */
+- static boolean canRawRetypeOnly(MethodType newType, MethodType targetType) {
+- return canRetypeOnly(newType, targetType, true);
++ public static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
++ return canRetype(newType, targetType, true);
+ }
+- static boolean canRetypeOnly(MethodType newType, MethodType targetType, boolean raw) {
+- if (!convOpSupported(OP_RETYPE_ONLY)) return false;
++ static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
++ if (!convOpSupported(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY)) return false;
int diff = diffTypes(newType, targetType, raw);
// %%% This assert is too strong. Factor diff into VerifyType and reconcile.
- assert((diff == 0) == VerifyType.isNullConversion(newType, targetType));
@@ -2042,17 +2067,34 @@ diff --git a/src/share/classes/sun/dyn/A
return diff == 0;
}
-@@ -456,7 +468,9 @@
- static MethodHandle makeRetypeOnly(Access token,
+@@ -447,19 +459,21 @@
+ */
+ public static MethodHandle makeRetypeOnly(Access token,
+ MethodType newType, MethodHandle target) {
+- return makeRetypeOnly(token, newType, target, false);
++ return makeRetype(token, newType, target, false);
+ }
+- public static MethodHandle makeRawRetypeOnly(Access token,
++ public static MethodHandle makeRetypeRaw(Access token,
+ MethodType newType, MethodHandle target) {
+- return makeRetypeOnly(token, newType, target, true);
++ return makeRetype(token, newType, target, true);
+ }
+- static MethodHandle makeRetypeOnly(Access token,
++ static MethodHandle makeRetype(Access token,
MethodType newType, MethodHandle target, boolean raw) {
Access.check(token);
- if (!canRetypeOnly(newType, target.type(), raw))
+ MethodType oldType = target.type();
+ if (oldType == newType) return target;
-+ if (!canRetypeOnly(newType, oldType, raw))
++ if (!canRetype(newType, oldType, raw))
return null;
// TO DO: clone the target guy, whatever he is, with new type.
- return new AdapterMethodHandle(target, newType, makeConv(OP_RETYPE_ONLY));
+- return new AdapterMethodHandle(target, newType, makeConv(OP_RETYPE_ONLY));
++ return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
+ }
+
+ /** Can a checkcast adapter validly convert the target to newType?
@@ -492,7 +506,7 @@
Access.check(token);
if (!canCheckCast(newType, target.type(), arg, castType))
@@ -7235,6 +7277,15 @@ diff --git a/src/share/classes/sun/dyn/F
* @author jrose
*/
class FromGeneric {
+@@ -146,7 +143,7 @@
+ if (fixArgs == null)
+ throw new InternalError("bad fixArgs");
+ // reinterpret the calling sequence as raw:
+- MethodHandle retyper = AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN,
++ MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN,
+ Invokers.invokerType(internalType), fixArgs);
+ if (retyper == null)
+ throw new InternalError("bad retyper");
@@ -226,7 +223,10 @@
// Produce an instance configured as a prototype.
return ctor.newInstance(entryPoint);
@@ -8191,7 +8242,7 @@ diff --git a/src/share/classes/sun/dyn/M
+ MethodHandle throwException(Access token, MethodType type) {
Access.check(token);
- throw new UnsupportedOperationException("Not yet implemented");
-+ return AdapterMethodHandle.makeRetypeOnly(token, type, THROW_EXCEPTION, true);
++ return AdapterMethodHandle.makeRetypeRaw(token, type, THROW_EXCEPTION);
}
- protected static String basicToString(MethodHandle target) {
@@ -8258,7 +8309,49 @@ diff --git a/src/share/classes/sun/dyn/M
static final int
ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
-@@ -216,6 +215,7 @@
+@@ -178,19 +177,20 @@
+ */
+ static final int
+ OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
+- OP_CHECK_CAST = 0x1, // ref-to-ref conversion; requires a Class argument
+- OP_PRIM_TO_PRIM = 0x2, // converts from one primitive to another
+- OP_REF_TO_PRIM = 0x3, // unboxes a wrapper to produce a primitive
+- OP_PRIM_TO_REF = 0x4, // boxes a primitive into a wrapper (NYI)
+- OP_SWAP_ARGS = 0x5, // swap arguments (vminfo is 2nd arg)
+- OP_ROT_ARGS = 0x6, // rotate arguments (vminfo is displaced arg)
+- OP_DUP_ARGS = 0x7, // duplicates one or more arguments (at TOS)
+- OP_DROP_ARGS = 0x8, // remove one or more argument slots
+- OP_COLLECT_ARGS = 0x9, // combine one or more arguments into a varargs (NYI)
+- OP_SPREAD_ARGS = 0xA, // expand in place a varargs array (of known size)
+- OP_FLYBY = 0xB, // operate first on reified argument list (NYI)
+- OP_RICOCHET = 0xC, // run an adapter chain on the return value (NYI)
+- CONV_OP_LIMIT = 0xD; // limit of CONV_OP enumeration
++ OP_RETYPE_RAW = 0x1, // no argument changes; straight retype
++ OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument
++ OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another
++ OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive
++ OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper (NYI)
++ OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg)
++ OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg)
++ OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS)
++ OP_DROP_ARGS = 0x9, // remove one or more argument slots
++ OP_COLLECT_ARGS = 0xA, // combine one or more arguments into a varargs (NYI)
++ OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size)
++ OP_FLYBY = 0xC, // operate first on reified argument list (NYI)
++ OP_RICOCHET = 0xD, // run an adapter chain on the return value (NYI)
++ CONV_OP_LIMIT = 0xE; // limit of CONV_OP enumeration
+ /** Shift and mask values for decoding the AMH.conversion field.
+ * These numbers are shared with the JVM for creating AMHs.
+ */
+@@ -209,6 +209,7 @@
+ // TODO: The following expression should be replaced by
+ // a JVM query.
+ ((1<<OP_RETYPE_ONLY)
++ |(1<<OP_RETYPE_RAW)
+ |(1<<OP_CHECK_CAST)
+ |(1<<OP_PRIM_TO_PRIM)
+ |(1<<OP_REF_TO_PRIM)
+@@ -216,6 +217,7 @@
|(1<<OP_ROT_ARGS)
|(1<<OP_DUP_ARGS)
|(1<<OP_DROP_ARGS)
@@ -9000,7 +9093,7 @@ diff --git a/src/share/classes/sun/dyn/T
* that implement members of the erasure-family of the given erased type.
*/
private ToGeneric(MethodType entryType) {
-@@ -111,19 +111,38 @@
+@@ -111,30 +111,48 @@
// primitive arguments according to their "raw" types int/long
MethodType intsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsInts();
ad = findAdapter(rawEntryTypeInit = intsAtEnd);
@@ -9041,8 +9134,11 @@ diff --git a/src/share/classes/sun/dyn/T
- MethodHandle rawEntryPoint = ad.prototypeEntryPoint();
MethodType tepType = entryType.insertParameterType(0, ad.getClass());
this.entryPoint =
- AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, rawEntryPoint);
-@@ -133,8 +152,7 @@
+- AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, rawEntryPoint);
++ AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, rawEntryPoint);
+ if (this.entryPoint == null)
+ throw new UnsupportedOperationException("cannot retype to "+entryType
+ +" from "+rawEntryPoint.type().dropParameterType(0));
this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
this.rawEntryType = rawEntryTypeInit;
this.adapter = ad;
@@ -9063,6 +9159,15 @@ diff --git a/src/share/classes/sun/dyn/T
}
if (filteredInvoker == null) return invoker;
return AdapterMethodHandle.makeRetypeOnly(Access.TOKEN, invoker.type(), filteredInvoker);
+@@ -211,7 +229,7 @@
+ // retype erased reference arguments (the cast makes it safe to do this)
+ MethodType tepType = type.insertParameterType(0, adapter.getClass());
+ MethodHandle typedEntryPoint =
+- AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, entryPoint);
++ AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, entryPoint);
+ return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
+ }
+
@@ -283,7 +301,10 @@
try {
return ctor.newInstance(entryPoint);
@@ -10145,7 +10250,7 @@ diff --git a/src/share/classes/sun/dyn/u
/// Constant functions
static void ignore(Object x) {
-@@ -543,7 +579,7 @@
+@@ -543,10 +579,10 @@
else if (VerifyType.isNullType(type))
mh = ALWAYS_NULL;
else
@@ -10153,7 +10258,11 @@ diff --git a/src/share/classes/sun/dyn/u
+ mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
if (exact) {
MethodType xmt = MethodType.make(type, Object.class);
- mh = AdapterMethodHandle.makeRawRetypeOnly(IMPL_TOKEN, xmt, mh);
+- mh = AdapterMethodHandle.makeRawRetypeOnly(IMPL_TOKEN, xmt, mh);
++ mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
+ }
+ if (cache != null)
+ cache.put(wrap, mh);
@@ -560,4 +596,127 @@
private static MethodHandle retype(MethodType type, MethodHandle mh) {
return AdapterMethodHandle.makeRetypeOnly(IMPL_TOKEN, type, mh);