Support for stopping all threads in a Jit environment.
diff --git a/vm/Thread.c b/vm/Thread.c
index b945483..6420533 100644
--- a/vm/Thread.c
+++ b/vm/Thread.c
@@ -234,6 +234,16 @@
 static void waitForThreadSuspend(Thread* self, Thread* thread);
 static int getThreadPriorityFromSystem(void);
 
+/*
+ * The JIT needs to know if any thread is suspended.  We do this by
+ * maintaining a global sum of all threads' suspend counts.  All suspendCount
+ * updates should go through this after aquiring threadSuspendCountLock.
+ */
+static inline void dvmAddToThreadSuspendCount(int *pSuspendCount, int delta)
+{
+    *pSuspendCount += delta;
+    gDvm.sumThreadSuspendCount += delta;
+}
 
 /*
  * Initialize thread list and main thread's environment.  We need to set
@@ -1556,6 +1566,12 @@
     }
 
 bail:
+#if defined(WITH_JIT)
+    /* Remove this thread's suspendCount from global suspendCount sum */
+    lockThreadSuspendCount();
+    dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
+    unlockThreadSuspendCount();
+#endif
     dvmReleaseTrackedAlloc(exception, self);
 }
 
@@ -2132,7 +2148,7 @@
     //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
 
     lockThreadSuspendCount();
-    thread->suspendCount++;
+    dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
     thread->dbgSuspendCount++;
 
     LOG_THREAD("threadid=%d: suspend++, now=%d\n",
@@ -2161,7 +2177,7 @@
 
     lockThreadSuspendCount();
     if (thread->suspendCount > 0) {
-        thread->suspendCount--;
+        dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
         thread->dbgSuspendCount--;
     } else {
         LOG_THREAD("threadid=%d:  suspendCount already zero\n",
@@ -2199,7 +2215,7 @@
      * though.
      */
     lockThreadSuspendCount();
-    self->suspendCount++;
+    dvmAddToThreadSuspendCount(&self->suspendCount, 1);
     self->dbgSuspendCount++;
 
     /*
@@ -2337,10 +2353,12 @@
  *
  * TODO: track basic stats about time required to suspend VM.
  */
+#define FIRST_SLEEP (250*1000)    /* 0.25s */
+#define MORE_SLEEP  (750*1000)    /* 0.75s */
 static void waitForThreadSuspend(Thread* self, Thread* thread)
 {
     const int kMaxRetries = 10;
-    const int kSpinSleepTime = 750*1000;        /* 0.75s */
+    int spinSleepTime = FIRST_SLEEP;
 
     int sleepIter = 0;
     int retryCount = 0;
@@ -2350,7 +2368,18 @@
         if (sleepIter == 0)         // get current time on first iteration
             startWhen = dvmGetRelativeTimeUsec();
 
-        if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
+#if defined (WITH_JIT)
+        /*
+         * If we're still waiting after the first timeout,
+         * unchain all translations.
+         */
+        if (gDvmJit.pJitEntryTable && retryCount > 0) {
+            LOGD("JIT unchain all attempt #%d",retryCount);
+            dvmJitUnchainAll();
+        }
+#endif
+
+        if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
             LOGW("threadid=%d (h=%d): spin on suspend threadid=%d (handle=%d)\n",
                 self->threadId, (int)self->handle,
                 thread->threadId, (int)thread->handle);
@@ -2358,6 +2387,7 @@
 
             // keep going; could be slow due to valgrind
             sleepIter = 0;
+            spinSleepTime = MORE_SLEEP;
 
             if (retryCount++ == kMaxRetries) {
                 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
@@ -2431,7 +2461,7 @@
             thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
             continue;
 
-        thread->suspendCount++;
+        dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
         if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
             thread->dbgSuspendCount++;
     }
@@ -2506,7 +2536,7 @@
             continue;
 
         if (thread->suspendCount > 0) {
-            thread->suspendCount--;
+            dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
             if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
                 thread->dbgSuspendCount--;
         } else {
@@ -2562,7 +2592,8 @@
         }
 
         assert(thread->suspendCount >= thread->dbgSuspendCount);
-        thread->suspendCount -= thread->dbgSuspendCount;
+        dvmAddToThreadSuspendCount(&thread->suspendCount,
+                                   -thread->dbgSuspendCount);
         thread->dbgSuspendCount = 0;
     }
     unlockThreadSuspendCount();
@@ -3524,4 +3555,3 @@
      */
     gcScanAllThreads();
 }
-