[jitzygote] Suspend all threads when remapping boot image methods.

Prevents other threads from concurrently modifying the data.

Bug: 143569713
Bug: 119800099
Test: boots
Change-Id: I2b07d34c98a37306e9157bfa63321ed01f68479e
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index e64908d..b7fab90 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -1077,6 +1077,7 @@
   // The private mapping created for this process has been mremaped. We can
   // reset it.
   child_mapping_methods.Reset();
+  LOG(INFO) << "Successfully mapped boot image methods";
 }
 
 void Jit::CreateThreadPool() {
@@ -1562,7 +1563,26 @@
   do {
     sleep(10);
   } while (!jit->GetCodeCache()->GetZygoteMap()->IsCompilationNotified());
-  jit->MapBootImageMethods();
+
+  // We will suspend other threads: we can only do that if we're attached to the
+  // runtime.
+  Runtime* runtime = Runtime::Current();
+  bool thread_attached = runtime->AttachCurrentThread(
+      "BootImagePollingThread",
+      /* as_daemon= */ true,
+      /* thread_group= */ nullptr,
+      /* create_peer= */ false);
+  CHECK(thread_attached);
+
+  {
+    // Prevent other threads from running while we are remapping the boot image
+    // ArtMethod's. Native threads might still be running, but they cannot
+    // change the contents of ArtMethod's.
+    ScopedSuspendAll ssa(__FUNCTION__);
+    runtime->GetJit()->MapBootImageMethods();
+  }
+
+  Runtime::Current()->DetachCurrentThread();
   return nullptr;
 }
 
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 502fe9f..e5b77c2 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -377,7 +377,7 @@
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Map boot image methods after all compilation in zygote has been done.
-  void MapBootImageMethods();
+  void MapBootImageMethods() REQUIRES(Locks::mutator_lock_);
 
   // Notify to other processes that the zygote is done profile compiling boot
   // class path methods.