jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java
changeset 9859 47e26ad535c4
parent 9752 88ab34b6da6d
child 10082 761643c9bebd
--- a/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Tue Jun 07 14:01:12 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Tue Jun 14 22:47:09 2011 -0700
@@ -405,13 +405,13 @@
                 insertStackMove(stackMove)
                 );
     }
-    private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
+    private static long makeSwapConv(int convOp, int srcArg, byte srcType, int destSlot, byte destType) {
         // more complex argument motion, requiring two slots to specify
         assert(convOp == OP_SWAP_ARGS || convOp == OP_ROT_ARGS);
         return ((long) srcArg << 32 |
                 (long) convOp << CONV_OP_SHIFT |
-                (int)  type   << CONV_SRC_TYPE_SHIFT |
-                (int)  type   << CONV_DEST_TYPE_SHIFT |
+                (int)  srcType << CONV_SRC_TYPE_SHIFT |
+                (int)  destType << CONV_DEST_TYPE_SHIFT |
                 (int)  destSlot << CONV_VMINFO_SHIFT
                 );
     }
@@ -943,24 +943,27 @@
         if (type2size(newType.parameterType(swapArg1)) !=
             type2size(newType.parameterType(swapArg2))) {
             // turn a swap into a pair of rotates:
-            // [x a b c y] => [a b c y x] => [y a b c x]
+            // [x a b c y] rot2(-1,argc=5) => [a b c y x] rot1(+1,argc=4) => target[y a b c x]
             int argc = swapArg2 - swapArg1 + 1;
             final int ROT = 1;
             ArrayList<Class<?>> rot1Params = new ArrayList<Class<?>>(target.type().parameterList());
             Collections.rotate(rot1Params.subList(swapArg1, swapArg1 + argc), -ROT);
             MethodType rot1Type = MethodType.methodType(target.type().returnType(), rot1Params);
             MethodHandle rot1 = makeRotateArguments(rot1Type, target, swapArg1, argc, +ROT);
+            assert(rot1 != null);
             if (argc == 2)  return rot1;
             MethodHandle rot2 = makeRotateArguments(newType, rot1, swapArg1, argc-1, -ROT);
+            assert(rot2 != null);
             return rot2;
         }
         if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
             return null;
-        Class<?> swapType = newType.parameterType(swapArg1);
+        Class<?> type1 = newType.parameterType(swapArg1);
+        Class<?> type2 = newType.parameterType(swapArg2);
         // in  arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
         // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
         int swapSlot2  = newType.parameterSlotDepth(swapArg2 + 1);
-        long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(swapType), swapSlot2);
+        long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(type1), swapSlot2, basicType(type2));
         return new AdapterMethodHandle(target, newType, conv);
     }
 
@@ -1029,16 +1032,16 @@
         assert(MAX_ARG_ROTATION == 1);
         int srcArg, dstArg;
         int dstSlot;
-        byte basicType;
-        if (chunk2Slots <= chunk1Slots) {
+        int moveChunk;
+        if (rotateBy == 1) {
             // Rotate right/down N (rotateBy = +N, N small, c2 small):
             // in  arglist: [0: ...keep1 | arg1: c1...  | limit-N: c2 | limit: keep2... ]
             // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1...   | limit: keep2... ]
             srcArg = limit-1;
             dstArg = firstArg;
-            dstSlot = depth0 - chunk2Slots;
-            basicType = basicType(newType.parameterType(srcArg));
-            assert(chunk2Slots == type2size(basicType));
+            //dstSlot = depth0 - chunk2Slots;  //chunk2Slots is not relevant
+            dstSlot = depth0 + MethodHandleNatives.OP_ROT_ARGS_DOWN_LIMIT_BIAS;
+            moveChunk = chunk2Slots;
         } else {
             // Rotate left/up N (rotateBy = -N, N small, c1 small):
             // in  arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2...   | limit: keep2... ]
@@ -1046,10 +1049,12 @@
             srcArg = firstArg;
             dstArg = limit-1;
             dstSlot = depth2;
-            basicType = basicType(newType.parameterType(srcArg));
-            assert(chunk1Slots == type2size(basicType));
+            moveChunk = chunk1Slots;
         }
-        long conv = makeSwapConv(OP_ROT_ARGS, srcArg, basicType, dstSlot);
+        byte srcType = basicType(newType.parameterType(srcArg));
+        byte dstType = basicType(newType.parameterType(dstArg));
+        assert(moveChunk == type2size(srcType));
+        long conv = makeSwapConv(OP_ROT_ARGS, srcArg, srcType, dstSlot, dstType);
         return new AdapterMethodHandle(target, newType, conv);
     }