Store OatDexFile instead of OatFile in DexFile.
This requires moving OatDexFile out of the OatFile class so that
a forward class declaration can be used for OatDexFile.
Bug: 19071355
Change-Id: Ibda85b78d0577e9e81073090616fc0f2fa526be3
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a89196d..a02d1ad 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -693,35 +693,6 @@
return *oat_file;
}
-const OatFile::OatDexFile* ClassLinker::FindOpenedOatDexFileForDexFile(const DexFile& dex_file) {
- const char* dex_location = dex_file.GetLocation().c_str();
- uint32_t dex_location_checksum = dex_file.GetLocationChecksum();
- return FindOpenedOatDexFile(nullptr, dex_location, &dex_location_checksum);
-}
-
-const OatFile::OatDexFile* ClassLinker::FindOpenedOatDexFile(const char* oat_location,
- const char* dex_location,
- const uint32_t* dex_location_checksum) {
- ReaderMutexLock mu(Thread::Current(), dex_lock_);
- for (const OatFile* oat_file : oat_files_) {
- DCHECK(oat_file != nullptr);
-
- if (oat_location != nullptr) {
- if (oat_file->GetLocation() != oat_location) {
- continue;
- }
- }
-
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location,
- dex_location_checksum,
- false);
- if (oat_dex_file != nullptr) {
- return oat_dex_file;
- }
- }
- return nullptr;
-}
-
std::vector<std::unique_ptr<const DexFile>> ClassLinker::OpenDexFilesFromOat(
const char* dex_location, const char* oat_location,
std::vector<std::string>* error_msgs) {
@@ -1600,7 +1571,7 @@
OatFile::OatClass ClassLinker::FindOatClass(const DexFile& dex_file, uint16_t class_def_idx,
bool* found) {
DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
- const OatFile::OatDexFile* oat_dex_file = FindOpenedOatDexFileForDexFile(dex_file);
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
if (oat_dex_file == nullptr) {
*found = false;
return OatFile::OatClass::Invalid();
@@ -2813,7 +2784,7 @@
}
}
- const OatFile::OatDexFile* oat_dex_file = FindOpenedOatDexFileForDexFile(dex_file);
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
// In case we run without an image there won't be a backing oat file.
if (oat_dex_file == nullptr) {
return false;
@@ -3845,9 +3816,19 @@
// Now comes the expensive part: things can be broken if (a) the klass' dex file has a
// definition for the super-class, and (b) the files are in separate oat files. The oat files
// are referenced from the dex file, so do (b) first. Only relevant if we have oat files.
- const OatFile* class_oat_file = dex_file.GetOatFile();
+ const OatDexFile* class_oat_dex_file = dex_file.GetOatDexFile();
+ const OatFile* class_oat_file = nullptr;
+ if (class_oat_dex_file != nullptr) {
+ class_oat_file = class_oat_dex_file->GetOatFile();
+ }
+
if (class_oat_file != nullptr) {
- const OatFile* loaded_super_oat_file = super_class->GetDexFile().GetOatFile();
+ const OatDexFile* loaded_super_oat_dex_file = super_class->GetDexFile().GetOatDexFile();
+ const OatFile* loaded_super_oat_file = nullptr;
+ if (loaded_super_oat_dex_file != nullptr) {
+ loaded_super_oat_file = loaded_super_oat_dex_file->GetOatFile();
+ }
+
if (loaded_super_oat_file != nullptr && class_oat_file != loaded_super_oat_file) {
// Now check (a).
const DexFile::ClassDef* super_class_def = dex_file.FindClassDef(class_def.superclass_idx_);
@@ -5293,9 +5274,8 @@
if (m->IsPrivate()) {
// The method can only be called inside its own oat file. Therefore it won't be called using
// its direct code if the oat file has been compiled in PIC mode.
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
const DexFile& dex_file = m->GetDeclaringClass()->GetDexFile();
- const OatFile::OatDexFile* oat_dex_file = class_linker->FindOpenedOatDexFileForDexFile(dex_file);
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
if (oat_dex_file == nullptr) {
// No oat file: the method has not been compiled.
return false;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index ec984cb..69a5337 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -600,17 +600,6 @@
}
mirror::DexCache* GetDexCache(size_t idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, dex_lock_);
- const OatFile::OatDexFile* FindOpenedOatDexFileForDexFile(const DexFile& dex_file)
- LOCKS_EXCLUDED(dex_lock_)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Find an opened oat dex file that contains dex_location. If oat_location is not nullptr,
- // the file must have that location, else any oat location is accepted.
- const OatFile::OatDexFile* FindOpenedOatDexFile(const char* oat_location,
- const char* dex_location,
- const uint32_t* dex_location_checksum)
- LOCKS_EXCLUDED(dex_lock_);
-
const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location)
LOCKS_EXCLUDED(dex_lock_);
@@ -739,8 +728,6 @@
friend class ImageWriter; // for GetClassRoots
friend class ImageDumper; // for FindOpenedOatFileFromOatLocation
friend class JniCompilerTest; // for GetRuntimeQuickGenericJniStub
- friend class NoDex2OatTest; // for FindOpenedOatFileForDexFile
- friend class NoPatchoatTest; // for FindOpenedOatFileForDexFile
ART_FRIEND_TEST(mirror::DexCacheTest, Open); // for AllocDexCache
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index edd8bfe..8685d8e 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -340,11 +340,11 @@
const std::string& location,
uint32_t location_checksum,
MemMap* mem_map,
- const OatFile* oat_file,
+ const OatDexFile* oat_dex_file,
std::string* error_msg) {
CHECK_ALIGNED(base, 4); // various dex file structures must be word aligned
std::unique_ptr<DexFile> dex_file(
- new DexFile(base, size, location, location_checksum, mem_map, oat_file));
+ new DexFile(base, size, location, location_checksum, mem_map, oat_dex_file));
if (!dex_file->Init(error_msg)) {
dex_file.reset();
}
@@ -355,7 +355,7 @@
const std::string& location,
uint32_t location_checksum,
MemMap* mem_map,
- const OatFile* oat_file)
+ const OatDexFile* oat_dex_file)
: begin_(base),
size_(size),
location_(location),
@@ -370,7 +370,7 @@
class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),
find_class_def_misses_(0),
class_def_index_(nullptr),
- oat_file_(oat_file) {
+ oat_dex_file_(oat_dex_file) {
CHECK(begin_ != NULL) << GetLocation();
CHECK_GT(size_, 0U) << GetLocation();
}
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index da39573..8e2d6c2 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -44,7 +44,7 @@
} // namespace mirror
class ClassLinker;
class MemMap;
-class OatFile;
+class OatDexFile;
class Signature;
template<class T> class Handle;
class StringPiece;
@@ -392,9 +392,9 @@
static std::unique_ptr<const DexFile> Open(const uint8_t* base, size_t size,
const std::string& location,
uint32_t location_checksum,
- const OatFile* oat_file,
+ const OatDexFile* oat_dex_file,
std::string* error_msg) {
- return OpenMemory(base, size, location, location_checksum, NULL, oat_file, error_msg);
+ return OpenMemory(base, size, location, location_checksum, NULL, oat_dex_file, error_msg);
}
// Open all classesXXX.dex files from a zip archive.
@@ -904,8 +904,8 @@
// the dex_location where it's file name part has been made canonical.
static std::string GetDexCanonicalLocation(const char* dex_location);
- const OatFile* GetOatFile() const {
- return oat_file_;
+ const OatDexFile* GetOatDexFile() const {
+ return oat_dex_file_;
}
private:
@@ -944,14 +944,14 @@
const std::string& location,
uint32_t location_checksum,
MemMap* mem_map,
- const OatFile* oat_file,
+ const OatDexFile* oat_dex_file,
std::string* error_msg);
DexFile(const uint8_t* base, size_t size,
const std::string& location,
uint32_t location_checksum,
MemMap* mem_map,
- const OatFile* oat_file);
+ const OatDexFile* oat_dex_file);
// Top-level initializer that calls other Init methods.
bool Init(std::string* error_msg);
@@ -1035,9 +1035,10 @@
typedef HashMap<const char*, const ClassDef*, UTF16EmptyFn, UTF16HashCmp, UTF16HashCmp> Index;
mutable Atomic<Index*> class_def_index_;
- // The oat file this dex file was loaded from. May be null in case the dex file is not coming
- // from an oat file, e.g., directly from an apk.
- const OatFile* oat_file_;
+ // If this dex file was loaded from an oat file, oat_dex_file_ contains a
+ // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
+ // null.
+ const OatDexFile* oat_dex_file_;
};
struct DexFileReference {
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 69cb22d..81703b1 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -453,7 +453,7 @@
std::unique_ptr<const DexFile> OatFile::OatDexFile::OpenDexFile(std::string* error_msg) const {
return DexFile::Open(dex_file_pointer_, FileSize(), dex_file_location_,
- dex_file_location_checksum_, GetOatFile(), error_msg);
+ dex_file_location_checksum_, this, error_msg);
}
uint32_t OatFile::OatDexFile::GetOatClassOffset(uint16_t class_def_index) const {
@@ -495,12 +495,12 @@
CHECK_LE(methods_pointer, oat_file_->End()) << oat_file_->GetLocation();
}
- return OatClass(oat_file_,
- status,
- type,
- bitmap_size,
- reinterpret_cast<const uint32_t*>(bitmap_pointer),
- reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
+ return OatFile::OatClass(oat_file_,
+ status,
+ type,
+ bitmap_size,
+ reinterpret_cast<const uint32_t*>(bitmap_pointer),
+ reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
}
OatFile::OatClass::OatClass(const OatFile* oat_file,
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 51952f3..2b9ef9d 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -37,9 +37,12 @@
class MemMap;
class OatMethodOffsets;
class OatHeader;
+class OatDexFile;
-class OatFile {
+class OatFile FINAL {
public:
+ typedef art::OatDexFile OatDexFile;
+
// Opens an oat file contained within the given elf file. This is always opened as
// non-executable at the moment.
static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location,
@@ -90,9 +93,7 @@
const OatHeader& GetOatHeader() const;
- class OatDexFile;
-
- class OatMethod {
+ class OatMethod FINAL {
public:
void LinkMethod(mirror::ArtMethod* method) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -156,7 +157,7 @@
friend class OatClass;
};
- class OatClass {
+ class OatClass FINAL {
public:
mirror::Class::Status GetStatus() const {
return status_;
@@ -207,63 +208,8 @@
const OatMethodOffsets* const methods_pointer_;
- friend class OatDexFile;
+ friend class art::OatDexFile;
};
-
- class OatDexFile {
- public:
- // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
- std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
-
- const OatFile* GetOatFile() const {
- return oat_file_;
- }
-
- // Returns the size of the DexFile refered to by this OatDexFile.
- size_t FileSize() const;
-
- // Returns original path of DexFile that was the source of this OatDexFile.
- const std::string& GetDexFileLocation() const {
- return dex_file_location_;
- }
-
- // Returns the canonical location of DexFile that was the source of this OatDexFile.
- const std::string& GetCanonicalDexFileLocation() const {
- return canonical_dex_file_location_;
- }
-
- // Returns checksum of original DexFile that was the source of this OatDexFile;
- uint32_t GetDexFileLocationChecksum() const {
- return dex_file_location_checksum_;
- }
-
- // Returns the OatClass for the class specified by the given DexFile class_def_index.
- OatClass GetOatClass(uint16_t class_def_index) const;
-
- // Returns the offset to the OatClass information. Most callers should use GetOatClass.
- uint32_t GetOatClassOffset(uint16_t class_def_index) const;
-
- ~OatDexFile();
-
- private:
- OatDexFile(const OatFile* oat_file,
- const std::string& dex_file_location,
- const std::string& canonical_dex_file_location,
- uint32_t dex_file_checksum,
- const uint8_t* dex_file_pointer,
- const uint32_t* oat_class_offsets_pointer);
-
- const OatFile* const oat_file_;
- const std::string dex_file_location_;
- const std::string canonical_dex_file_location_;
- const uint32_t dex_file_location_checksum_;
- const uint8_t* const dex_file_pointer_;
- const uint32_t* const oat_class_offsets_pointer_;
-
- friend class OatFile;
- DISALLOW_COPY_AND_ASSIGN(OatDexFile);
- };
-
const OatDexFile* GetOatDexFile(const char* dex_location,
const uint32_t* const dex_location_checksum,
bool exception_if_not_found = true) const
@@ -382,11 +328,69 @@
mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
friend class OatClass;
- friend class OatDexFile;
+ friend class art::OatDexFile;
friend class OatDumper; // For GetBase and GetLimit
DISALLOW_COPY_AND_ASSIGN(OatFile);
};
+// OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't
+// support forward declarations of inner classes, and we want to
+// forward-declare OatDexFile so that we can store an opaque pointer to an
+// OatDexFile in DexFile.
+class OatDexFile FINAL {
+ public:
+ // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
+ std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
+
+ const OatFile* GetOatFile() const {
+ return oat_file_;
+ }
+
+ // Returns the size of the DexFile refered to by this OatDexFile.
+ size_t FileSize() const;
+
+ // Returns original path of DexFile that was the source of this OatDexFile.
+ const std::string& GetDexFileLocation() const {
+ return dex_file_location_;
+ }
+
+ // Returns the canonical location of DexFile that was the source of this OatDexFile.
+ const std::string& GetCanonicalDexFileLocation() const {
+ return canonical_dex_file_location_;
+ }
+
+ // Returns checksum of original DexFile that was the source of this OatDexFile;
+ uint32_t GetDexFileLocationChecksum() const {
+ return dex_file_location_checksum_;
+ }
+
+ // Returns the OatClass for the class specified by the given DexFile class_def_index.
+ OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
+
+ // Returns the offset to the OatClass information. Most callers should use GetOatClass.
+ uint32_t GetOatClassOffset(uint16_t class_def_index) const;
+
+ ~OatDexFile();
+
+ private:
+ OatDexFile(const OatFile* oat_file,
+ const std::string& dex_file_location,
+ const std::string& canonical_dex_file_location,
+ uint32_t dex_file_checksum,
+ const uint8_t* dex_file_pointer,
+ const uint32_t* oat_class_offsets_pointer);
+
+ const OatFile* const oat_file_;
+ const std::string dex_file_location_;
+ const std::string canonical_dex_file_location_;
+ const uint32_t dex_file_location_checksum_;
+ const uint8_t* const dex_file_pointer_;
+ const uint32_t* const oat_class_offsets_pointer_;
+
+ friend class OatFile;
+ DISALLOW_COPY_AND_ASSIGN(OatDexFile);
+};
+
} // namespace art
#endif // ART_RUNTIME_OAT_FILE_H_
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index a8b0876..a198824 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -787,7 +787,8 @@
std::vector<std::string> error_msgs;
dex_files = linker->OpenDexFilesFromOat(dex_location_.c_str(), oat_location_.c_str(), &error_msgs);
CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
- loaded_oat_file_ = dex_files[0]->GetOatFile();
+ CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
+ loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
}
const OatFile* GetLoadedOatFile() const {
diff --git a/test/116-nodex2oat/nodex2oat.cc b/test/116-nodex2oat/nodex2oat.cc
index 564d58d..131af31 100644
--- a/test/116-nodex2oat/nodex2oat.cc
+++ b/test/116-nodex2oat/nodex2oat.cc
@@ -28,8 +28,7 @@
ScopedObjectAccess soa(Thread::Current());
mirror::Class* klass = soa.Decode<mirror::Class*>(cls);
const DexFile& dex_file = klass->GetDexFile();
- const OatFile::OatDexFile* oat_dex_file =
- Runtime::Current()->GetClassLinker()->FindOpenedOatDexFileForDexFile(dex_file);
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
return oat_dex_file != nullptr;
}
};
diff --git a/test/117-nopatchoat/nopatchoat.cc b/test/117-nopatchoat/nopatchoat.cc
index da276f2..7eac412 100644
--- a/test/117-nopatchoat/nopatchoat.cc
+++ b/test/117-nopatchoat/nopatchoat.cc
@@ -28,11 +28,7 @@
ScopedObjectAccess soa(Thread::Current());
mirror::Class* klass = soa.Decode<mirror::Class*>(cls);
const DexFile& dex_file = klass->GetDexFile();
-
- const OatFile::OatDexFile* oat_dex_file =
- Runtime::Current()->GetClassLinker()->FindOpenedOatDexFileForDexFile(dex_file);
-
- return oat_dex_file;
+ return dex_file.GetOatDexFile();
}
static bool hasExecutableOat(jclass cls) {
diff --git a/test/118-noimage-dex2oat/noimage-dex2oat.cc b/test/118-noimage-dex2oat/noimage-dex2oat.cc
index c49a13e..aacf00f 100644
--- a/test/118-noimage-dex2oat/noimage-dex2oat.cc
+++ b/test/118-noimage-dex2oat/noimage-dex2oat.cc
@@ -28,8 +28,7 @@
ScopedObjectAccess soa(Thread::Current());
mirror::Class* klass = soa.Decode<mirror::Class*>(cls);
const DexFile& dex_file = klass->GetDexFile();
- const OatFile::OatDexFile* oat_dex_file =
- Runtime::Current()->GetClassLinker()->FindOpenedOatDexFileForDexFile(dex_file);
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
return oat_dex_file != nullptr;
}
};