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, \