summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc84
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;