--- a/netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java Sat Jun 20 23:55:53 2009 -0700
+++ b/netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java Thu Jul 02 03:19:50 2009 -0700
@@ -40,6 +40,19 @@ import static org.junit.Assert.*;
* @author jrose
*/
public class MethodHandlesTest {
+ // How much output?
+ static int verbosity = 1;
+
+ // Set this true during development if you want to fast-forward to
+ // a particular new, non-working test. Tests which are known to
+ // work (or have recently worked) test this flag and return on true.
+ static boolean CAN_SKIP_WORKING = false;
+ //static { CAN_SKIP_WORKING = true; }
+
+ // Set true to test more calls. If false, some tests are just
+ // lookups, without exercising the actual method handle.
+ static boolean DO_MORE_CALLS = false;
+
@Test
public void testFirst() throws Throwable {
@@ -72,8 +85,9 @@ public class MethodHandlesTest {
}
@Test @Ignore("should not insert arguments beyond MethodHandlePushLimit")
public void testFail_6() throws Throwable {
- testInsertArguments(0, 0, 4);
- }
+ testInsertArguments(0, 0, MAX_ARG_INCREASE+1);
+ }
+ static final int MAX_ARG_INCREASE = 3;
public MethodHandlesTest() {
}
@@ -283,19 +297,6 @@ public class MethodHandlesTest {
return ACCESS_CASES[2]; // PACKAGE but not PUBLIC
}
}
-
- // How much output?
- static int verbosity = 1;
-
- // Set this true during development if you want to fast-forward to
- // a particular new, non-working test. Tests which are known to
- // work (or have recently worked) test this flag and return on true.
- static boolean CAN_SKIP_WORKING = false;
- //static { CAN_SKIP_WORKING = true; }
-
- // Set true to test more calls. If false, some tests are just
- // lookups, without exercising the actual method handle.
- static boolean DO_MORE_CALLS = false;
@Test
public void testFindStatic() throws Throwable {
@@ -727,38 +728,118 @@ public class MethodHandlesTest {
public void testPermuteArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("permuteArguments");
- for (int inargs = 1; inargs <= 4; inargs++) {
- Object[] args = randomArgs(inargs, Integer.class);
+ testPermuteArguments(4, Integer.class, 2, String.class, 0);
+ //testPermuteArguments(6, Integer.class, 0, null, 30);
+ //testPermuteArguments(4, Integer.class, 1, int.class, 6);
+ }
+ public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
+ if (verbosity >= 1)
+ System.out.println("permuteArguments "+max+"*"+type1.getName()
+ +(t2c==0?"":"/"+t2c+"*"+type2.getName())
+ +(dilution > 0 ? " with dilution "+dilution : ""));
+ int t2pos = t2c == 0 ? 0 : 1;
+ for (int inargs = t2pos+1; inargs <= max; inargs++) {
+ Class<?>[] types = new Class<?>[inargs];
+ Arrays.fill(types, type1);
+ if (t2c != 0) {
+ // Fill in a middle range with type2:
+ Arrays.fill(types, t2pos, Math.min(t2pos+t2c, inargs), type2);
+ }
+ Object[] args = randomArgs(types);
int numcases = 1;
- for (int outargs = 0; outargs <= 4; outargs++) {
+ for (int outargs = 0; outargs <= max; outargs++) {
+ if (outargs - inargs >= MAX_ARG_INCREASE) continue;
int[] reorder = new int[outargs];
- for (int cas = 0; cas < numcases; cas++) {
+ int casStep = dilution + 1;
+ // Avoid some common factors:
+ while ((casStep > 2 && casStep % 2 == 0 && inargs % 2 == 0) ||
+ (casStep > 3 && casStep % 3 == 0 && inargs % 3 == 0))
+ casStep++;
+ for (int cas = 0; cas < numcases; cas += casStep) {
for (int i = 0, c = cas; i < outargs; i++) {
reorder[i] = c % inargs;
c /= inargs;
}
- testPermuteArguments(args, reorder);
+ testPermuteArguments(args, types, reorder);
}
numcases *= inargs;
- }
- }
- }
-
- void testPermuteArguments(Object[] args, int[] reorder) throws Throwable {
+ if (dilution > 10 && outargs >= 4) {
+ // Do some special patterns, which we probably missed.
+ // Replication of a single argument or argument pair.
+ for (int i = 0; i < inargs; i++) {
+ Arrays.fill(reorder, i);
+ testPermuteArguments(args, types, reorder);
+ for (int d = 1; d <= 2; d++) {
+ if (i + d >= inargs) continue;
+ for (int j = 1; j < outargs; j += 2)
+ reorder[j] += 1;
+ testPermuteArguments(args, types, reorder);
+ testPermuteArguments(args, types, reverse(reorder));
+ }
+ }
+ // Repetition of a sequence of 3 or more arguments.
+ for (int i = 1; i < inargs; i++) {
+ for (int len = 3; len <= inargs; len++) {
+ for (int j = 0; j < outargs; j++)
+ reorder[j] = (i + (j % len)) % inargs;
+ testPermuteArguments(args, types, reorder);
+ testPermuteArguments(args, types, reverse(reorder));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static int[] reverse(int[] reorder) {
+ reorder = reorder.clone();
+ for (int i = 0, imax = reorder.length / 2; i < imax; i++) {
+ int j = reorder.length - 1 - i;
+ int tem = reorder[i];
+ reorder[i] = reorder[j];
+ reorder[j] = tem;
+ }
+ return reorder;
+ }
+
+ void testPermuteArguments(Object[] args, Class<?>[] types, int[] reorder) throws Throwable {
countTest();
+ if (args == null && types == null) {
+ int max = 0;
+ for (int j : reorder) {
+ if (max < j) max = j;
+ }
+ args = randomArgs(max+1, Integer.class);
+ }
+ if (args == null) {
+ args = randomArgs(types);
+ }
+ if (types == null) {
+ types = new Class<?>[args.length];
+ for (int i = 0; i < args.length; i++)
+ types[i] = args[i].getClass();
+ }
int inargs = args.length, outargs = reorder.length;
+ assert(inargs == types.length);
if (verbosity >= 2)
System.out.println("permuteArguments "+Arrays.toString(reorder));
Object[] permArgs = new Object[outargs];
- for (int i = 0; i < outargs; i++)
+ Class<?>[] permTypes = new Class<?>[outargs];
+ for (int i = 0; i < outargs; i++) {
permArgs[i] = args[reorder[i]];
+ permTypes[i] = types[reorder[i]];
+ }
if (verbosity >= 3) {
- System.out.println("in args: "+Arrays.asList(args));
- System.out.println("out args: "+Arrays.asList(permArgs));
- }
- MethodHandle target = ValueConversions.varargsList(outargs);
- target = MethodHandles.permuteArguments(target, MethodType.makeGeneric(inargs), reorder);
- Object result = MethodHandles.invoke(target, args);
+ System.out.println("in args: "+Arrays.asList(args));
+ System.out.println("out args: "+Arrays.asList(permArgs));
+ System.out.println("in types: "+Arrays.asList(types));
+ System.out.println("out types: "+Arrays.asList(permTypes));
+ }
+ MethodType inType = MethodType.make(Object.class, types);
+ MethodType outType = MethodType.make(Object.class, permTypes);
+ MethodHandle target = MethodHandles.convertArguments(ValueConversions.varargsList(outargs), outType);
+ MethodHandle newTarget = MethodHandles.permuteArguments(target, inType, reorder);
+ Object result = MethodHandles.invoke(newTarget, args);
Object expected = Arrays.asList(permArgs);
assertEquals(expected, result);
}
@@ -869,7 +950,7 @@ public class MethodHandlesTest {
startTest("insertArguments");
for (int nargs = 0; nargs <= 4; nargs++) {
for (int ins = 0; ins <= 4; ins++) {
- if (ins >= 4) continue; // FIXME Fail_6
+ if (ins > MAX_ARG_INCREASE) continue; // FIXME Fail_6
for (int pos = 0; pos <= nargs; pos++) {
testInsertArguments(nargs, pos, ins);
}