diff options
author | 2022-06-24 23:14:24 +0100 | |
---|---|---|
committer | 2022-07-04 16:25:06 +0000 | |
commit | dbfa799b5e9d48a4f93410da37b199aaa8878d9b (patch) | |
tree | 485471e2addb3bf236cbd3459e0fe99a45598978 /runtime/oat_file_assistant.cc | |
parent | 865006d268317b0ebd9e9a28671e8157e3983726 (diff) |
Add a new version of `GetDexOptNeeded`.
The new version has two improvements:
- It takes a bit field `DexOptTrigger` as an input instead of
`profile_changed` and `downgrade`. The bit field gives the caller more
flexibility to customize the conditions to trigger dexopt.
- It returns the result in a more structured way: a boolean representing
whether dexopt should be performed and an object containing whether
the vdex file is usable and the location of the usable files.
The old version is refactored so that it shares the same underlying
logic with the new version. The behavior of the old version remains
unchanged.
Bug: 229268202
Test: m test-art-host-gtest-art_runtime_tests
Change-Id: I2841b8b0494e1bc7e0a57f0690d817b67bde64dc
Merged-In: I2841b8b0494e1bc7e0a57f0690d817b67bde64dc
(cherry picked from commit af72f6cf8762bbebe472b8562df116efe4327a9c)
Diffstat (limited to 'runtime/oat_file_assistant.cc')
-rw-r--r-- | runtime/oat_file_assistant.cc | 104 |
1 files changed, 78 insertions, 26 deletions
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index b69d2af3f6..e111b27308 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -295,19 +295,70 @@ bool OatFileAssistant::IsInBootClassPath() { return false; } -int OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target, +OatFileAssistant::DexOptTrigger OatFileAssistant::GetDexOptTrigger( + CompilerFilter::Filter target_compiler_filter [[gnu::unused]], + bool profile_changed, + bool downgrade) { + OatFileInfo& info = GetBestInfo(); + + if (!info.IsUseable()) { + // Essentially always recompile. + return OatFileAssistant::DexOptTrigger{.targetFilterIsBetter = true}; + } + + const OatFile* file = info.GetFile(); + DCHECK(file != nullptr); + + CompilerFilter::Filter current = file->GetCompilerFilter(); + if (profile_changed && CompilerFilter::DependsOnProfile(current)) { + // Since the profile has been changed, we should re-compile even if the compilation does not + // make the compiler filter better. + return OatFileAssistant::DexOptTrigger{ + .targetFilterIsBetter = true, .targetFilterIsSame = true, .targetFilterIsWorse = true}; + } + + if (downgrade) { + // The caller's intention is to downgrade the compiler filter. We should only re-compile if the + // target compiler filter is worse than the current one. + return OatFileAssistant::DexOptTrigger{.targetFilterIsWorse = true}; + } + + // This is the usual case. The caller's intention is to see if a better oat file can be generated. + return OatFileAssistant::DexOptTrigger{.targetFilterIsBetter = true, + .primaryBootImageBecomesUsable = true}; +} + +int OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target_compiler_filter, bool profile_changed, bool downgrade) { OatFileInfo& info = GetBestInfo(); - DexOptNeeded dexopt_needed = info.GetDexOptNeeded(target, - profile_changed, - downgrade); + DexOptNeeded dexopt_needed = info.GetDexOptNeeded( + target_compiler_filter, GetDexOptTrigger(target_compiler_filter, profile_changed, downgrade)); if (info.IsOatLocation() || dexopt_needed == kDex2OatFromScratch) { return dexopt_needed; } return -dexopt_needed; } +bool OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target_compiler_filter, + DexOptTrigger dexopt_trigger, + /*out*/ DexOptStatus* dexopt_status) { + OatFileInfo& info = GetBestInfo(); + DexOptNeeded dexopt_needed = info.GetDexOptNeeded(target_compiler_filter, dexopt_trigger); + if (info.IsUseable()) { + if (&info == &dm_for_oat_ || &info == &dm_for_odex_) { + dexopt_status->location_ = kLocationDm; + } else if (info.IsOatLocation()) { + dexopt_status->location_ = kLocationOat; + } else { + dexopt_status->location_ = kLocationOdex; + } + } else { + dexopt_status->location_ = kLocationNoneOrError; + } + return dexopt_needed != kNoDexOptNeeded; +} + bool OatFileAssistant::IsUpToDate() { return GetBestInfo().Status() == kOatUpToDate; } @@ -925,14 +976,16 @@ OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() { } OatFileAssistant::DexOptNeeded OatFileAssistant::OatFileInfo::GetDexOptNeeded( - CompilerFilter::Filter target, - bool profile_changed, - bool downgrade) { - + CompilerFilter::Filter target_compiler_filter, const DexOptTrigger dexopt_trigger) { if (IsUseable()) { - return CompilerFilterIsOkay(target, profile_changed, downgrade) - ? kNoDexOptNeeded - : kDex2OatForFilter; + return ShouldRecompileForFilter(target_compiler_filter, dexopt_trigger) ? kDex2OatForFilter : + kNoDexOptNeeded; + } + + // In this case, the oat file is not usable. If the caller doesn't seek for a better compiler + // filter (e.g., the caller wants to downgrade), then we should not recompile. + if (!dexopt_trigger.targetFilterIsBetter) { + return kNoDexOptNeeded; } if (Status() == kOatBootImageOutOfDate) { @@ -1052,25 +1105,24 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { return file_.get(); } -bool OatFileAssistant::OatFileInfo::CompilerFilterIsOkay( - CompilerFilter::Filter target, bool profile_changed, bool downgrade) { +bool OatFileAssistant::OatFileInfo::ShouldRecompileForFilter(CompilerFilter::Filter target, + const DexOptTrigger dexopt_trigger) { const OatFile* file = GetFile(); - if (file == nullptr) { - return false; - } + DCHECK(file != nullptr); CompilerFilter::Filter current = file->GetCompilerFilter(); - if (profile_changed && CompilerFilter::DependsOnProfile(current)) { - VLOG(oat) << "Compiler filter not okay because Profile changed"; - return false; + if (dexopt_trigger.targetFilterIsBetter && CompilerFilter::IsBetter(target, current)) { + return true; } - - if (downgrade) { - return !CompilerFilter::IsBetter(current, target); + if (dexopt_trigger.targetFilterIsSame && current == target) { + return true; + } + if (dexopt_trigger.targetFilterIsWorse && CompilerFilter::IsBetter(current, target)) { + return true; } - if (CompilerFilter::DependsOnImageChecksum(current) && - CompilerFilter::IsAsGoodAs(current, target)) { + if (dexopt_trigger.primaryBootImageBecomesUsable && + CompilerFilter::DependsOnImageChecksum(current)) { // If the oat file has been compiled without an image, and the runtime is // now running with an image loaded from disk, return that we need to // re-compile. The recompilation will generate a better oat file, and with an app @@ -1081,11 +1133,11 @@ bool OatFileAssistant::OatFileInfo::CompilerFilterIsOkay( !StartsWith(oat_boot_class_path_checksums, "i") && oat_file_assistant_->IsPrimaryBootImageUsable()) { DCHECK(!file->GetOatHeader().RequiresImage()); - return false; + return true; } } - return CompilerFilter::IsAsGoodAs(current, target); + return false; } bool OatFileAssistant::ClassLoaderContextIsOkay(const OatFile& oat_file) const { |