Add -XX:ForceJavaZygoteForkLoop flag
Setting this to true effectively disables the zygote native fork
loop, either for testing/measurement purposes, or as a fallback.
Bug: 192020504
Test: Check logcat with and without the flag.
Change-Id: I83c401d21ae2797442011d9ac6f23c78990920bd
Merged-In: I83c401d21ae2797442011d9ac6f23c78990920bd
(cherry picked from commit 1792c6ff1c9838dfbe948be124dc1a8501fc6636)
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 2c18ddb..050233d 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -442,11 +442,17 @@
Runtime::Current()->SetZygoteNoThreadSection(false);
}
-static jboolean ZygoteHooks_nativeZygoteJitEnabled(JNIEnv* env ATTRIBUTE_UNUSED,
- jclass klass ATTRIBUTE_UNUSED) {
+static jboolean ZygoteHooks_nativeZygoteLongSuspendOk(JNIEnv* env ATTRIBUTE_UNUSED,
+ jclass klass ATTRIBUTE_UNUSED) {
+ // Indefinite thread suspensions are not OK if we're supposed to be JIT-compiling for other
+ // processes. We only care about JIT compilation that affects other processes. The zygote
+ // itself doesn't run appreciable amounts of Java code when running single-threaded, so
+ // suspending the JIT in non-jit-zygote mode is OK.
+ // TODO: Make this potentially return true once we're done with JIT compilation in JIT Zygote.
// Only called in zygote. Thus static is OK here.
- static bool result = jit::Jit::InZygoteUsingJit();
- return result ? JNI_TRUE : JNI_FALSE;
+ static bool isJitZygote = jit::Jit::InZygoteUsingJit();
+ static bool explicitlyDisabled = Runtime::Current()->IsJavaZygoteForkLoopRequired();
+ return (isJitZygote || explicitlyDisabled) ? JNI_FALSE : JNI_TRUE;
}
@@ -455,7 +461,7 @@
NATIVE_METHOD(ZygoteHooks, nativePostZygoteFork, "()V"),
NATIVE_METHOD(ZygoteHooks, nativePostForkSystemServer, "(I)V"),
NATIVE_METHOD(ZygoteHooks, nativePostForkChild, "(JIZZLjava/lang/String;)V"),
- NATIVE_METHOD(ZygoteHooks, nativeZygoteJitEnabled, "()Z"),
+ NATIVE_METHOD(ZygoteHooks, nativeZygoteLongSuspendOk, "()Z"),
NATIVE_METHOD(ZygoteHooks, startZygoteNoThreadCreation, "()V"),
NATIVE_METHOD(ZygoteHooks, stopZygoteNoThreadCreation, "()V"),
};
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 8ce9144..3e1fd4f 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -441,6 +441,10 @@
.WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
.IntoKey(M::VerifierMissingKThrowFatal)
+ .Define("-XX:ForceJavaZygoteForkLoop=_")
+ .WithType<bool>()
+ .WithValueMap({{"false", false}, {"true", true}})
+ .IntoKey(M::ForceJavaZygoteForkLoop)
.Define("-XX:PerfettoHprof=_")
.WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1e563dd..669c613 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1348,6 +1348,7 @@
MemMap::Init();
verifier_missing_kthrow_fatal_ = runtime_options.GetOrDefault(Opt::VerifierMissingKThrowFatal);
+ force_java_zygote_fork_loop_ = runtime_options.GetOrDefault(Opt::ForceJavaZygoteForkLoop);
perfetto_hprof_enabled_ = runtime_options.GetOrDefault(Opt::PerfettoHprof);
perfetto_javaheapprof_enabled_ = runtime_options.GetOrDefault(Opt::PerfettoJavaHeapStackProf);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 1486a9a..68456cd 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -991,6 +991,10 @@
return verifier_missing_kthrow_fatal_;
}
+ bool IsJavaZygoteForkLoopRequired() const {
+ return force_java_zygote_fork_loop_;
+ }
+
bool IsPerfettoHprofEnabled() const {
return perfetto_hprof_enabled_;
}
@@ -1413,6 +1417,7 @@
std::atomic<bool> startup_completed_ = false;
bool verifier_missing_kthrow_fatal_;
+ bool force_java_zygote_fork_loop_;
bool perfetto_hprof_enabled_;
bool perfetto_javaheapprof_enabled_;
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index 966bc83..ddbbfec 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -176,6 +176,10 @@
RUNTIME_OPTIONS_KEY (bool, FastClassNotFoundException, true)
RUNTIME_OPTIONS_KEY (bool, VerifierMissingKThrowFatal, true)
+// Setting this to true causes ART to disable Zygote native fork loop. ART also
+// internally enables this if ZygoteJit is enabled.
+RUNTIME_OPTIONS_KEY (bool, ForceJavaZygoteForkLoop, false)
+
// Whether to allow loading of the perfetto hprof plugin.
// Even with this option set, we will still only actually load the plugin
// if we are on a userdebug build or the app is debuggable or profileable.