Jit: Misc fixes, move_exception, blocking mode, self-cosim

OP_MOVE_EXCEPTION handler was neglecting to reset.
Blocking mode was failing to signal empty queue in some cases
Self-cosim was including operations in traces that can't be done twice
Added OP_MOVE_EXCEPTION to self cosim's no-replay ops (it has side effects)
Restored threshold of 1 to self-cosim (now able to boot device with self-cosim)
When threshold < 6, disable 2nd-level translation filter
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c
index b53ebf8..5787378 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -38,6 +38,9 @@
         gDvmJit.compilerWorkDequeueIndex = 0;
     }
     gDvmJit.compilerQueueLength--;
+    if (gDvmJit.compilerQueueLength == 0) {
+        int cc = pthread_cond_signal(&gDvmJit.compilerQueueEmpty);
+    }
 
     /* Remember the high water mark of the queue length */
     if (gDvmJit.compilerQueueLength > gDvmJit.compilerMaxQueued)
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 857536f..35460ed 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -208,13 +208,6 @@
 }
 
 #if defined(WITH_SELF_VERIFICATION)
-/* Prevent certain opcodes from being jitted */
-static inline bool selfVerificationPuntOps(OpCode op)
-{
-  return (op == OP_MONITOR_ENTER || op == OP_MONITOR_EXIT ||
-          op == OP_NEW_INSTANCE  || op == OP_NEW_ARRAY);
-}
-
 /*
  * The following are used to keep compiled loads and stores from modifying
  * memory during self verification mode.
@@ -2048,10 +2041,13 @@
             int offset = offsetof(InterpState, self);
             int exOffset = offsetof(Thread, exception);
             int selfReg = allocTemp(cUnit);
+            int resetReg = allocTemp(cUnit);
             RegLocation rlDest = getDestLoc(cUnit, mir, 0);
             rlResult = evalLoc(cUnit, rlDest, kCoreReg, true);
             loadWordDisp(cUnit, rGLUE, offset, selfReg);
+            loadConstant(cUnit, resetReg, 0);
             loadWordDisp(cUnit, selfReg, exOffset, rlResult.lowReg);
+            storeWordDisp(cUnit, selfReg, exOffset, resetReg);
             storeValue(cUnit, rlDest, rlResult);
            break;
         }
@@ -3882,11 +3878,6 @@
                 ((gDvmJit.opList[dalvikOpCode >> 3] &
                   (1 << (dalvikOpCode & 0x7))) !=
                  0);
-#if defined(WITH_SELF_VERIFICATION)
-            /* Punt on opcodes we can't replay */
-            if (selfVerificationPuntOps(dalvikOpCode))
-                singleStepMe = true;
-#endif
             if (singleStepMe || cUnit->allSingleStep) {
                 notHandled = false;
                 genInterpSingleStep(cUnit, mir);
diff --git a/vm/interp/Jit.c b/vm/interp/Jit.c
index 018a77f..69cfdf2 100644
--- a/vm/interp/Jit.c
+++ b/vm/interp/Jit.c
@@ -350,11 +350,7 @@
 
 #if defined(WITH_SELF_VERIFICATION)
     // Force JIT into blocking, translate everything mode
-    /*
-     * FIXME
-     * Cannot boot to home with threshold 1
-     * gDvmJit.threshold = 1;
-     */
+    gDvmJit.threshold = 1;
     gDvmJit.blockingMode = true;
 #endif
 
@@ -550,6 +546,18 @@
         interpState->jitState = kJitTSelectAbort;
 }
 
+#if defined(WITH_SELF_VERIFICATION)
+static bool selfVerificationPuntOps(DecodedInstruction *decInsn)
+{
+    OpCode op = decInsn->opCode;
+    int flags =  dexGetInstrFlags(gDvm.instrFlags, op);
+    return (op == OP_MONITOR_ENTER || op == OP_MONITOR_EXIT ||
+            op == OP_NEW_INSTANCE || op == OP_NEW_ARRAY ||
+            op == OP_CHECK_CAST || op == OP_MOVE_EXCEPTION ||
+            (flags & kInstrInvoke));
+}
+#endif
+
 /*
  * Adds to the current trace request one instruction at a time, just
  * before that instruction is interpreted.  This is the primary trace
@@ -580,6 +588,21 @@
     const u2 *lastPC = interpState->lastPC;
     interpState->lastPC = pc;
 
+#if defined(WITH_SELF_VERIFICATION)
+    /*
+     * We can't allow some instructions to be executed twice, and so they
+     * must not appear in any translations.  End the trace before they
+     * are inlcluded.
+     */
+    if (lastPC && interpState->jitState == kJitTSelect) {
+        DecodedInstruction decInsn;
+        dexDecodeInstruction(gDvm.instrFormat, lastPC, &decInsn);
+        if (selfVerificationPuntOps(&decInsn)) {
+            interpState->jitState = kJitTSelectEnd;
+        }
+    }
+#endif
+
     switch (interpState->jitState) {
         char* nopStr;
         int target;
@@ -603,6 +626,7 @@
                 break;
             }
 
+
 #if defined(SHOW_TRACE)
             LOGD("TraceGen: adding %s",getOpcodeName(decInsn.opCode));
 #endif
@@ -931,8 +955,8 @@
             res = true;
         }
 
-        /* If stress mode (threshold==1), always translate */
-        res &= (gDvmJit.threshold != 1);
+        /* If stress mode (threshold <= 6), always translate */
+        res &= (gDvmJit.threshold > 6);
 
         /*
          * If the compiler is backlogged, or if a debugger or profiler is