Fix race between post fork initialization and JIT.
Only start JIT threads after all zygote fork logic has been setup.
For robustness, also set the runtime state as the first thing post fork.
Test: m
Change-Id: Icf5db341275002599d0e89add4d9f6b2f799004d
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 52c0e9d..ad60546 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -1128,18 +1128,11 @@
code_cache_->SetGarbageCollectCode(!jit_compiler_->GenerateDebugInfo() &&
!Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
- if (thread_pool_ != nullptr) {
- if (is_system_server &&
- Runtime::Current()->IsUsingApexBootImageLocation() &&
- UseJitCompilation()) {
- // Disable garbage collection: we don't want it to delete methods we're compiling
- // through boot and system server profiles.
- // TODO(ngeoffray): Fix this so we still collect deoptimized and unused code.
- code_cache_->SetGarbageCollectCode(false);
- }
-
- // Resume JIT compilation.
- thread_pool_->CreateThreads();
+ if (is_system_server && Runtime::Current()->IsUsingApexBootImageLocation()) {
+ // Disable garbage collection: we don't want it to delete methods we're compiling
+ // through boot and system server profiles.
+ // TODO(ngeoffray): Fix this so we still collect deoptimized and unused code.
+ code_cache_->SetGarbageCollectCode(false);
}
}
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 7de6e1d..ca331df 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -255,15 +255,15 @@
}
static void ZygoteHooks_nativePostZygoteFork(JNIEnv*, jclass) {
- Runtime* runtime = Runtime::Current();
- if (runtime->IsZygote()) {
- runtime->PostZygoteFork();
- }
+ Runtime::Current()->PostZygoteFork();
}
static void ZygoteHooks_nativePostForkSystemServer(JNIEnv* env ATTRIBUTE_UNUSED,
jclass klass ATTRIBUTE_UNUSED) {
- Runtime::Current()->SetSystemServer(true);
+ // Set the runtime state as the first thing, in case JIT and other services
+ // start querying it.
+ Runtime::Current()->SetAsSystemServer();
+
// This JIT code cache for system server is created whilst the runtime is still single threaded.
// System server has a window where it can create executable pages for this purpose, but this is
// turned off after this hook. Consequently, the only JIT mode supported is the dual-view JIT
@@ -286,6 +286,9 @@
jboolean is_zygote,
jstring instruction_set) {
DCHECK(!(is_system_server && is_zygote));
+ // Set the runtime state as the first thing, in case JIT and other services
+ // start querying it.
+ Runtime::Current()->SetAsZygoteChild(is_system_server, is_zygote);
Thread* thread = reinterpret_cast<Thread*>(token);
// Our system thread ID, etc, has changed so reset Thread state.
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1b12f6a..b651851 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -978,8 +978,7 @@
NativeBridgeAction action,
const char* isa,
bool profile_system_server) {
- is_zygote_ = false;
- is_primary_zygote_ = false;
+ DCHECK(!IsZygote());
if (is_native_bridge_loaded_) {
switch (action) {
diff --git a/runtime/runtime.h b/runtime/runtime.h
index ca01761..ea516cd 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -173,8 +173,17 @@
return is_system_server_;
}
- void SetSystemServer(bool value) {
- is_system_server_ = value;
+ void SetAsSystemServer() {
+ is_system_server_ = true;
+ is_zygote_ = false;
+ is_primary_zygote_ = false;
+ }
+
+ void SetAsZygoteChild(bool is_system_server, bool is_zygote) {
+ // System server should have been set earlier in SetAsSystemServer.
+ CHECK_EQ(is_system_server_, is_system_server);
+ is_zygote_ = is_zygote;
+ is_primary_zygote_ = false;
}
bool IsExplicitGcDisabled() const {