diff options
Diffstat (limited to 'src/class_linker.cc')
| -rw-r--r-- | src/class_linker.cc | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index cfad9d1b7d..0fae4248e9 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -44,7 +44,7 @@ #include "mirror/class.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" -#include "mirror/dex_cache.h" +#include "mirror/dex_cache-inl.h" #include "mirror/field-inl.h" #include "mirror/iftable-inl.h" #include "mirror/abstract_method.h" @@ -74,7 +74,9 @@ namespace art { -void artInterpreterToQuickEntry(Thread* self, ShadowFrame* shadow_frame, JValue* result); +extern "C" void artInterpreterToQuickEntry(Thread* self, MethodHelper& mh, + const DexFile::CodeItem* code_item, + ShadowFrame* shadow_frame, JValue* result); static void ThrowNoClassDefFoundError(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2))) @@ -195,12 +197,14 @@ ClassLinker* ClassLinker::CreateFromImage(InternTable* intern_table) { ClassLinker::ClassLinker(InternTable* intern_table) // dex_lock_ is recursive as it may be used in stack dumping. - : dex_lock_("ClassLinker dex lock", kDefaultMutexLevel, true), + : dex_lock_("ClassLinker dex lock", kDefaultMutexLevel), class_roots_(NULL), array_iftable_(NULL), init_done_(false), is_dirty_(false), - intern_table_(intern_table) { + intern_table_(intern_table), + portable_resolution_trampoline_(NULL), + quick_resolution_trampoline_(NULL) { CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax)); } @@ -662,22 +666,22 @@ bool ClassLinker::GenerateOatFile(const std::string& dex_filename, } void ClassLinker::RegisterOatFile(const OatFile& oat_file) { - MutexLock mu(Thread::Current(), dex_lock_); + WriterMutexLock mu(Thread::Current(), dex_lock_); RegisterOatFileLocked(oat_file); } void ClassLinker::RegisterOatFileLocked(const OatFile& oat_file) { - dex_lock_.AssertHeld(Thread::Current()); -#ifndef NDEBUG - for (size_t i = 0; i < oat_files_.size(); ++i) { - CHECK_NE(&oat_file, oat_files_[i]) << oat_file.GetLocation(); + dex_lock_.AssertExclusiveHeld(Thread::Current()); + if (kIsDebugBuild) { + for (size_t i = 0; i < oat_files_.size(); ++i) { + CHECK_NE(&oat_file, oat_files_[i]) << oat_file.GetLocation(); + } } -#endif oat_files_.push_back(&oat_file); } OatFile* ClassLinker::OpenOat(const ImageSpace* space) { - MutexLock mu(Thread::Current(), dex_lock_); + WriterMutexLock mu(Thread::Current(), dex_lock_); const Runtime* runtime = Runtime::Current(); const ImageHeader& image_header = space->GetImageHeader(); // Grab location but don't use Object::AsString as we haven't yet initialized the roots to @@ -708,7 +712,7 @@ OatFile* ClassLinker::OpenOat(const ImageSpace* space) { } const OatFile* ClassLinker::FindOpenedOatFileForDexFile(const DexFile& dex_file) { - MutexLock mu(Thread::Current(), dex_lock_); + ReaderMutexLock mu(Thread::Current(), dex_lock_); return FindOpenedOatFileFromDexLocation(dex_file.GetLocation()); } @@ -754,7 +758,7 @@ static const DexFile* FindDexFileInOatLocation(const std::string& dex_location, const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& dex_location, const std::string& oat_location) { - MutexLock mu(Thread::Current(), dex_lock_); + WriterMutexLock mu(Thread::Current(), dex_lock_); return FindOrCreateOatFileForDexLocationLocked(dex_location, oat_location); } @@ -856,7 +860,7 @@ const DexFile* ClassLinker::VerifyAndOpenDexFileFromOatFile(const OatFile* oat_f } const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) { - MutexLock mu(Thread::Current(), dex_lock_); + WriterMutexLock mu(Thread::Current(), dex_lock_); const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location); if (open_oat_file != NULL) { @@ -923,7 +927,7 @@ const OatFile* ClassLinker::FindOpenedOatFileFromOatLocation(const std::string& } const OatFile* ClassLinker::FindOatFileFromOatLocation(const std::string& oat_location) { - MutexLock mu(Thread::Current(), dex_lock_); + ReaderMutexLock mu(Thread::Current(), dex_lock_); return FindOatFileFromOatLocationLocked(oat_location); } @@ -951,6 +955,8 @@ void ClassLinker::InitFromImage() { CHECK_EQ(oat_file->GetOatHeader().GetImageFileLocationOatChecksum(), 0U); CHECK_EQ(oat_file->GetOatHeader().GetImageFileLocationOatDataBegin(), 0U); CHECK(oat_file->GetOatHeader().GetImageFileLocation().empty()); + portable_resolution_trampoline_ = oat_file->GetOatHeader().GetPortableResolutionTrampoline(); + quick_resolution_trampoline_ = oat_file->GetOatHeader().GetQuickResolutionTrampoline(); mirror::Object* dex_caches_object = space->GetImageHeader().GetImageRoot(ImageHeader::kDexCaches); mirror::ObjectArray<mirror::DexCache>* dex_caches = dex_caches_object->AsObjectArray<mirror::DexCache>(); @@ -1037,17 +1043,12 @@ void ClassLinker::InitFromImageCallback(mirror::Object* obj, void* arg) { return; } - // Check if object is a method without its code set and point it to the resolution trampoline. + // Set entry points to interpreter for methods in interpreter only mode. if (obj->IsMethod()) { mirror::AbstractMethod* method = obj->AsMethod(); - // Install entry point from interpreter. - if (method->GetEntryPointFromCompiledCode() == NULL && !method->IsNative() && !method->IsProxyMethod()) { - method->SetEntryPointFromInterpreter(interpreter::EnterInterpreterFromInterpreter); - } else { - method->SetEntryPointFromInterpreter(artInterpreterToQuickEntry); - } - if (method->GetEntryPointFromCompiledCode() == NULL) { - method->SetEntryPointFromCompiledCode(GetResolutionTrampoline()); + if (Runtime::Current()->GetInstrumentation()->InterpretOnly() && !method->IsNative()) { + method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterEntry); + method->SetEntryPointFromCompiledCode(GetInterpreterEntryPoint()); } } } @@ -1059,14 +1060,14 @@ void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg) { visitor(class_roots_, arg); Thread* self = Thread::Current(); { - MutexLock mu(self, dex_lock_); + ReaderMutexLock mu(self, dex_lock_); for (size_t i = 0; i < dex_caches_.size(); i++) { visitor(dex_caches_[i], arg); } } { - MutexLock mu(self, *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); typedef Table::const_iterator It; // TODO: C++0x auto for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) { visitor(it->second, arg); @@ -1081,7 +1082,7 @@ void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg) { } void ClassLinker::VisitClasses(ClassVisitor* visitor, void* arg) const { - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); typedef Table::const_iterator It; // TODO: C++0x auto for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) { if (!visitor(it->second, arg)) { @@ -1608,14 +1609,16 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat oat_method.LinkMethod(method.get()); // Install entry point from interpreter. - if (method->GetEntryPointFromCompiledCode() == NULL && !method->IsNative() && - !method->IsProxyMethod()) { - method->SetEntryPointFromInterpreter(interpreter::EnterInterpreterFromInterpreter); + Runtime* runtime = Runtime::Current(); + bool enter_interpreter = method->GetEntryPointFromCompiledCode() == NULL || + (runtime->GetInstrumentation()->InterpretOnly() && + !method->IsNative() && !method->IsProxyMethod()); + if (enter_interpreter) { + method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterEntry); } else { method->SetEntryPointFromInterpreter(artInterpreterToQuickEntry); } - Runtime* runtime = Runtime::Current(); if (method->IsAbstract()) { method->SetEntryPointFromCompiledCode(GetAbstractMethodErrorStub()); return; @@ -1623,7 +1626,7 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat if (method->IsStatic() && !method->IsConstructor()) { // For static methods excluding the class initializer, install the trampoline. - method->SetEntryPointFromCompiledCode(GetResolutionTrampoline()); + method->SetEntryPointFromCompiledCode(GetResolutionTrampoline(runtime->GetClassLinker())); } if (method->IsNative()) { @@ -1631,8 +1634,8 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat method->UnregisterNative(Thread::Current()); } - if (method->GetEntryPointFromCompiledCode() == NULL) { - // No code? You must mean to go into the interpreter. + if (enter_interpreter) { + // Set entry point from compiled code if there's no code or in interpreter only mode. method->SetEntryPointFromCompiledCode(GetInterpreterEntryPoint()); } @@ -1807,7 +1810,7 @@ void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, SirtRef<mirror: } bool ClassLinker::IsDexFileRegisteredLocked(const DexFile& dex_file) const { - dex_lock_.AssertHeld(Thread::Current()); + dex_lock_.AssertSharedHeld(Thread::Current()); for (size_t i = 0; i != dex_caches_.size(); ++i) { if (dex_caches_[i]->GetDexFile() == &dex_file) { return true; @@ -1817,12 +1820,12 @@ bool ClassLinker::IsDexFileRegisteredLocked(const DexFile& dex_file) const { } bool ClassLinker::IsDexFileRegistered(const DexFile& dex_file) const { - MutexLock mu(Thread::Current(), dex_lock_); + ReaderMutexLock mu(Thread::Current(), dex_lock_); return IsDexFileRegisteredLocked(dex_file); } void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) { - dex_lock_.AssertHeld(Thread::Current()); + dex_lock_.AssertExclusiveHeld(Thread::Current()); CHECK(dex_cache.get() != NULL) << dex_file.GetLocation(); CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation())); dex_caches_.push_back(dex_cache.get()); @@ -1833,7 +1836,7 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror: void ClassLinker::RegisterDexFile(const DexFile& dex_file) { Thread* self = Thread::Current(); { - MutexLock mu(self, dex_lock_); + ReaderMutexLock mu(self, dex_lock_); if (IsDexFileRegisteredLocked(dex_file)) { return; } @@ -1843,7 +1846,7 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file) { // get to a suspend point. SirtRef<mirror::DexCache> dex_cache(self, AllocDexCache(self, dex_file)); { - MutexLock mu(self, dex_lock_); + WriterMutexLock mu(self, dex_lock_); if (IsDexFileRegisteredLocked(dex_file)) { return; } @@ -1852,12 +1855,12 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file) { } void ClassLinker::RegisterDexFile(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) { - MutexLock mu(Thread::Current(), dex_lock_); + WriterMutexLock mu(Thread::Current(), dex_lock_); RegisterDexFileLocked(dex_file, dex_cache); } mirror::DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const { - MutexLock mu(Thread::Current(), dex_lock_); + ReaderMutexLock mu(Thread::Current(), dex_lock_); // Search assuming unique-ness of dex file. for (size_t i = 0; i != dex_caches_.size(); ++i) { mirror::DexCache* dex_cache = dex_caches_[i]; @@ -1883,7 +1886,7 @@ mirror::DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const { } void ClassLinker::FixupDexCaches(mirror::AbstractMethod* resolution_method) const { - MutexLock mu(Thread::Current(), dex_lock_); + ReaderMutexLock mu(Thread::Current(), dex_lock_); for (size_t i = 0; i != dex_caches_.size(); ++i) { dex_caches_[i]->Fixup(resolution_method); } @@ -2079,7 +2082,7 @@ mirror::Class* ClassLinker::InsertClass(const StringPiece& descriptor, mirror::C LOG(INFO) << "Loaded class " << descriptor << source; } size_t hash = StringPieceHash()(descriptor); - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); Table& classes = image_class ? image_classes_ : classes_; mirror::Class* existing = LookupClassLocked(descriptor.data(), klass->GetClassLoader(), hash, classes); #ifndef NDEBUG @@ -2097,7 +2100,7 @@ mirror::Class* ClassLinker::InsertClass(const StringPiece& descriptor, mirror::C bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* class_loader) { size_t hash = Hash(descriptor); - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); typedef Table::iterator It; // TODO: C++0x auto // TODO: determine if its better to search classes_ or image_classes_ first ClassHelper kh; @@ -2125,7 +2128,7 @@ bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* mirror::Class* ClassLinker::LookupClass(const char* descriptor, const mirror::ClassLoader* class_loader) { size_t hash = Hash(descriptor); - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); // TODO: determine if its better to search classes_ or image_classes_ first mirror::Class* klass = NULL; // Use image class only if the class_loader is null. @@ -2165,7 +2168,7 @@ mirror::Class* ClassLinker::LookupClassLocked(const char* descriptor, void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Class*>& classes) { classes.clear(); size_t hash = Hash(descriptor); - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); typedef Table::const_iterator It; // TODO: C++0x auto // TODO: determine if its better to search classes_ or image_classes_ first ClassHelper kh(NULL, this); @@ -2499,7 +2502,7 @@ mirror::AbstractMethod* ClassLinker::FindMethodForProxy(const mirror::Class* pro mirror::DexCache* dex_cache = NULL; { mirror::ObjectArray<mirror::Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes(); - MutexLock mu(Thread::Current(), dex_lock_); + ReaderMutexLock mu(Thread::Current(), dex_lock_); for (size_t i = 0; i != dex_caches_.size(); ++i) { if (dex_caches_[i]->GetResolvedTypes() == resolved_types) { dex_cache = dex_caches_[i]; @@ -3880,7 +3883,7 @@ void ClassLinker::DumpAllClasses(int flags) const { // lock held, because it might need to resolve a field's type, which would try to take the lock. std::vector<mirror::Class*> all_classes; { - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); typedef Table::const_iterator It; // TODO: C++0x auto for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) { all_classes.push_back(it->second); @@ -3896,13 +3899,13 @@ void ClassLinker::DumpAllClasses(int flags) const { } void ClassLinker::DumpForSigQuit(std::ostream& os) const { - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); os << "Loaded classes: " << image_classes_.size() << " image classes; " << classes_.size() << " allocated classes\n"; } size_t ClassLinker::NumLoadedClasses() const { - MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); return classes_.size() + image_classes_.size(); } |