Create OatFileAssistant::OatFileInfo inner class.
To share code reused for getting info about both the odex and oat files.
Test: oat file assistant tests.
Change-Id: Ifcc48e0ac481899285e39e3b02f3ade180e38728
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 8700a90..fd58907 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -16,18 +16,7 @@
#include "oat_file_assistant.h"
-#include <fcntl.h>
-#ifdef __linux__
-#include <sys/sendfile.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
-
-#include <set>
-
#include "base/logging.h"
#include "base/stringprintf.h"
#include "compiler_filter.h"
@@ -71,7 +60,7 @@
const char* oat_location,
const InstructionSet isa,
bool load_executable)
- : isa_(isa), load_executable_(load_executable) {
+ : isa_(isa), load_executable_(load_executable), odex_(this), oat_(this) {
CHECK(dex_location != nullptr) << "OatFileAssistant: null dex location";
dex_location_.assign(dex_location);
@@ -81,15 +70,23 @@
load_executable_ = false;
}
+ // Get the odex filename.
std::string error_msg;
- if (!DexLocationToOdexFilename(dex_location_, isa_, &odex_file_name_, &error_msg)) {
+ std::string odex_file_name;
+ if (DexLocationToOdexFilename(dex_location_, isa_, &odex_file_name, &error_msg)) {
+ odex_.Reset(odex_file_name);
+ } else {
LOG(WARNING) << "Failed to determine odex file name: " << error_msg;
}
+ // Get the oat filename.
if (oat_location != nullptr) {
- oat_file_name_ = std::string(oat_location);
+ oat_.Reset(oat_location);
} else {
- if (!DexLocationToOatFilename(dex_location_, isa_, &oat_file_name_, &error_msg)) {
+ std::string oat_file_name;
+ if (DexLocationToOatFilename(dex_location_, isa_, &oat_file_name, &error_msg)) {
+ oat_.Reset(oat_file_name);
+ } else {
LOG(WARNING) << "Failed to determine oat file name for dex location "
<< dex_location_ << ": " << error_msg;
}
@@ -124,11 +121,12 @@
CHECK(error_msg != nullptr);
CHECK(!flock_.HasFile()) << "OatFileAssistant::Lock already acquired";
- if (OatFileName() == nullptr) {
+ const std::string* oat_file_name = oat_.Filename();
+ if (oat_file_name == nullptr) {
*error_msg = "Failed to determine lock file";
return false;
}
- std::string lock_file_name = *OatFileName() + ".flock";
+ std::string lock_file_name = *oat_file_name + ".flock";
if (!flock_.Init(lock_file_name.c_str(), error_msg)) {
unlink(lock_file_name.c_str());
@@ -137,64 +135,33 @@
return true;
}
-static bool GivenOatFileCompilerFilterIsOkay(const OatFile& oat_file,
- CompilerFilter::Filter target,
- bool profile_changed) {
- CompilerFilter::Filter current = oat_file.GetCompilerFilter();
-
- if (profile_changed && CompilerFilter::DependsOnProfile(current)) {
- VLOG(oat) << "Compiler filter not okay because Profile changed";
- return false;
- }
- return CompilerFilter::IsAsGoodAs(current, target);
-}
-
-bool OatFileAssistant::OatFileCompilerFilterIsOkay(CompilerFilter::Filter target,
- bool profile_changed) {
- const OatFile* oat_file = GetOatFile();
- if (oat_file != nullptr) {
- return GivenOatFileCompilerFilterIsOkay(*oat_file, target, profile_changed);
- }
- return false;
-}
-
-bool OatFileAssistant::OdexFileCompilerFilterIsOkay(CompilerFilter::Filter target,
- bool profile_changed) {
- const OatFile* odex_file = GetOdexFile();
- if (odex_file != nullptr) {
- return GivenOatFileCompilerFilterIsOkay(*odex_file, target, profile_changed);
- }
- return false;
-}
-
OatFileAssistant::DexOptNeeded
-OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target,
- bool profile_changed) {
+OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target, bool profile_changed) {
bool compilation_desired = CompilerFilter::IsBytecodeCompilationEnabled(target);
// See if the oat file is in good shape as is.
- bool oat_okay = OatFileCompilerFilterIsOkay(target, profile_changed);
+ bool oat_okay = oat_.CompilerFilterIsOkay(target, profile_changed);
if (oat_okay) {
if (compilation_desired) {
- if (OatFileIsUpToDate()) {
+ if (oat_.IsUpToDate()) {
return kNoDexOptNeeded;
}
} else {
- if (!OatFileIsOutOfDate()) {
+ if (!oat_.IsOutOfDate()) {
return kNoDexOptNeeded;
}
}
}
// See if the odex file is in good shape as is.
- bool odex_okay = OdexFileCompilerFilterIsOkay(target, profile_changed);
+ bool odex_okay = odex_.CompilerFilterIsOkay(target, profile_changed);
if (odex_okay) {
if (compilation_desired) {
- if (OdexFileIsUpToDate()) {
+ if (odex_.IsUpToDate()) {
return kNoDexOptNeeded;
}
} else {
- if (!OdexFileIsOutOfDate()) {
+ if (!odex_.IsOutOfDate()) {
return kNoDexOptNeeded;
}
}
@@ -202,11 +169,11 @@
// See if we can get an up-to-date file by running patchoat.
if (compilation_desired) {
- if (odex_okay && OdexFileNeedsRelocation() && OdexFileHasPatchInfo()) {
+ if (odex_okay && odex_.NeedsRelocation() && odex_.HasPatchInfo()) {
return kPatchOatNeeded;
}
- if (oat_okay && OatFileNeedsRelocation() && OatFileHasPatchInfo()) {
+ if (oat_okay && oat_.NeedsRelocation() && oat_.HasPatchInfo()) {
return kSelfPatchOatNeeded;
}
}
@@ -251,8 +218,8 @@
switch (GetDexOptNeeded(target, profile_changed)) {
case kNoDexOptNeeded: return kUpdateSucceeded;
case kDex2OatNeeded: return GenerateOatFile(error_msg);
- case kPatchOatNeeded: return RelocateOatFile(OdexFileName(), error_msg);
- case kSelfPatchOatNeeded: return RelocateOatFile(OatFileName(), error_msg);
+ case kPatchOatNeeded: return RelocateOatFile(odex_.Filename(), error_msg);
+ case kSelfPatchOatNeeded: return RelocateOatFile(oat_.Filename(), error_msg);
}
UNREACHABLE();
}
@@ -263,46 +230,40 @@
// 2. Not out-of-date files that are already opened non-executable.
// 3. Not out-of-date files that we must reopen non-executable.
- if (OatFileIsUpToDate()) {
- oat_file_released_ = true;
- return std::move(cached_oat_file_);
+ if (oat_.IsUpToDate()) {
+ return oat_.ReleaseFile();
}
- if (OdexFileIsUpToDate()) {
- oat_file_released_ = true;
- return std::move(cached_odex_file_);
+ if (odex_.IsUpToDate()) {
+ return odex_.ReleaseFile();
}
VLOG(oat) << "Oat File Assistant: No relocated oat file found,"
<< " attempting to fall back to interpreting oat file instead.";
- if (!OatFileIsOutOfDate() && !OatFileIsExecutable()) {
- oat_file_released_ = true;
- return std::move(cached_oat_file_);
+ if (!oat_.IsOutOfDate() && !oat_.IsExecutable()) {
+ return oat_.ReleaseFile();
}
- if (!OdexFileIsOutOfDate() && !OdexFileIsExecutable()) {
- oat_file_released_ = true;
- return std::move(cached_odex_file_);
+ if (!odex_.IsOutOfDate() && !odex_.IsExecutable()) {
+ return odex_.ReleaseFile();
}
- if (!OatFileIsOutOfDate()) {
+ if (!oat_.IsOutOfDate()) {
load_executable_ = false;
- ClearOatFileCache();
- if (!OatFileIsOutOfDate()) {
- CHECK(!OatFileIsExecutable());
- oat_file_released_ = true;
- return std::move(cached_oat_file_);
+ oat_.Reset();
+ if (!oat_.IsOutOfDate()) {
+ CHECK(!oat_.IsExecutable());
+ return oat_.ReleaseFile();
}
}
- if (!OdexFileIsOutOfDate()) {
+ if (!odex_.IsOutOfDate()) {
load_executable_ = false;
- ClearOdexFileCache();
- if (!OdexFileIsOutOfDate()) {
- CHECK(!OdexFileIsExecutable());
- oat_file_released_ = true;
- return std::move(cached_odex_file_);
+ odex_.Reset();
+ if (!odex_.IsOutOfDate()) {
+ CHECK(!odex_.IsExecutable());
+ return odex_.ReleaseFile();
}
}
@@ -358,43 +319,31 @@
}
const std::string* OatFileAssistant::OdexFileName() {
- return odex_file_name_.empty() ? nullptr : &odex_file_name_;
+ return odex_.Filename();
}
bool OatFileAssistant::OdexFileExists() {
- return GetOdexFile() != nullptr;
+ return odex_.Exists();
}
OatFileAssistant::OatStatus OatFileAssistant::OdexFileStatus() {
- if (!odex_file_status_attempted_) {
- odex_file_status_attempted_ = true;
- const OatFile* odex_file = GetOdexFile();
- if (odex_file == nullptr) {
- cached_odex_file_status_ = kOatOutOfDate;
- } else {
- cached_odex_file_status_ = GivenOatFileStatus(*odex_file);
- }
- }
- return cached_odex_file_status_;
+ return odex_.Status();
}
bool OatFileAssistant::OdexFileIsOutOfDate() {
- return OdexFileStatus() == kOatOutOfDate;
+ return odex_.IsOutOfDate();
}
bool OatFileAssistant::OdexFileNeedsRelocation() {
- return OdexFileStatus() == kOatNeedsRelocation;
+ return odex_.NeedsRelocation();
}
bool OatFileAssistant::OdexFileIsUpToDate() {
- return OdexFileStatus() == kOatUpToDate;
+ return odex_.IsUpToDate();
}
CompilerFilter::Filter OatFileAssistant::OdexFileCompilerFilter() {
- const OatFile* odex_file = GetOdexFile();
- CHECK(odex_file != nullptr);
-
- return odex_file->GetCompilerFilter();
+ return odex_.CompilerFilter();
}
static std::string ArtFileName(const OatFile* oat_file) {
@@ -409,43 +358,31 @@
}
const std::string* OatFileAssistant::OatFileName() {
- return oat_file_name_.empty() ? nullptr : &oat_file_name_;
+ return oat_.Filename();
}
bool OatFileAssistant::OatFileExists() {
- return GetOatFile() != nullptr;
+ return oat_.Exists();
}
OatFileAssistant::OatStatus OatFileAssistant::OatFileStatus() {
- if (!oat_file_status_attempted_) {
- oat_file_status_attempted_ = true;
- const OatFile* oat_file = GetOatFile();
- if (oat_file == nullptr) {
- cached_oat_file_status_ = kOatOutOfDate;
- } else {
- cached_oat_file_status_ = GivenOatFileStatus(*oat_file);
- }
- }
- return cached_oat_file_status_;
+ return oat_.Status();
}
bool OatFileAssistant::OatFileIsOutOfDate() {
- return OatFileStatus() == kOatOutOfDate;
+ return oat_.IsOutOfDate();
}
bool OatFileAssistant::OatFileNeedsRelocation() {
- return OatFileStatus() == kOatNeedsRelocation;
+ return oat_.NeedsRelocation();
}
bool OatFileAssistant::OatFileIsUpToDate() {
- return OatFileStatus() == kOatUpToDate;
+ return oat_.IsUpToDate();
}
CompilerFilter::Filter OatFileAssistant::OatFileCompilerFilter() {
- const OatFile* oat_file = GetOatFile();
- CHECK(oat_file != nullptr);
-
- return oat_file->GetCompilerFilter();
+ return oat_.CompilerFilter();
}
OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& file) {
@@ -572,12 +509,12 @@
}
const std::string& input_file_name = *input_file;
- if (OatFileName() == nullptr) {
+ if (oat_.Filename() == nullptr) {
*error_msg = "Patching of oat file for dex location " + dex_location_
+ " not attempted because the oat file name could not be determined.";
return kUpdateNotAttempted;
}
- const std::string& oat_file_name = *OatFileName();
+ const std::string& oat_file_name = *oat_.Filename();
const ImageInfo* image_info = GetImageInfo();
Runtime* runtime = Runtime::Current();
@@ -609,7 +546,7 @@
}
// Mark that the oat file has changed and we should try to reload.
- ClearOatFileCache();
+ oat_.Reset();
return kUpdateSucceeded;
}
@@ -624,12 +561,12 @@
return kUpdateNotAttempted;
}
- if (OatFileName() == nullptr) {
+ if (oat_.Filename() == nullptr) {
*error_msg = "Generation of oat file for dex location " + dex_location_
+ " not attempted because the oat file name could not be determined.";
return kUpdateNotAttempted;
}
- const std::string& oat_file_name = *OatFileName();
+ const std::string& oat_file_name = *oat_.Filename();
// dex2oat ignores missing dex files and doesn't report an error.
// Check explicitly here so we can detect the error properly.
@@ -674,7 +611,7 @@
}
// Mark that the oat file has changed and we should try to reload.
- ClearOatFileCache();
+ oat_.Reset();
return kUpdateSucceeded;
}
@@ -821,7 +758,7 @@
has_original_dex_files_ = false;
// Get the checksum from the odex if we can.
- const OatFile* odex_file = GetOdexFile();
+ const OatFile* odex_file = odex_.GetFile();
if (odex_file != nullptr) {
const OatFile::OatDexFile* odex_dex_file = odex_file->GetOatDexFile(
dex_location_.c_str(), nullptr, false);
@@ -835,86 +772,6 @@
return required_dex_checksum_found_ ? &cached_required_dex_checksum_ : nullptr;
}
-const OatFile* OatFileAssistant::GetOdexFile() {
- CHECK(!oat_file_released_) << "OdexFile called after oat file released.";
- if (!odex_file_load_attempted_) {
- odex_file_load_attempted_ = true;
- if (OdexFileName() != nullptr) {
- const std::string& odex_file_name = *OdexFileName();
- std::string error_msg;
- cached_odex_file_.reset(OatFile::Open(odex_file_name.c_str(),
- odex_file_name.c_str(),
- nullptr,
- nullptr,
- load_executable_,
- /*low_4gb*/false,
- dex_location_.c_str(),
- &error_msg));
- if (cached_odex_file_.get() == nullptr) {
- VLOG(oat) << "OatFileAssistant test for existing pre-compiled oat file "
- << odex_file_name << ": " << error_msg;
- }
- }
- }
- return cached_odex_file_.get();
-}
-
-bool OatFileAssistant::OdexFileIsExecutable() {
- const OatFile* odex_file = GetOdexFile();
- return (odex_file != nullptr && odex_file->IsExecutable());
-}
-
-bool OatFileAssistant::OdexFileHasPatchInfo() {
- const OatFile* odex_file = GetOdexFile();
- return (odex_file != nullptr && odex_file->HasPatchInfo());
-}
-
-void OatFileAssistant::ClearOdexFileCache() {
- odex_file_load_attempted_ = false;
- cached_odex_file_.reset();
- odex_file_status_attempted_ = false;
-}
-
-const OatFile* OatFileAssistant::GetOatFile() {
- CHECK(!oat_file_released_) << "OatFile called after oat file released.";
- if (!oat_file_load_attempted_) {
- oat_file_load_attempted_ = true;
- if (OatFileName() != nullptr) {
- const std::string& oat_file_name = *OatFileName();
- std::string error_msg;
- cached_oat_file_.reset(OatFile::Open(oat_file_name.c_str(),
- oat_file_name.c_str(),
- nullptr,
- nullptr,
- load_executable_,
- /*low_4gb*/false,
- dex_location_.c_str(),
- &error_msg));
- if (cached_oat_file_.get() == nullptr) {
- VLOG(oat) << "OatFileAssistant test for existing oat file "
- << oat_file_name << ": " << error_msg;
- }
- }
- }
- return cached_oat_file_.get();
-}
-
-bool OatFileAssistant::OatFileIsExecutable() {
- const OatFile* oat_file = GetOatFile();
- return (oat_file != nullptr && oat_file->IsExecutable());
-}
-
-bool OatFileAssistant::OatFileHasPatchInfo() {
- const OatFile* oat_file = GetOatFile();
- return (oat_file != nullptr && oat_file->HasPatchInfo());
-}
-
-void OatFileAssistant::ClearOatFileCache() {
- oat_file_load_attempted_ = false;
- cached_oat_file_.reset();
- oat_file_status_attempted_ = false;
-}
-
const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() {
if (!image_info_load_attempted_) {
image_info_load_attempted_ = true;
@@ -990,5 +847,113 @@
return ret;
}
+OatFileAssistant::OatFileInfo::OatFileInfo(OatFileAssistant* oat_file_assistant)
+ : oat_file_assistant_(oat_file_assistant)
+{}
+
+const std::string* OatFileAssistant::OatFileInfo::Filename() {
+ return filename_provided_ ? &filename_ : nullptr;
+}
+
+bool OatFileAssistant::OatFileInfo::Exists() {
+ return GetFile() != nullptr;
+}
+
+OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() {
+ if (!status_attempted_) {
+ status_attempted_ = true;
+ const OatFile* file = GetFile();
+ if (file == nullptr) {
+ status_ = kOatOutOfDate;
+ } else {
+ status_ = oat_file_assistant_->GivenOatFileStatus(*file);
+ }
+ }
+ return status_;
+}
+
+bool OatFileAssistant::OatFileInfo::IsOutOfDate() {
+ return Status() == kOatOutOfDate;
+}
+
+bool OatFileAssistant::OatFileInfo::NeedsRelocation() {
+ return Status() == kOatNeedsRelocation;
+}
+
+bool OatFileAssistant::OatFileInfo::IsUpToDate() {
+ return Status() == kOatUpToDate;
+}
+
+CompilerFilter::Filter OatFileAssistant::OatFileInfo::CompilerFilter() {
+ const OatFile* file = GetFile();
+ CHECK(file != nullptr);
+ return file->GetCompilerFilter();
+}
+
+const OatFile* OatFileAssistant::OatFileInfo::GetFile() {
+ CHECK(!file_released_) << "GetFile called after oat file released.";
+ if (!load_attempted_) {
+ load_attempted_ = true;
+ if (filename_provided_) {
+ std::string error_msg;
+ file_.reset(OatFile::Open(filename_.c_str(),
+ filename_.c_str(),
+ nullptr,
+ nullptr,
+ oat_file_assistant_->load_executable_,
+ /*low_4gb*/false,
+ oat_file_assistant_->dex_location_.c_str(),
+ &error_msg));
+ if (file_.get() == nullptr) {
+ VLOG(oat) << "OatFileAssistant test for existing oat file "
+ << filename_ << ": " << error_msg;
+ }
+ }
+ }
+ return file_.get();
+}
+
+bool OatFileAssistant::OatFileInfo::CompilerFilterIsOkay(
+ CompilerFilter::Filter target, bool profile_changed) {
+ const OatFile* file = GetFile();
+ if (file == nullptr) {
+ return false;
+ }
+
+ CompilerFilter::Filter current = file->GetCompilerFilter();
+ if (profile_changed && CompilerFilter::DependsOnProfile(current)) {
+ VLOG(oat) << "Compiler filter not okay because Profile changed";
+ return false;
+ }
+ return CompilerFilter::IsAsGoodAs(current, target);
+}
+
+bool OatFileAssistant::OatFileInfo::IsExecutable() {
+ const OatFile* file = GetFile();
+ return (file != nullptr && file->IsExecutable());
+}
+
+bool OatFileAssistant::OatFileInfo::HasPatchInfo() {
+ const OatFile* file = GetFile();
+ return (file != nullptr && file->HasPatchInfo());
+}
+
+void OatFileAssistant::OatFileInfo::Reset() {
+ load_attempted_ = false;
+ file_.reset();
+ status_attempted_ = false;
+}
+
+void OatFileAssistant::OatFileInfo::Reset(const std::string& filename) {
+ filename_provided_ = true;
+ filename_ = filename;
+ Reset();
+}
+
+std::unique_ptr<OatFile> OatFileAssistant::OatFileInfo::ReleaseFile() {
+ file_released_ = true;
+ return std::move(file_);
+}
+
} // namespace art