Clean up VLOG(oat) in OatFileAssistant.
Refactor GetOatDexFile to have an error message out parameter.
Change-Id: I6b933f1fcfc9726c051a9d9678d92587cc02501e
Test: OatFileAssistantTest with and without -verbose:oat logging turned on.
Test: m test-art-host
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 3c64c81..534f53d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1501,11 +1501,8 @@
SHARED_REQUIRES(Locks::mutator_lock_) {
DCHECK(error_msg != nullptr);
std::unique_ptr<const DexFile> dex_file;
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, nullptr);
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, nullptr, error_msg);
if (oat_dex_file == nullptr) {
- *error_msg = StringPrintf("Failed finding oat dex file for %s %s",
- oat_file->GetLocation().c_str(),
- location);
return std::unique_ptr<const DexFile>();
}
std::string inner_error_msg;
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 68610a7..5752fd9 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -1073,7 +1073,7 @@
const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
const uint32_t* dex_location_checksum,
- bool warn_if_not_found) const {
+ std::string* error_msg) const {
// NOTE: We assume here that the canonical location for a given dex_location never
// changes. If it does (i.e. some symlink used by the filename changes) we may return
// an incorrect OatDexFile. As long as we have a checksum to check, we shall return
@@ -1115,32 +1115,29 @@
secondary_oat_dex_files_.PutBefore(secondary_lb, key_copy, oat_dex_file);
}
}
- if (oat_dex_file != nullptr &&
- (dex_location_checksum == nullptr ||
- oat_dex_file->GetDexFileLocationChecksum() == *dex_location_checksum)) {
- return oat_dex_file;
+
+ if (oat_dex_file == nullptr) {
+ if (error_msg != nullptr) {
+ std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location);
+ *error_msg = "Failed to find OatDexFile for DexFile " + std::string(dex_location)
+ + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation();
+ }
+ return nullptr;
}
- if (warn_if_not_found) {
- std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location);
- std::string checksum("<unspecified>");
- if (dex_location_checksum != nullptr) {
- checksum = StringPrintf("0x%08x", *dex_location_checksum);
+ if (dex_location_checksum != nullptr &&
+ oat_dex_file->GetDexFileLocationChecksum() != *dex_location_checksum) {
+ if (error_msg != nullptr) {
+ std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location);
+ std::string checksum = StringPrintf("0x%08x", oat_dex_file->GetDexFileLocationChecksum());
+ std::string required_checksum = StringPrintf("0x%08x", *dex_location_checksum);
+ *error_msg = "OatDexFile for DexFile " + std::string(dex_location)
+ + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation()
+ + " has checksum " + checksum + " but " + required_checksum + " was required";
}
- LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_location
- << " ( canonical path " << dex_canonical_location << ")"
- << " with checksum " << checksum << " in OatFile " << GetLocation();
- if (kIsDebugBuild) {
- for (const OatDexFile* odf : oat_dex_files_storage_) {
- LOG(WARNING) << "OatFile " << GetLocation()
- << " contains OatDexFile " << odf->GetDexFileLocation()
- << " (canonical path " << odf->GetCanonicalDexFileLocation() << ")"
- << " with checksum 0x" << std::hex << odf->GetDexFileLocationChecksum();
- }
- }
+ return nullptr;
}
-
- return nullptr;
+ return oat_dex_file;
}
OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index aa727ff..f5ab9dc 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -213,9 +213,15 @@
friend class art::OatDexFile;
};
+
+ // Get the OatDexFile for the given dex_location within this oat file.
+ // If dex_location_checksum is non-null, the OatDexFile will only be
+ // returned if it has a matching checksum.
+ // If error_msg is non-null and no OatDexFile is returned, error_msg will
+ // be updated with a description of why no OatDexFile was returned.
const OatDexFile* GetOatDexFile(const char* dex_location,
const uint32_t* const dex_location_checksum,
- bool exception_if_not_found = true) const
+ /*out*/std::string* error_msg = nullptr) const
REQUIRES(!secondary_lookup_lock_);
const std::vector<const OatDexFile*>& GetOatDexFiles() const {
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index fd58907..2c2a2b8 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -277,10 +277,9 @@
// Load the primary dex file.
std::string error_msg;
const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile(
- dex_location, nullptr, false);
+ dex_location, nullptr, &error_msg);
if (oat_dex_file == nullptr) {
- LOG(WARNING) << "Attempt to load out-of-date oat file "
- << oat_file.GetLocation() << " for dex location " << dex_location;
+ LOG(WARNING) << error_msg;
return std::vector<std::unique_ptr<const DexFile>>();
}
@@ -294,7 +293,7 @@
// Load secondary multidex files
for (size_t i = 1; ; i++) {
std::string secondary_dex_location = DexFile::GetMultiDexLocation(i, dex_location);
- oat_dex_file = oat_file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
+ oat_dex_file = oat_file.GetOatDexFile(secondary_dex_location.c_str(), nullptr);
if (oat_dex_file == nullptr) {
// There are no more secondary dex files to load.
break;
@@ -389,25 +388,25 @@
// Verify the dex checksum.
// Note: GetOatDexFile will return null if the dex checksum doesn't match
// what we provide, which verifies the primary dex checksum for us.
+ std::string error_msg;
const uint32_t* dex_checksum_pointer = GetRequiredDexChecksum();
const OatFile::OatDexFile* oat_dex_file = file.GetOatDexFile(
- dex_location_.c_str(), dex_checksum_pointer, false);
+ dex_location_.c_str(), dex_checksum_pointer, &error_msg);
if (oat_dex_file == nullptr) {
+ VLOG(oat) << error_msg;
return kOatOutOfDate;
}
// Verify the dex checksums for any secondary multidex files
for (size_t i = 1; ; i++) {
- std::string secondary_dex_location
- = DexFile::GetMultiDexLocation(i, dex_location_.c_str());
+ std::string secondary_dex_location = DexFile::GetMultiDexLocation(i, dex_location_.c_str());
const OatFile::OatDexFile* secondary_oat_dex_file
- = file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
+ = file.GetOatDexFile(secondary_dex_location.c_str(), nullptr);
if (secondary_oat_dex_file == nullptr) {
// There are no more secondary dex files to check.
break;
}
- std::string error_msg;
uint32_t expected_secondary_checksum = 0;
if (DexFile::GetChecksum(secondary_dex_location.c_str(),
&expected_secondary_checksum, &error_msg)) {
@@ -429,7 +428,6 @@
}
CompilerFilter::Filter current_compiler_filter = file.GetCompilerFilter();
- VLOG(oat) << "Compiler filter for " << file.GetLocation() << " is " << current_compiler_filter;
// Verify the image checksum
if (CompilerFilter::DependsOnImageChecksum(current_compiler_filter)) {
@@ -760,8 +758,8 @@
// Get the checksum from the odex if we can.
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);
+ const OatFile::OatDexFile* odex_dex_file
+ = odex_file->GetOatDexFile(dex_location_.c_str(), nullptr);
if (odex_dex_file != nullptr) {
cached_required_dex_checksum_ = odex_dex_file->GetDexFileLocationChecksum();
required_dex_checksum_found_ = true;
@@ -867,6 +865,8 @@
status_ = kOatOutOfDate;
} else {
status_ = oat_file_assistant_->GivenOatFileStatus(*file);
+ VLOG(oat) << file->GetLocation() << " is " << status_
+ << " with filter " << file->GetCompilerFilter();
}
}
return status_;
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 39848b4..05c5a22 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -320,6 +320,34 @@
EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
}
+// Case: We have a DEX file and ODEX file for a different dex location.
+// Expect: The status is kDex2OatNeeded.
+TEST_F(OatFileAssistantTest, OatForDifferentDex) {
+ // Generate an odex file for OatForDifferentDex_A.jar
+ std::string dex_location_a = GetScratchDir() + "/OatForDifferentDex_A.jar";
+ std::string odex_location = GetOdexDir() + "/OatForDifferentDex.odex";
+ Copy(GetDexSrc1(), dex_location_a);
+ GenerateOdexForTest(dex_location_a, odex_location, CompilerFilter::kSpeed);
+
+ // Try to use that odex file for OatForDifferentDex.jar
+ std::string dex_location = GetScratchDir() + "/OatForDifferentDex.jar";
+ Copy(GetDexSrc1(), dex_location);
+
+ OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+ EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
+ oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
+
+ EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+ EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+ EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+ EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+ EXPECT_FALSE(oat_file_assistant.OatFileExists());
+ EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+ EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
+ EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+}
+
// Case: We have a DEX file and speed-profile OAT file for it.
// Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
// kDex2Oat if the profile has changed.