Guard entrypoint changing by runtime shutdown lock.

There was a race when we changed the allocation entrypoints where a
new thread would be starting (Thread::Init) and initialize to the
wrong entrypoints. Guarding allocation entrypoint changing
with the runtime shutdown lock fixes this race condition since
Thread::Init is only called with the runtime shutdown lock held.

Bug: 13250963

Change-Id: I8eb209c124b6bf17020de874e1b0083f158b8200
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 01ad46d..e10d881 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -23,6 +23,7 @@
 #include "class_linker.h"
 #include "debugger.h"
 #include "dex_file-inl.h"
+#include "entrypoints/quick/quick_alloc_entrypoints.h"
 #include "interpreter/interpreter.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
@@ -41,8 +42,6 @@
 
 namespace art {
 
-extern void SetQuickAllocEntryPointsInstrumented(bool instrumented);
-
 namespace instrumentation {
 
 const bool kVerboseInstrumentation = false;
@@ -466,10 +465,13 @@
       quick_alloc_entry_points_instrumentation_counter_.FetchAndAdd(1) == 0;
   if (enable_instrumentation) {
     // Instrumentation wasn't enabled so enable it.
-    SetQuickAllocEntryPointsInstrumented(true);
     ThreadList* tl = Runtime::Current()->GetThreadList();
     tl->SuspendAll();
-    ResetQuickAllocEntryPoints();
+    {
+      MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_);
+      SetQuickAllocEntryPointsInstrumented(true);
+      ResetQuickAllocEntryPoints();
+    }
     tl->ResumeAll();
   }
 }
@@ -481,10 +483,13 @@
   const bool disable_instrumentation =
       quick_alloc_entry_points_instrumentation_counter_.FetchAndSub(1) == 1;
   if (disable_instrumentation) {
-    SetQuickAllocEntryPointsInstrumented(false);
     ThreadList* tl = Runtime::Current()->GetThreadList();
     tl->SuspendAll();
-    ResetQuickAllocEntryPoints();
+    {
+      MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_);
+      SetQuickAllocEntryPointsInstrumented(false);
+      ResetQuickAllocEntryPoints();
+    }
     tl->ResumeAll();
   }
 }