diff options
-rw-r--r-- | runtime/class_linker.cc | 50 | ||||
-rw-r--r-- | runtime/class_linker.h | 13 | ||||
-rw-r--r-- | runtime/dex_file.cc | 8 | ||||
-rw-r--r-- | runtime/dex_file.h | 21 | ||||
-rw-r--r-- | runtime/oat_file.cc | 14 | ||||
-rw-r--r-- | runtime/oat_file.h | 128 | ||||
-rw-r--r-- | runtime/oat_file_assistant_test.cc | 3 | ||||
-rw-r--r-- | test/116-nodex2oat/nodex2oat.cc | 3 | ||||
-rw-r--r-- | test/117-nopatchoat/nopatchoat.cc | 6 | ||||
-rw-r--r-- | test/118-noimage-dex2oat/noimage-dex2oat.cc | 3 |
10 files changed, 108 insertions, 141 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index a89196d830..a02d1ad770 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -693,35 +693,6 @@ OatFile& ClassLinker::GetImageOatFile(gc::space::ImageSpace* space) { 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 @@ uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file, 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 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class } } - 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 @@ static bool CheckSuperClassChange(Handle<mirror::Class> klass, // 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 @@ bool ClassLinker::MayBeCalledWithDirectCodePointer(mirror::ArtMethod* m) { 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 ec984cb703..69a5337369 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -600,17 +600,6 @@ class ClassLinker { } 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 @@ class ClassLinker { 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 edd8bfeefb..8685d8e73c 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -340,11 +340,11 @@ std::unique_ptr<const DexFile> DexFile::OpenMemory(const uint8_t* base, 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 @@ DexFile::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) : begin_(base), size_(size), location_(location), @@ -370,7 +370,7 @@ DexFile::DexFile(const uint8_t* base, size_t size, 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 da395734d3..8e2d6c2a55 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -44,7 +44,7 @@ namespace mirror { } // namespace mirror class ClassLinker; class MemMap; -class OatFile; +class OatDexFile; class Signature; template<class T> class Handle; class StringPiece; @@ -392,9 +392,9 @@ class DexFile { 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 @@ class DexFile { // 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 @@ class DexFile { 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 @@ class DexFile { 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 69cb22d07a..81703b1b2a 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -453,7 +453,7 @@ size_t OatFile::OatDexFile::FileSize() const { 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 @@ OatFile::OatClass OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) con 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 51952f318c..2b9ef9da71 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -37,9 +37,12 @@ class ElfFile; 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 @@ class OatFile { 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 @@ class OatFile { friend class OatClass; }; - class OatClass { + class OatClass FINAL { public: mirror::Class::Status GetStatus() const { return status_; @@ -207,63 +208,8 @@ class OatFile { 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 @@ class OatFile { 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 a8b08766d3..a1988244c7 100644 --- a/runtime/oat_file_assistant_test.cc +++ b/runtime/oat_file_assistant_test.cc @@ -787,7 +787,8 @@ class RaceGenerateTask : public Task { 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 564d58d251..131af312be 100644 --- a/test/116-nodex2oat/nodex2oat.cc +++ b/test/116-nodex2oat/nodex2oat.cc @@ -28,8 +28,7 @@ class NoDex2OatTest { 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 da276f2b52..7eac412681 100644 --- a/test/117-nopatchoat/nopatchoat.cc +++ b/test/117-nopatchoat/nopatchoat.cc @@ -28,11 +28,7 @@ class NoPatchoatTest { 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 c49a13e8f4..aacf00f300 100644 --- a/test/118-noimage-dex2oat/noimage-dex2oat.cc +++ b/test/118-noimage-dex2oat/noimage-dex2oat.cc @@ -28,8 +28,7 @@ class NoDex2OatTest { 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; } }; |