Snap for 4517567 from 11b61a49725c31291a17adb09b804ce5c7de4ef8 to pi-release

Change-Id: If2fcf70d6d734b8063cd9be1984f90cd1be0fc0b
diff --git a/dx/src/com/android/dx/dex/code/RopTranslator.java b/dx/src/com/android/dx/dex/code/RopTranslator.java
index 3630740..8375f9e 100644
--- a/dx/src/com/android/dx/dex/code/RopTranslator.java
+++ b/dx/src/com/android/dx/dex/code/RopTranslator.java
@@ -705,7 +705,7 @@
 
             RegisterSpecList regs = insn.getSources();
             Constant[] constants = new Constant[] {
-                insn.getInvokeMethod(),
+                insn.getPolymorphicMethod(),
                 insn.getCallSiteProto()
                 };
             DalvInsn di = new MultiCstInsn(opcode, pos, regs, constants);
diff --git a/dx/src/com/android/dx/rop/code/InvokePolymorphicInsn.java b/dx/src/com/android/dx/rop/code/InvokePolymorphicInsn.java
index e5def1d..ca5a3b8 100644
--- a/dx/src/com/android/dx/rop/code/InvokePolymorphicInsn.java
+++ b/dx/src/com/android/dx/rop/code/InvokePolymorphicInsn.java
@@ -28,9 +28,18 @@
  * multiple constants.
  */
 public class InvokePolymorphicInsn extends Insn {
-    private static final CstString INVOKE_DESCRIPTOR =
+    /** Default descriptor for signature polymorphic methods. */
+    private static final CstString DEFAULT_DESCRIPTOR =
             new CstString("([Ljava/lang/Object;)Ljava/lang/Object;");
 
+    /** Descriptor for VarHandle set methods. */
+    private static final CstString VARHANDLE_SET_DESCRIPTOR =
+            new CstString("([Ljava/lang/Object;)V");
+
+    /** Descriptor for VarHandle compare-and-set methods. */
+    private static final CstString VARHANDLE_COMPARE_AND_SET_DESCRIPTOR =
+            new CstString("([Ljava/lang/Object;)Z");
+
     /** {@code non-null;} list of exceptions caught */
     private final TypeList catches;
 
@@ -42,10 +51,9 @@
     private final CstMethodRef callSiteMethod;
 
     /**
-     * {@code non-null;} method to invoke, either {@code java.lang.invoke.MethodHandle.invoke} or
-     * {@code java.lang.invoke.MethodHandle.invokeExact}.
+     * {@code non-null;} signature polymorphic method.
      */
-    private final CstMethodRef invokeMethod;
+    private final CstMethodRef polymorphicMethod;
 
     /**
      * {@code non-null;} the call site prototype.
@@ -82,7 +90,7 @@
         }
 
         this.callSiteMethod = callSiteMethod;
-        this.invokeMethod = makeInvokeMethod(callSiteMethod);
+        this.polymorphicMethod = makePolymorphicMethod(callSiteMethod);
         this.callSiteProto = makeCallSiteProto(callSiteMethod);
     }
 
@@ -137,8 +145,8 @@
      *
      * @return {@code non-null;} method reference to be invoked
      */
-    public CstMethodRef getInvokeMethod() {
-        return invokeMethod;
+    public CstMethodRef getPolymorphicMethod() {
+        return polymorphicMethod;
     }
 
     /**
@@ -155,15 +163,74 @@
     /** {@inheritDoc} */
     @Override
     public String getInlineString() {
-        return getInvokeMethod().toString() + " " +
+        return getPolymorphicMethod().toString() + " " +
             getCallSiteProto().toString() + " " +
             ThrowingInsn.toCatchString(catches);
     }
 
-    private static CstMethodRef makeInvokeMethod(final CstMethodRef callSiteMethod) {
-        // The name is either invoke or invokeExact. The INVOKE_DESCRIPTOR is fixed.
-        CstNat cstNat = new CstNat(callSiteMethod.getNat().getName(), INVOKE_DESCRIPTOR);
-        return new CstMethodRef(callSiteMethod.getDefiningClass(), cstNat);
+    private static CstMethodRef makePolymorphicMethod(final CstMethodRef callSiteMethod) {
+        CstType definingClass= callSiteMethod.getDefiningClass();
+        CstString cstMethodName = callSiteMethod.getNat().getName();
+        String methodName = callSiteMethod.getNat().getName().getString();
+
+        if (definingClass.equals(CstType.METHOD_HANDLE)) {
+            if (methodName.equals("invoke") || methodName.equals("invokeExact")) {
+                CstNat cstNat = new CstNat(cstMethodName, DEFAULT_DESCRIPTOR);
+                return new CstMethodRef(definingClass, cstNat);
+            }
+        }
+
+        if (definingClass.equals(CstType.VAR_HANDLE)) {
+            switch (methodName) {
+                case "compareAndExchange":
+                case "compareAndExchangeAcquire":
+                case "compareAndExchangeRelease":
+                case "get":
+                case "getAcquire":
+                case "getAndAdd":
+                case "getAndAddAcquire":
+                case "getAndAddRelease":
+                case "getAndBitwiseAnd":
+                case "getAndBitwiseAndAcquire":
+                case "getAndBitwiseAndRelease":
+                case "getAndBitwiseOr":
+                case "getAndBitwiseOrAcquire":
+                case "getAndBitwiseOrRelease":
+                case "getAndBitwiseXor":
+                case "getAndBitwiseXorAcquire":
+                case "getAndBitwiseXorRelease":
+                case "getAndSet":
+                case "getAndSetAcquire":
+                case "getAndSetRelease":
+                case "getOpaque":
+                case "getVolatile":
+                {
+                    CstNat cstNat = new CstNat(cstMethodName, DEFAULT_DESCRIPTOR);
+                    return new CstMethodRef(definingClass, cstNat);
+                }
+                case "set":
+                case "setOpaque":
+                case "setRelease":
+                case "setVolatile":
+                {
+                    CstNat cstNat = new CstNat(cstMethodName, VARHANDLE_SET_DESCRIPTOR);
+                    return new CstMethodRef(definingClass, cstNat);
+                }
+                case "compareAndSet":
+                case "weakCompareAndSet":
+                case "weakCompareAndSetAcquire":
+                case "weakCompareAndSetPlain":
+                case "weakCompareAndSetRelease":
+                {
+                    CstNat cstNat = new CstNat(cstMethodName, VARHANDLE_COMPARE_AND_SET_DESCRIPTOR);
+                    return new CstMethodRef(definingClass, cstNat);
+                }
+                default:
+                    break;
+            }
+        }
+        throw new IllegalArgumentException("Unknown signature polymorphic method: " +
+                                           callSiteMethod.toHuman());
     }
 
     private static CstProtoRef makeCallSiteProto(final CstMethodRef callSiteMethod) {
diff --git a/dx/tests/141-invoke-polymorphic-varhandles/expected.txt b/dx/tests/141-invoke-polymorphic-varhandles/expected.txt
index 7488fb7..12d3a9e 100644
--- a/dx/tests/141-invoke-polymorphic-varhandles/expected.txt
+++ b/dx/tests/141-invoke-polymorphic-varhandles/expected.txt
@@ -23,9 +23,9 @@
 java.lang.invoke.VarHandle.compareAndExchangeRelease:(LVarHandleDexTest;ZZ)V
 java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
 java.lang.invoke.VarHandle.compareAndExchangeRelease:(LVarHandleDexTest;ZZ)Z
-java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.compareAndSet:(LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
 java.lang.invoke.VarHandle.compareAndSet:(LVarHandleDexTest;ZZ)Z
+java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z
 java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
 java.lang.invoke.VarHandle.get:(LVarHandleDexTest;)Ljava/lang/Float;
 java.lang.invoke.VarHandle.get:([Ljava/lang/Object;)Ljava/lang/Object;
@@ -156,37 +156,37 @@
 java.lang.invoke.VarHandle.getVolatile:(LVarHandleDexTest;)V
 java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/String;I)V
 java.lang.invoke.VarHandle.getVolatile:(LVarHandleDexTest;)Z
-java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.set:(LVarHandleDexTest;Ljava/lang/Float;)V
 java.lang.invoke.VarHandle.set:(LVarHandleDexTest;Z)V
+java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)V
 java.lang.invoke.VarHandle.set:([Ljava/lang/String;ILjava/lang/String;)V
-java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.setOpaque:(LVarHandleDexTest;Ljava/lang/Float;)V
 java.lang.invoke.VarHandle.setOpaque:(LVarHandleDexTest;Z)V
+java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)V
 java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/String;ILjava/lang/String;)V
-java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.setRelease:(LVarHandleDexTest;Ljava/lang/Float;)V
 java.lang.invoke.VarHandle.setRelease:(LVarHandleDexTest;Z)V
+java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)V
 java.lang.invoke.VarHandle.setRelease:([Ljava/lang/String;ILjava/lang/String;)V
-java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.setVolatile:(LVarHandleDexTest;Ljava/lang/Float;)V
 java.lang.invoke.VarHandle.setVolatile:(LVarHandleDexTest;Z)V
+java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)V
 java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/String;ILjava/lang/String;)V
-java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.weakCompareAndSet:(LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
 java.lang.invoke.VarHandle.weakCompareAndSet:(LVarHandleDexTest;ZZ)Z
+java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z
 java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.weakCompareAndSetAcquire:(LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
 java.lang.invoke.VarHandle.weakCompareAndSetAcquire:(LVarHandleDexTest;ZZ)Z
+java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z
 java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.weakCompareAndSetPlain:(LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
 java.lang.invoke.VarHandle.weakCompareAndSetPlain:(LVarHandleDexTest;ZZ)Z
+java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z
 java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;
 java.lang.invoke.VarHandle.weakCompareAndSetRelease:(LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
 java.lang.invoke.VarHandle.weakCompareAndSetRelease:(LVarHandleDexTest;ZZ)Z
+java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z
 java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndExchangeAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndExchangeAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)V
@@ -194,16 +194,16 @@
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndExchange:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)V
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)V
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
-invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
+invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z, (LVarHandleDexTest;ZZ)Z
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.getAndAddAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.getAndAddAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)V
 invoke-polymorphic {v1, v0, v5, v6}, java.lang.invoke.VarHandle.getAndAdd:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;ZZ)Z
@@ -242,26 +242,26 @@
 invoke-polymorphic {v1, v0}, java.lang.invoke.VarHandle.getOpaque:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;)V
 invoke-polymorphic {v1, v0}, java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;)Z
 invoke-polymorphic {v1, v0}, java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;)V
-invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Z)V
-invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Z)V
-invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Z)V
-invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Z)V
+invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)V, (LVarHandleDexTest;Z)V
+invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)V, (LVarHandleDexTest;Z)V
+invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)V, (LVarHandleDexTest;Z)V
+invoke-polymorphic {v1, v0, v6}, java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)V, (LVarHandleDexTest;Z)V
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Ljava/lang/Float;
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)V
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndExchange:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Ljava/lang/Float;
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndExchange:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)V
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Ljava/lang/Float;
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)V
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
-invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
+invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Z
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.getAndAddAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Ljava/lang/Float;
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.getAndAddAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)V
 invoke-polymorphic {v1, v0, v3, v2}, java.lang.invoke.VarHandle.getAndAdd:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;Ljava/lang/Float;)Ljava/lang/Float;
@@ -300,26 +300,26 @@
 invoke-polymorphic {v1, v0}, java.lang.invoke.VarHandle.getOpaque:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;)V
 invoke-polymorphic {v1, v0}, java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;)Ljava/lang/Float;
 invoke-polymorphic {v1, v0}, java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;)V
-invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;)V
-invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;)V
-invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;)V
-invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, (LVarHandleDexTest;Ljava/lang/Float;)V
+invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)V, (LVarHandleDexTest;Ljava/lang/Float;)V
+invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)V, (LVarHandleDexTest;Ljava/lang/Float;)V
+invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)V, (LVarHandleDexTest;Ljava/lang/Float;)V
+invoke-polymorphic {v1, v0, v2}, java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)V, (LVarHandleDexTest;Ljava/lang/Float;)V
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndExchange:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndExchange:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndExchangeRelease:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
-invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.compareAndSet:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetAcquire:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSet:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetPlain:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.weakCompareAndSetRelease:([Ljava/lang/Object;)Z, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.getAndAddAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.getAndAddAcquire:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
 invoke-polymorphic {v1, v0, v7, v3, v2}, java.lang.invoke.VarHandle.getAndAdd:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
@@ -358,7 +358,7 @@
 invoke-polymorphic {v1, v0, v7}, java.lang.invoke.VarHandle.getOpaque:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;I)V
 invoke-polymorphic {v1, v0, v7}, java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;I)Ljava/lang/String;
 invoke-polymorphic {v1, v0, v7}, java.lang.invoke.VarHandle.getVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;I)V
-invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;)V
-invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;)V
-invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;)V
-invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)Ljava/lang/Object;, ([Ljava/lang/String;ILjava/lang/String;)V
+invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.set:([Ljava/lang/Object;)V, ([Ljava/lang/String;ILjava/lang/String;)V
+invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.setOpaque:([Ljava/lang/Object;)V, ([Ljava/lang/String;ILjava/lang/String;)V
+invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.setRelease:([Ljava/lang/Object;)V, ([Ljava/lang/String;ILjava/lang/String;)V
+invoke-polymorphic {v1, v0, v7, v2}, java.lang.invoke.VarHandle.setVolatile:([Ljava/lang/Object;)V, ([Ljava/lang/String;ILjava/lang/String;)V
diff --git a/dx/tests/run-all-tests b/dx/tests/run-all-tests
index d24ef7a..3734a98 100755
--- a/dx/tests/run-all-tests
+++ b/dx/tests/run-all-tests
@@ -105,9 +105,10 @@
 }
 
 function update_result {
-  test_name=$1
-  output=$2
-  result=$3
+  local -r test_name=$1
+  local -r output=$2
+  local -r result=$3
+  local expectFail
 
   if [[ "$known_bad" == *"$test_name"* ]]; then
     expectFail=1
@@ -134,33 +135,46 @@
   fi
 }
 
+function run_one_test_with_flock {
+  local -r output_dir=$1
+  local -r test_name=$2
+  local -r lock_file=$3
+
+  # Wait for the lock and run the test when acquired
+  flock "${lock_file}" ./run-test --output_dir "${output_dir}" "${test_name}"
+}
+
 function run_tests {
+  readonly test_root=$(mktemp -d)
+  trap "rm -rf ${test_root}" EXIT
   if [[ "$sequential" = "yes" ]]; then
     for test_name in *; do
       if [[ "$skip_tests" = *"$test_name"* ]]; then
-          skipped+=(${test_name})
-          continue
+        skipped+=(${test_name})
+        continue
       fi
       if [ -d "$test_name" -a -r "$test_name" ]; then
-        output=/tmp/$$/$test_name
-        ./run-test --output_dir "$output" "$test_name"
-        update_result $test_name $output $?
+        output="${test_root}/${test_name}"
+        ./run-test --output_dir "${output}" "${test_name}"
+        update_result "${test_name}" "${output}" $?
       fi
     done
   else
-    i=0
+    readonly num_workers=4
+    local i=0
     for test_name in *; do
       if [[ "$skip_tests" = *"$test_name"* ]]; then
-          skipped+=(${test_name})
-          continue
+        skipped+=(${test_name})
+        continue
       fi
-      if [ -d "$test_name" -a -r "$test_name" ]; then
-          output=/tmp/$$/$test_name
-          ./run-test --output_dir "$output" "$test_name" &
-          test_pids[i]=$!
-          test_names[test_pids[i]]="$test_name"
-          test_outputs[test_pids[i]]="output"
-          let i+=1
+      local lock_file=${test_root}/lock.$((i % num_workers))
+      if [ -d "${test_name}" -a -r "${test_name}" ]; then
+        output="${test_root}/${test_name}"
+        run_one_test_with_flock "$output" "$test_name" "$lock_file" &
+        test_pids[i]=$!
+        test_names[test_pids[i]]="$test_name"
+        test_outputs[test_pids[i]]="output"
+        let i+=1
       fi
     done
 
@@ -174,6 +188,9 @@
 function handle_interrupt {
   trap INT
   display_results
+  if [ ! -z "${test_pids}" ]; then
+    killall ${test_pids}
+  fi
 }
 
 trap handle_interrupt INT