diff options
Diffstat (limited to 'runtime/class_linker.cc')
| -rw-r--r-- | runtime/class_linker.cc | 84 |
1 files changed, 34 insertions, 50 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index a89196d830..12fa546460 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -242,7 +242,10 @@ ClassLinker::ClassLinker(InternTable* intern_table) quick_generic_jni_trampoline_(nullptr), quick_to_interpreter_bridge_trampoline_(nullptr), image_pointer_size_(sizeof(void*)) { - memset(find_array_class_cache_, 0, kFindArrayCacheSize * sizeof(mirror::Class*)); + CHECK(intern_table_ != nullptr); + for (size_t i = 0; i < kFindArrayCacheSize; ++i) { + find_array_class_cache_[i] = GcRoot<mirror::Class>(nullptr); + } } void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> boot_class_path) { @@ -693,35 +696,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) { @@ -937,19 +911,21 @@ void ClassLinker::InitFromImage() { VLOG(startup) << "ClassLinker::InitFromImage exiting"; } -void ClassLinker::VisitClassRoots(RootCallback* callback, void* arg, VisitRootFlags flags) { +void ClassLinker::VisitClassRoots(RootVisitor* visitor, VisitRootFlags flags) { WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); if ((flags & kVisitRootFlagAllRoots) != 0) { + BufferedRootVisitor<kDefaultBufferedRootCount> buffered_visitor( + visitor, RootInfo(kRootStickyClass)); for (GcRoot<mirror::Class>& root : class_table_) { - root.VisitRoot(callback, arg, RootInfo(kRootStickyClass)); + buffered_visitor.VisitRoot(root); } for (GcRoot<mirror::Class>& root : pre_zygote_class_table_) { - root.VisitRoot(callback, arg, RootInfo(kRootStickyClass)); + buffered_visitor.VisitRoot(root); } } else if ((flags & kVisitRootFlagNewRoots) != 0) { for (auto& root : new_class_roots_) { mirror::Class* old_ref = root.Read<kWithoutReadBarrier>(); - root.VisitRoot(callback, arg, RootInfo(kRootStickyClass)); + root.VisitRoot(visitor, RootInfo(kRootStickyClass)); mirror::Class* new_ref = root.Read<kWithoutReadBarrier>(); if (UNLIKELY(new_ref != old_ref)) { // Uh ohes, GC moved a root in the log. Need to search the class_table and update the @@ -976,18 +952,18 @@ void ClassLinker::VisitClassRoots(RootCallback* callback, void* arg, VisitRootFl // Keep in sync with InitCallback. Anything we visit, we need to // reinit references to when reinitializing a ClassLinker from a // mapped image. -void ClassLinker::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags flags) { - class_roots_.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); - Thread* self = Thread::Current(); +void ClassLinker::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) { + class_roots_.VisitRoot(visitor, RootInfo(kRootVMInternal)); + Thread* const self = Thread::Current(); { ReaderMutexLock mu(self, dex_lock_); if ((flags & kVisitRootFlagAllRoots) != 0) { for (GcRoot<mirror::DexCache>& dex_cache : dex_caches_) { - dex_cache.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); + dex_cache.VisitRoot(visitor, RootInfo(kRootVMInternal)); } } else if ((flags & kVisitRootFlagNewRoots) != 0) { for (size_t index : new_dex_cache_roots_) { - dex_caches_[index].VisitRoot(callback, arg, RootInfo(kRootVMInternal)); + dex_caches_[index].VisitRoot(visitor, RootInfo(kRootVMInternal)); } } if ((flags & kVisitRootFlagClearRootLog) != 0) { @@ -999,11 +975,10 @@ void ClassLinker::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags f log_new_dex_caches_roots_ = false; } } - VisitClassRoots(callback, arg, flags); - array_iftable_.VisitRoot(callback, arg, RootInfo(kRootVMInternal)); - DCHECK(!array_iftable_.IsNull()); + VisitClassRoots(visitor, flags); + array_iftable_.VisitRoot(visitor, RootInfo(kRootVMInternal)); for (size_t i = 0; i < kFindArrayCacheSize; ++i) { - find_array_class_cache_[i].VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal)); + find_array_class_cache_[i].VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); } } @@ -1600,7 +1575,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 +2788,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; @@ -3411,7 +3386,7 @@ bool ClassLinker::InitializeClass(Thread* self, Handle<mirror::Class> klass, // so we need to throw it again now. VLOG(compiler) << "Return from class initializer of " << PrettyDescriptor(klass.Get()) << " without exception while transaction was aborted: re-throw it now."; - Runtime::Current()->ThrowInternalErrorForAbortedTransaction(self); + Runtime::Current()->ThrowTransactionAbortError(self); mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self); success = false; } else { @@ -3845,9 +3820,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 +5278,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; |