JDWP: allow VirtualMachine.Resume on partial suspension

Allows to resume multiple threads with a single VirtualMachine.Resume
command. When some threads are suspended for an event by the debugger
with a suspend count of 1 (other threads are running), a debugger can
resume them all this way.

Bug: 18924933

(cherry picked from commit f9d233dae8ca66ed5a2a474155d6bee0d74c355b)

Change-Id: I948c3b50d43693e86ae31e0928a33a467328583f
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 24ff92e..3647dc4 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -720,7 +720,6 @@
 void ThreadList::ResumeAllForDebugger() {
   Thread* self = Thread::Current();
   Thread* debug_thread = Dbg::GetDebugThread();
-  bool needs_resume = false;
 
   VLOG(threads) << *self << " ResumeAllForDebugger starting...";
 
@@ -733,32 +732,34 @@
       MutexLock mu(self, *Locks::thread_suspend_count_lock_);
       // Update global suspend all state for attaching threads.
       DCHECK_GE(suspend_all_count_, debug_suspend_all_count_);
-      needs_resume = (debug_suspend_all_count_ > 0);
-      if (needs_resume) {
+      if (debug_suspend_all_count_ > 0) {
         --suspend_all_count_;
         --debug_suspend_all_count_;
-        // Decrement everybody's suspend count (except our own).
-        for (const auto& thread : list_) {
-          if (thread == self || thread == debug_thread) {
-            continue;
-          }
-          if (thread->GetDebugSuspendCount() == 0) {
-            // This thread may have been individually resumed with ThreadReference.Resume.
-            continue;
-          }
-          VLOG(threads) << "requesting thread resume: " << *thread;
-          thread->ModifySuspendCount(self, -1, true);
-        }
       } else {
         // We've been asked to resume all threads without being asked to
-        // suspend them all before. Let's print a warning.
+        // suspend them all before. That may happen if a debugger tries
+        // to resume some suspended threads (with suspend count == 1)
+        // at once with a VirtualMachine.Resume command. Let's print a
+        // warning.
         LOG(WARNING) << "Debugger attempted to resume all threads without "
                      << "having suspended them all before.";
       }
+      // Decrement everybody's suspend count (except our own).
+      for (const auto& thread : list_) {
+        if (thread == self || thread == debug_thread) {
+          continue;
+        }
+        if (thread->GetDebugSuspendCount() == 0) {
+          // This thread may have been individually resumed with ThreadReference.Resume.
+          continue;
+        }
+        VLOG(threads) << "requesting thread resume: " << *thread;
+        thread->ModifySuspendCount(self, -1, true);
+      }
     }
   }
 
-  if (needs_resume) {
+  {
     MutexLock mu(self, *Locks::thread_suspend_count_lock_);
     Thread::resume_cond_->Broadcast(self);
   }