changeset 22:2d71974f86ca

meth: more permutation tests
author jrose
date Thu, 02 Jul 2009 03:19:50 -0700
parents 0bef39e3540b
children 4a09278b5c95
files netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java
diffstat 1 files changed, 108 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
  * @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 @@
     }
     @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() {
     }
@@ -284,19 +298,6 @@
         }
     }
 
-    // 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 {
         if (CAN_SKIP_WORKING)  return;
@@ -727,38 +728,118 @@
     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;
+                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));
+                        }
+                    }
+                }
             }
         }
     }
 
-    void testPermuteArguments(Object[] args, int[] reorder) throws Throwable {
+    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));
+            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));
         }
-        MethodHandle target = ValueConversions.varargsList(outargs);
-        target = MethodHandles.permuteArguments(target, MethodType.makeGeneric(inargs), reorder);
-        Object result = MethodHandles.invoke(target, args);
+        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 @@
         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);
                 }