Keep dex files live for duration of oatdump
Not keeping the dex file live caused a dex cache with a pointer to a
stale dex file resulting in oatdump failing. This is required to
remove the dex file location test that causes the class loader 068
test to fail.
Change-Id: I5d532862ab998482c0d16d7a63c6bdc3752f031a
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 1950d56..c553a18 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -78,6 +78,21 @@
"kClassRoots",
};
+// Map is so that we don't allocate multiple dex files for the same OatDexFile.
+static std::map<const OatFile::OatDexFile*,
+ std::unique_ptr<const DexFile>> opened_dex_files;
+
+const DexFile* OpenDexFile(const OatFile::OatDexFile* oat_dex_file, std::string* error_msg) {
+ DCHECK(oat_dex_file != nullptr);
+ auto it = opened_dex_files.find(oat_dex_file);
+ if (it != opened_dex_files.end()) {
+ return it->second.get();
+ }
+ const DexFile* ret = oat_dex_file->OpenDexFile(error_msg).release();
+ opened_dex_files.emplace(oat_dex_file, std::unique_ptr<const DexFile>(ret));
+ return ret;
+}
+
class OatSymbolizer FINAL {
public:
class RodataWriter FINAL : public CodeOutput {
@@ -159,8 +174,8 @@
void WalkOatDexFile(const OatFile::OatDexFile* oat_dex_file, Callback callback) {
std::string error_msg;
- std::unique_ptr<const DexFile> dex_file(oat_dex_file->OpenDexFile(&error_msg));
- if (dex_file.get() == nullptr) {
+ const DexFile* const dex_file = OpenDexFile(oat_dex_file, &error_msg);
+ if (dex_file == nullptr) {
return;
}
for (size_t class_def_index = 0;
@@ -172,7 +187,7 @@
switch (type) {
case kOatClassAllCompiled:
case kOatClassSomeCompiled:
- WalkOatClass(oat_class, *dex_file.get(), class_def, callback);
+ WalkOatClass(oat_class, *dex_file, class_def, callback);
break;
case kOatClassNoneCompiled:
@@ -504,8 +519,8 @@
const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
CHECK(oat_dex_file != nullptr);
std::string error_msg;
- std::unique_ptr<const DexFile> dex_file(oat_dex_file->OpenDexFile(&error_msg));
- if (dex_file.get() == nullptr) {
+ const DexFile* const dex_file = OpenDexFile(oat_dex_file, &error_msg);
+ if (dex_file == nullptr) {
LOG(WARNING) << "Failed to open dex file '" << oat_dex_file->GetDexFileLocation()
<< "': " << error_msg;
} else {
@@ -533,8 +548,8 @@
const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
CHECK(oat_dex_file != nullptr);
std::string error_msg;
- std::unique_ptr<const DexFile> dex_file(oat_dex_file->OpenDexFile(&error_msg));
- if (dex_file.get() == nullptr) {
+ const DexFile* const dex_file = OpenDexFile(oat_dex_file, &error_msg);
+ if (dex_file == nullptr) {
LOG(WARNING) << "Failed to open dex file '" << oat_dex_file->GetDexFileLocation()
<< "': " << error_msg;
continue;
@@ -593,8 +608,8 @@
// Create the verifier early.
std::string error_msg;
- std::unique_ptr<const DexFile> dex_file(oat_dex_file.OpenDexFile(&error_msg));
- if (dex_file.get() == nullptr) {
+ const DexFile* const dex_file = OpenDexFile(&oat_dex_file, &error_msg);
+ if (dex_file == nullptr) {
os << "NOT FOUND: " << error_msg << "\n\n";
os << std::flush;
return false;
@@ -621,7 +636,7 @@
<< " (" << oat_class.GetType() << ")\n";
// TODO: include bitmap here if type is kOatClassSomeCompiled?
if (options_.list_classes_) continue;
- if (!DumpOatClass(&vios, oat_class, *(dex_file.get()), class_def, &stop_analysis)) {
+ if (!DumpOatClass(&vios, oat_class, *dex_file, class_def, &stop_analysis)) {
success = false;
}
if (stop_analysis) {
@@ -638,7 +653,7 @@
std::string error_msg;
std::string dex_file_location = oat_dex_file.GetDexFileLocation();
- std::unique_ptr<const DexFile> dex_file(oat_dex_file.OpenDexFile(&error_msg));
+ const DexFile* const dex_file = OpenDexFile(&oat_dex_file, &error_msg);
if (dex_file == nullptr) {
os << "Failed to open dex file '" << dex_file_location << "': " << error_msg;
return false;
@@ -2337,21 +2352,17 @@
ScopedObjectAccess soa(self);
ClassLinker* class_linker = runtime->GetClassLinker();
class_linker->RegisterOatFile(oat_file);
- std::vector<std::unique_ptr<const DexFile>> dex_files;
+ std::vector<const DexFile*> class_path;
for (const OatFile::OatDexFile* odf : oat_file->GetOatDexFiles()) {
std::string error_msg;
- std::unique_ptr<const DexFile> dex_file = odf->OpenDexFile(&error_msg);
+ const DexFile* const dex_file = OpenDexFile(odf, &error_msg);
CHECK(dex_file != nullptr) << error_msg;
class_linker->RegisterDexFile(*dex_file);
- dex_files.push_back(std::move(dex_file));
+ class_path.push_back(dex_file);
}
// Need a class loader.
// Fake that we're a compiler.
- std::vector<const DexFile*> class_path;
- for (auto& dex_file : dex_files) {
- class_path.push_back(dex_file.get());
- }
jobject class_loader = class_linker->CreatePathClassLoader(self, class_path);
// Use the class loader while dumping.