Fix deadlock with the JIT code cache.

Also remove hack done for ThreadStress.

Change-Id: Ie25c3bca08d9f2b8919706fa3fc26c5ab213f4a3
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index cfccec8..ce972ef 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -25,6 +25,7 @@
 #include "linear_alloc.h"
 #include "mem_map.h"
 #include "oat_file-inl.h"
+#include "scoped_thread_state_change.h"
 #include "thread_list.h"
 
 namespace art {
@@ -407,9 +408,17 @@
   // Run a checkpoint on all threads to mark the JIT compiled code they are running.
   {
     Barrier barrier(0);
-    MarkCodeClosure closure(this, &barrier);
-    size_t threads_running_checkpoint =
-        Runtime::Current()->GetThreadList()->RunCheckpoint(&closure);
+    size_t threads_running_checkpoint = 0;
+    {
+      // Walking the stack requires the mutator lock.
+      // We only take the lock when running the checkpoint and not waiting so that
+      // when we go back to suspended, we can execute checkpoints that were requested
+      // concurrently, and then move to waiting for our own checkpoint to finish.
+      ScopedObjectAccess soa(self);
+      MarkCodeClosure closure(this, &barrier);
+      threads_running_checkpoint =
+          Runtime::Current()->GetThreadList()->RunCheckpoint(&closure);
+    }
     if (threads_running_checkpoint != 0) {
       barrier.Increment(self, threads_running_checkpoint);
     }