Add two flags to customize JIT zygote.

1) -Xuseprofiledjit to do compilation of system server (and potentially
apps) at startup with a profile
2) -Xjitzygotepthreadpriority to set the zygote JIT thread priority.

Bug: 119800099
Test: m
Change-Id: I131c5a8bae0f4b15c33c3e24e07465b7858f7fe2
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 9d05f6b..a5317d0 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -90,6 +90,8 @@
 JitOptions* JitOptions::CreateFromRuntimeArguments(const RuntimeArgumentMap& options) {
   auto* jit_options = new JitOptions;
   jit_options->use_jit_compilation_ = options.GetOrDefault(RuntimeArgumentMap::UseJitCompilation);
+  jit_options->use_profiled_jit_compilation_ =
+      options.GetOrDefault(RuntimeArgumentMap::UseProfiledJitCompilation);
 
   jit_options->code_cache_initial_capacity_ =
       options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheInitialCapacity);
@@ -101,6 +103,8 @@
       options.GetOrDefault(RuntimeArgumentMap::ProfileSaverOpts);
   jit_options->thread_pool_pthread_priority_ =
       options.GetOrDefault(RuntimeArgumentMap::JITPoolThreadPthreadPriority);
+  jit_options->zygote_thread_pool_pthread_priority_ =
+      options.GetOrDefault(RuntimeArgumentMap::JITZygotePoolThreadPthreadPriority);
 
   // Set default compile threshold to aid with checking defaults.
   jit_options->compile_threshold_ =
@@ -1172,10 +1176,13 @@
   constexpr bool kJitPoolNeedsPeers = true;
   thread_pool_.reset(new ThreadPool("Jit thread pool", 1, kJitPoolNeedsPeers));
 
-  thread_pool_->SetPthreadPriority(options_->GetThreadPoolPthreadPriority());
+  Runtime* runtime = Runtime::Current();
+  thread_pool_->SetPthreadPriority(
+      runtime->IsZygote()
+          ? options_->GetZygoteThreadPoolPthreadPriority()
+          : options_->GetThreadPoolPthreadPriority());
   Start();
 
-  Runtime* runtime = Runtime::Current();
   if (runtime->IsZygote()) {
     // To speed up class lookups, generate a type lookup table for
     // dex files not backed by oat file.
@@ -1276,7 +1283,9 @@
   Runtime* runtime = Runtime::Current();
   // If the runtime is debuggable, no need to precompile methods.
   if (runtime->IsSystemServer() &&
-      UseJitCompilation() && HasImageWithProfile() &&
+      UseJitCompilation() &&
+      options_->UseProfiledJitCompilation() &&
+      HasImageWithProfile() &&
       !runtime->IsJavaDebuggable()) {
     thread_pool_->AddTask(Thread::Current(), new JitProfileTask(dex_files, class_loader));
   }
@@ -1700,10 +1709,11 @@
 }
 
 void Jit::PostZygoteFork() {
+  Runtime* runtime = Runtime::Current();
   if (thread_pool_ == nullptr) {
     // If this is a child zygote, check if we need to remap the boot image
     // methods.
-    if (Runtime::Current()->IsZygote() &&
+    if (runtime->IsZygote() &&
         fd_methods_ != -1 &&
         code_cache_->GetZygoteMap()->IsCompilationNotified()) {
       ScopedSuspendAll ssa(__FUNCTION__);
@@ -1711,8 +1721,7 @@
     }
     return;
   }
-  if (Runtime::Current()->IsZygote() &&
-      code_cache_->GetZygoteMap()->IsCompilationDoneButNotNotified()) {
+  if (runtime->IsZygote() && code_cache_->GetZygoteMap()->IsCompilationDoneButNotNotified()) {
     // Copy the boot image methods data to the mappings we created to share
     // with the children. We do this here as we are the only thread running and
     // we don't risk other threads concurrently updating the ArtMethod's.
@@ -1721,7 +1730,10 @@
     CHECK(code_cache_->GetZygoteMap()->IsCompilationNotified());
   }
   thread_pool_->CreateThreads();
-  thread_pool_->SetPthreadPriority(options_->GetThreadPoolPthreadPriority());
+  thread_pool_->SetPthreadPriority(
+      runtime->IsZygote()
+          ? options_->GetZygoteThreadPoolPthreadPriority()
+          : options_->GetThreadPoolPthreadPriority());
 }
 
 void Jit::BootCompleted() {
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index cbfd954..639fd8e 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -61,6 +61,10 @@
 // At what priority to schedule jit threads. 9 is the lowest foreground priority on device.
 // See android/os/Process.java.
 static constexpr int kJitPoolThreadPthreadDefaultPriority = 9;
+// At what priority to schedule jit zygote threads compiling profiles in the background.
+// 19 is the lowest background priority on device.
+// See android/os/Process.java.
+static constexpr int kJitZygotePoolThreadPthreadDefaultPriority = 19;
 // We check whether to jit-compile the method every Nth invoke.
 // The tests often use threshold of 1000 (and thus 500 to start profiling).
 static constexpr uint32_t kJitSamplesBatchSize = 512;  // Must be power of 2.
@@ -113,10 +117,18 @@
     return thread_pool_pthread_priority_;
   }
 
+  int GetZygoteThreadPoolPthreadPriority() const {
+    return zygote_thread_pool_pthread_priority_;
+  }
+
   bool UseJitCompilation() const {
     return use_jit_compilation_;
   }
 
+  bool UseProfiledJitCompilation() const {
+    return use_profiled_jit_compilation_;
+  }
+
   void SetUseJitCompilation(bool b) {
     use_jit_compilation_ = b;
   }
@@ -148,6 +160,7 @@
   static uint32_t RoundUpThreshold(uint32_t threshold);
 
   bool use_jit_compilation_;
+  bool use_profiled_jit_compilation_;
   bool use_baseline_compiler_;
   size_t code_cache_initial_capacity_;
   size_t code_cache_max_capacity_;
@@ -158,10 +171,12 @@
   uint16_t invoke_transition_weight_;
   bool dump_info_on_shutdown_;
   int thread_pool_pthread_priority_;
+  int zygote_thread_pool_pthread_priority_;
   ProfileSaverOptions profile_saver_options_;
 
   JitOptions()
       : use_jit_compilation_(false),
+        use_profiled_jit_compilation_(false),
         use_baseline_compiler_(false),
         code_cache_initial_capacity_(0),
         code_cache_max_capacity_(0),
@@ -171,7 +186,8 @@
         priority_thread_weight_(0),
         invoke_transition_weight_(0),
         dump_info_on_shutdown_(false),
-        thread_pool_pthread_priority_(kJitPoolThreadPthreadDefaultPriority) {}
+        thread_pool_pthread_priority_(kJitPoolThreadPthreadDefaultPriority),
+        zygote_thread_pool_pthread_priority_(kJitZygotePoolThreadPthreadDefaultPriority) {}
 
   DISALLOW_COPY_AND_ASSIGN(JitOptions);
 };
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 98014da..508e697 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -237,6 +237,10 @@
           .WithType<bool>()
           .WithValueMap({{"false", false}, {"true", true}})
           .IntoKey(M::UseJitCompilation)
+      .Define("-Xuseprofiledjit:_")
+          .WithType<bool>()
+          .WithValueMap({{"false", false}, {"true", true}})
+          .IntoKey(M::UseProfiledJitCompilation)
       .Define("-Xjitinitialsize:_")
           .WithType<MemoryKiB>()
           .IntoKey(M::JITCodeCacheInitialCapacity)
@@ -258,6 +262,9 @@
       .Define("-Xjitpthreadpriority:_")
           .WithType<int>()
           .IntoKey(M::JITPoolThreadPthreadPriority)
+      .Define("-Xjitzygotepthreadpriority:_")
+          .WithType<int>()
+          .IntoKey(M::JITZygotePoolThreadPthreadPriority)
       .Define("-Xjitsaveprofilinginfo")
           .WithType<ProfileSaverOptions>()
           .AppendValues()
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index 441b2f2..4462de2 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -76,6 +76,7 @@
 RUNTIME_OPTIONS_KEY (bool,                UseTLAB,                        (kUseTlab || kUseReadBarrier))
 RUNTIME_OPTIONS_KEY (bool,                EnableHSpaceCompactForOOM,      true)
 RUNTIME_OPTIONS_KEY (bool,                UseJitCompilation,              true)
+RUNTIME_OPTIONS_KEY (bool,                UseProfiledJitCompilation,      false)
 RUNTIME_OPTIONS_KEY (bool,                DumpNativeStackOnSigQuit,       true)
 RUNTIME_OPTIONS_KEY (bool,                MadviseRandomAccess,            false)
 RUNTIME_OPTIONS_KEY (JniIdType,           OpaqueJniIds,                   JniIdType::kDefault)  // -Xopaque-jni-ids:{true, false, swapable}
@@ -86,6 +87,7 @@
 RUNTIME_OPTIONS_KEY (unsigned int,        JITPriorityThreadWeight)
 RUNTIME_OPTIONS_KEY (unsigned int,        JITInvokeTransitionWeight)
 RUNTIME_OPTIONS_KEY (int,                 JITPoolThreadPthreadPriority,   jit::kJitPoolThreadPthreadDefaultPriority)
+RUNTIME_OPTIONS_KEY (int,                 JITZygotePoolThreadPthreadPriority,   jit::kJitZygotePoolThreadPthreadDefaultPriority)
 RUNTIME_OPTIONS_KEY (MemoryKiB,           JITCodeCacheInitialCapacity,    jit::JitCodeCache::kInitialCapacity)
 RUNTIME_OPTIONS_KEY (MemoryKiB,           JITCodeCacheMaxCapacity,        jit::JitCodeCache::kMaxCapacity)
 RUNTIME_OPTIONS_KEY (MillisecondsToNanoseconds, \