Add -XX:MadviseRandomAccess option
If enabled, ART will advise random access to the kernel for files
that are thought to have such access patterns.
Bug: 67772594
Test: verify that -XX:MadviseRandomAccess:true is passed to runtime init
(cherry picked from commit 087f2046dfdf41646c740a05004b4d40cbd99b11)
Change-Id: I76a5f62846d563a4f2cf25e47dbd320464aee8c1
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index b3c3aa0..781ddd7 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -77,9 +77,6 @@
// For debugging, Open will print DlOpen error message if set to true.
static constexpr bool kPrintDlOpenErrorMessage = false;
-// If true, we advise the kernel about dex file mem map accesses.
-static constexpr bool kMadviseDexFileAccesses = true;
-
// Note for OatFileBase and descendents:
//
// These are used in OatFile::Open to try all our loaders.
@@ -1651,20 +1648,19 @@
// Madvise the dex file based on the state we are moving to.
void OatDexFile::MadviseDexFile(const DexFile& dex_file, MadviseState state) {
- const bool low_ram = Runtime::Current()->GetHeap()->IsLowMemoryMode();
+ Runtime* const runtime = Runtime::Current();
+ const bool low_ram = runtime->GetHeap()->IsLowMemoryMode();
// TODO: Also do madvise hints for non low ram devices.
- if (!kMadviseDexFileAccesses || !low_ram) {
+ if (!low_ram) {
return;
}
- if (state == MadviseState::kMadviseStateAtLoad) {
- if (low_ram) {
- // Default every dex file to MADV_RANDOM when its loaded by default for low ram devices.
- // Other devices have enough page cache to get performance benefits from loading more pages
- // into the page cache.
- MadviseLargestPageAlignedRegion(dex_file.Begin(),
- dex_file.Begin() + dex_file.Size(),
- MADV_RANDOM);
- }
+ if (state == MadviseState::kMadviseStateAtLoad && runtime->MAdviseRandomAccess()) {
+ // Default every dex file to MADV_RANDOM when its loaded by default for low ram devices.
+ // Other devices have enough page cache to get performance benefits from loading more pages
+ // into the page cache.
+ MadviseLargestPageAlignedRegion(dex_file.Begin(),
+ dex_file.Begin() + dex_file.Size(),
+ MADV_RANDOM);
}
const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
if (oat_dex_file != nullptr) {
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 9888186..9841a95 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -159,6 +159,10 @@
.WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
.IntoKey(M::DumpNativeStackOnSigQuit)
+ .Define("-XX:MadviseRandomAccess:_")
+ .WithType<bool>()
+ .WithValueMap({{"false", false}, {"true", true}})
+ .IntoKey(M::MadviseRandomAccess)
.Define("-Xusejit:_")
.WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
@@ -717,6 +721,7 @@
UsageMessage(stream, " -XX:LargeObjectSpace={disabled,map,freelist}\n");
UsageMessage(stream, " -XX:LargeObjectThreshold=N\n");
UsageMessage(stream, " -XX:DumpNativeStackOnSigQuit=booleanvalue\n");
+ UsageMessage(stream, " -XX:MadviseRandomAccess:booleanvalue\n");
UsageMessage(stream, " -XX:SlowDebug={false,true}\n");
UsageMessage(stream, " -Xmethod-trace\n");
UsageMessage(stream, " -Xmethod-trace-file:filename");
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index a4ed21e..8eb4a07 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1143,6 +1143,7 @@
zygote_max_failed_boots_ = runtime_options.GetOrDefault(Opt::ZygoteMaxFailedBoots);
experimental_flags_ = runtime_options.GetOrDefault(Opt::Experimental);
is_low_memory_mode_ = runtime_options.Exists(Opt::LowMemoryMode);
+ madvise_random_access_ = runtime_options.GetOrDefault(Opt::MadviseRandomAccess);
plugins_ = runtime_options.ReleaseOrDefault(Opt::Plugins);
agents_ = runtime_options.ReleaseOrDefault(Opt::AgentPath);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 399e1c1..9f79a01 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -682,6 +682,12 @@
return result;
}
+ // Whether or not we use MADV_RANDOM on files that are thought to have random access patterns.
+ // This is beneficial for low RAM devices since it reduces page cache thrashing.
+ bool MAdviseRandomAccess() const {
+ return madvise_random_access_;
+ }
+
private:
static void InitPlatformSignalHandlers();
@@ -916,6 +922,10 @@
// Whether or not we are on a low RAM device.
bool is_low_memory_mode_;
+ // Whether or not we use MADV_RANDOM on files that are thought to have random access patterns.
+ // This is beneficial for low RAM devices since it reduces page cache thrashing.
+ bool madvise_random_access_;
+
// Whether the application should run in safe mode, that is, interpreter only.
bool safe_mode_;
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index cafae22..2e03562 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -70,6 +70,7 @@
RUNTIME_OPTIONS_KEY (bool, EnableHSpaceCompactForOOM, true)
RUNTIME_OPTIONS_KEY (bool, UseJitCompilation, false)
RUNTIME_OPTIONS_KEY (bool, DumpNativeStackOnSigQuit, true)
+RUNTIME_OPTIONS_KEY (bool, MadviseRandomAccess, false)
RUNTIME_OPTIONS_KEY (unsigned int, JITCompileThreshold)
RUNTIME_OPTIONS_KEY (unsigned int, JITWarmupThreshold)
RUNTIME_OPTIONS_KEY (unsigned int, JITOsrThreshold)