diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 156 |
1 files changed, 88 insertions, 68 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 16cddd5f71..4474f1be5b 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -64,7 +64,7 @@ #include "ScopedLocalRef.h" #include "scoped_thread_state_change.h" #include "handle_scope-inl.h" -#include "thread.h" +#include "thread-inl.h" #include "utils.h" #include "verifier/method_verifier.h" #include "well_known_classes.h" @@ -89,21 +89,29 @@ static void ThrowEarlierClassFailure(mirror::Class* c) // a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we // failed in verification, in which case v2 5.4.1 says we need to re-throw // the previous error. - if (!Runtime::Current()->IsCompiler()) { // Give info if this occurs at runtime. + Runtime* runtime = Runtime::Current(); + bool is_compiler = runtime->IsCompiler(); + if (!is_compiler) { // Give info if this occurs at runtime. LOG(INFO) << "Rejecting re-init on previously-failed class " << PrettyClass(c); } CHECK(c->IsErroneous()) << PrettyClass(c) << " " << c->GetStatus(); Thread* self = Thread::Current(); - ThrowLocation throw_location = self->GetCurrentLocationForThrow(); - if (c->GetVerifyErrorClass() != NULL) { - // TODO: change the verifier to store an _instance_, with a useful detail message? - std::string temp; - self->ThrowNewException(throw_location, c->GetVerifyErrorClass()->GetDescriptor(&temp), - PrettyDescriptor(c).c_str()); + if (is_compiler) { + // At compile time, accurate errors and NCDFE are disabled to speed compilation. + mirror::Throwable* pre_allocated = runtime->GetPreAllocatedNoClassDefFoundError(); + self->SetException(ThrowLocation(), pre_allocated); } else { - self->ThrowNewException(throw_location, "Ljava/lang/NoClassDefFoundError;", - PrettyDescriptor(c).c_str()); + ThrowLocation throw_location = self->GetCurrentLocationForThrow(); + if (c->GetVerifyErrorClass() != NULL) { + // TODO: change the verifier to store an _instance_, with a useful detail message? + std::string temp; + self->ThrowNewException(throw_location, c->GetVerifyErrorClass()->GetDescriptor(&temp), + PrettyDescriptor(c).c_str()); + } else { + self->ThrowNewException(throw_location, "Ljava/lang/NoClassDefFoundError;", + PrettyDescriptor(c).c_str()); + } } } @@ -438,7 +446,7 @@ void ClassLinker::InitWithoutImage(const std::vector<const DexFile*>& boot_class for (size_t i = 0; i != boot_class_path.size(); ++i) { const DexFile* dex_file = boot_class_path[i]; CHECK(dex_file != NULL); - AppendToBootClassPath(*dex_file); + AppendToBootClassPath(self, *dex_file); } // now we can use FindSystemClass @@ -666,7 +674,7 @@ void ClassLinker::RunRootClinits() { if (!c->IsArrayClass() && !c->IsPrimitive()) { StackHandleScope<1> hs(self); Handle<mirror::Class> h_class(hs.NewHandle(GetClassRoot(ClassRoot(i)))); - EnsureInitialized(h_class, true, true); + EnsureInitialized(self, h_class, true, true); self->AssertNoPendingException(); } } @@ -1880,7 +1888,7 @@ void ClassLinker::VisitClassesWithoutClassesLock(ClassVisitor* visitor, void* ar while (!local_arg.success) { size_t class_table_size; { - ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); class_table_size = class_table_.size(); } mirror::Class* class_type = mirror::Class::GetJavaLangClass(); @@ -2024,7 +2032,7 @@ mirror::Class* ClassLinker::EnsureResolved(Thread* self, const char* descriptor, } CHECK(h_class->IsRetired()); // Get the updated class from class table. - klass = LookupClass(descriptor, h_class.Get()->GetClassLoader()); + klass = LookupClass(self, descriptor, h_class.Get()->GetClassLoader()); } // Wait for the class if it has not already been linked. @@ -2083,11 +2091,11 @@ mirror::Class* ClassLinker::FindClassInPathClassLoader(ScopedObjectAccessAlready ClassPathEntry pair = FindInClassPath(descriptor, boot_class_path_); // Check if this would be found in the parent boot class loader. if (pair.second != nullptr) { - mirror::Class* klass = LookupClass(descriptor, nullptr); + mirror::Class* klass = LookupClass(self, descriptor, nullptr); if (klass != nullptr) { return EnsureResolved(self, descriptor, klass); } - klass = DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, + klass = DefineClass(self, descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second); if (klass != nullptr) { return klass; @@ -2139,7 +2147,7 @@ mirror::Class* ClassLinker::FindClassInPathClassLoader(ScopedObjectAccessAlready if (dex_class_def != nullptr) { RegisterDexFile(*dex_file); mirror::Class* klass = - DefineClass(descriptor, class_loader, *dex_file, *dex_class_def); + DefineClass(self, descriptor, class_loader, *dex_file, *dex_class_def); if (klass == nullptr) { CHECK(self->IsExceptionPending()) << descriptor; self->ClearException(); @@ -2167,7 +2175,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, return FindPrimitiveClass(descriptor[0]); } // Find the class in the loaded classes table. - mirror::Class* klass = LookupClass(descriptor, class_loader.Get()); + mirror::Class* klass = LookupClass(self, descriptor, class_loader.Get()); if (klass != nullptr) { return EnsureResolved(self, descriptor, klass); } @@ -2178,7 +2186,8 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, // The boot class loader, search the boot class path. ClassPathEntry pair = FindInClassPath(descriptor, boot_class_path_); if (pair.second != nullptr) { - return DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second); + return DefineClass(self, descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, + *pair.second); } else { // The boot class loader is searched ahead of the application class loader, failures are // expected and will be wrapped in a ClassNotFoundException. Use the pre-allocated error to @@ -2190,7 +2199,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, } else if (Runtime::Current()->UseCompileTimeClassPath()) { // First try with the bootstrap class loader. if (class_loader.Get() != nullptr) { - klass = LookupClass(descriptor, nullptr); + klass = LookupClass(self, descriptor, nullptr); if (klass != nullptr) { return EnsureResolved(self, descriptor, klass); } @@ -2199,7 +2208,8 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, // a NoClassDefFoundError being allocated. ClassPathEntry pair = FindInClassPath(descriptor, boot_class_path_); if (pair.second != nullptr) { - return DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second); + return DefineClass(self, descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, + *pair.second); } // Next try the compile time class path. const std::vector<const DexFile*>* class_path; @@ -2211,7 +2221,12 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, } pair = FindInClassPath(descriptor, *class_path); if (pair.second != nullptr) { - return DefineClass(descriptor, class_loader, *pair.first, *pair.second); + return DefineClass(self, descriptor, class_loader, *pair.first, *pair.second); + } else { + // Use the pre-allocated NCDFE at compile time to avoid wasting time constructing exceptions. + mirror::Throwable* pre_allocated = Runtime::Current()->GetPreAllocatedNoClassDefFoundError(); + self->SetException(ThrowLocation(), pre_allocated); + return nullptr; } } else { ScopedObjectAccessUnchecked soa(self); @@ -2254,11 +2269,10 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, return nullptr; } -mirror::Class* ClassLinker::DefineClass(const char* descriptor, +mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, ConstHandle<mirror::ClassLoader> class_loader, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def) { - Thread* self = Thread::Current(); StackHandleScope<3> hs(self); auto klass = hs.NewHandle<mirror::Class>(nullptr); bool should_allocate = false; @@ -2299,7 +2313,7 @@ mirror::Class* ClassLinker::DefineClass(const char* descriptor, return nullptr; } klass->SetDexCache(FindDexCache(dex_file)); - LoadClass(dex_file, dex_class_def, klass, class_loader.Get()); + LoadClass(self, dex_file, dex_class_def, klass, class_loader.Get()); ObjectLock<mirror::Class> lock(self, klass); if (self->IsExceptionPending()) { // An exception occured during load, set status to erroneous while holding klass' lock in case @@ -2764,7 +2778,7 @@ void ClassLinker::LinkCode(ConstHandle<mirror::ArtMethod> method, -void ClassLinker::LoadClass(const DexFile& dex_file, +void ClassLinker::LoadClass(Thread* self, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, ConstHandle<mirror::Class> klass, mirror::ClassLoader* class_loader) { @@ -2800,22 +2814,21 @@ void ClassLinker::LoadClass(const DexFile& dex_file, OatFile::OatClass oat_class = FindOatClass(dex_file, klass->GetDexClassDefIndex(), &has_oat_class); if (has_oat_class) { - LoadClassMembers(dex_file, class_data, klass, class_loader, &oat_class); + LoadClassMembers(self, dex_file, class_data, klass, class_loader, &oat_class); } } if (!has_oat_class) { - LoadClassMembers(dex_file, class_data, klass, class_loader, nullptr); + LoadClassMembers(self, dex_file, class_data, klass, class_loader, nullptr); } } -void ClassLinker::LoadClassMembers(const DexFile& dex_file, +void ClassLinker::LoadClassMembers(Thread* self, const DexFile& dex_file, const byte* class_data, ConstHandle<mirror::Class> klass, mirror::ClassLoader* class_loader, const OatFile::OatClass* oat_class) { // Load fields. ClassDataItemIterator it(dex_file, class_data); - Thread* self = Thread::Current(); if (it.NumStaticFields() != 0) { mirror::ObjectArray<mirror::ArtField>* statics = AllocArtFieldArray(self, it.NumStaticFields()); if (UNLIKELY(statics == NULL)) { @@ -2834,6 +2847,7 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file, klass->SetIFields(fields); } for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) { + self->AllowThreadSuspension(); StackHandleScope<1> hs(self); Handle<mirror::ArtField> sfield(hs.NewHandle(AllocArtField(self))); if (UNLIKELY(sfield.Get() == NULL)) { @@ -2844,6 +2858,7 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file, LoadField(dex_file, it, klass, sfield); } for (size_t i = 0; it.HasNextInstanceField(); i++, it.Next()) { + self->AllowThreadSuspension(); StackHandleScope<1> hs(self); Handle<mirror::ArtField> ifield(hs.NewHandle(AllocArtField(self))); if (UNLIKELY(ifield.Get() == NULL)) { @@ -2879,6 +2894,7 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file, uint32_t last_dex_method_index = DexFile::kDexNoIndex; size_t last_class_def_method_index = 0; for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) { + self->AllowThreadSuspension(); StackHandleScope<1> hs(self); Handle<mirror::ArtMethod> method(hs.NewHandle(LoadMethod(self, dex_file, it, klass))); if (UNLIKELY(method.Get() == NULL)) { @@ -2899,6 +2915,7 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file, class_def_method_index++; } for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) { + self->AllowThreadSuspension(); StackHandleScope<1> hs(self); Handle<mirror::ArtMethod> method(hs.NewHandle(LoadMethod(self, dex_file, it, klass))); if (UNLIKELY(method.Get() == NULL)) { @@ -2987,8 +3004,7 @@ mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file return dst; } -void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) { - Thread* self = Thread::Current(); +void ClassLinker::AppendToBootClassPath(Thread* self, const DexFile& dex_file) { StackHandleScope<1> hs(self); Handle<mirror::DexCache> dex_cache(hs.NewHandle(AllocDexCache(self, dex_file))); CHECK(dex_cache.Get() != NULL) << "Failed to allocate dex cache for " << dex_file.GetLocation(); @@ -3142,7 +3158,7 @@ mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descripto if (component_type.Get() == nullptr) { DCHECK(self->IsExceptionPending()); // We need to accept erroneous classes as component types. - component_type.Assign(LookupClass(descriptor + 1, class_loader.Get())); + component_type.Assign(LookupClass(self, descriptor + 1, class_loader.Get())); if (component_type.Get() == nullptr) { DCHECK(self->IsExceptionPending()); return nullptr; @@ -3172,7 +3188,7 @@ mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descripto // class to the hash table --- necessary because of possible races with // other threads.) if (class_loader.Get() != component_type->GetClassLoader()) { - mirror::Class* new_class = LookupClass(descriptor, component_type->GetClassLoader()); + mirror::Class* new_class = LookupClass(self, descriptor, component_type->GetClassLoader()); if (new_class != NULL) { return new_class; } @@ -3391,11 +3407,11 @@ bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* return false; } -mirror::Class* ClassLinker::LookupClass(const char* descriptor, +mirror::Class* ClassLinker::LookupClass(Thread* self, const char* descriptor, const mirror::ClassLoader* class_loader) { size_t hash = Hash(descriptor); { - ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); mirror::Class* result = LookupClassFromTableLocked(descriptor, class_loader, hash); if (result != NULL) { return result; @@ -3531,9 +3547,8 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Clas } } -void ClassLinker::VerifyClass(ConstHandle<mirror::Class> klass) { +void ClassLinker::VerifyClass(Thread* self, ConstHandle<mirror::Class> klass) { // TODO: assert that the monitor on the Class is held - Thread* self = Thread::Current(); ObjectLock<mirror::Class> lock(self, klass); // Don't attempt to re-verify if already sufficiently verified. @@ -3576,7 +3591,7 @@ void ClassLinker::VerifyClass(ConstHandle<mirror::Class> klass) { ObjectLock<mirror::Class> lock(self, super); if (!super->IsVerified() && !super->IsErroneous()) { - VerifyClass(super); + VerifyClass(self, super); } if (!super->IsCompileTimeVerified()) { std::string error_msg( @@ -3617,7 +3632,7 @@ void ClassLinker::VerifyClass(ConstHandle<mirror::Class> klass) { verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure; std::string error_msg; if (!preverified) { - verifier_failure = verifier::MethodVerifier::VerifyClass(klass.Get(), + verifier_failure = verifier::MethodVerifier::VerifyClass(self, klass.Get(), Runtime::Current()->IsCompiler(), &error_msg); } @@ -3652,7 +3667,7 @@ void ClassLinker::VerifyClass(ConstHandle<mirror::Class> klass) { klass->SetStatus(mirror::Class::kStatusVerified, self); // As this is a fake verified status, make sure the methods are _not_ marked preverified // later. - klass->SetAccessFlags(klass->GetAccessFlags() | kAccPreverified); + klass->SetPreverified(); } } } else { @@ -3675,9 +3690,9 @@ void ClassLinker::VerifyClass(ConstHandle<mirror::Class> klass) { } void ClassLinker::EnsurePreverifiedMethods(ConstHandle<mirror::Class> klass) { - if ((klass->GetAccessFlags() & kAccPreverified) == 0) { + if (!klass->IsPreverified()) { klass->SetPreverifiedFlagOnAllMethods(); - klass->SetAccessFlags(klass->GetAccessFlags() | kAccPreverified); + klass->SetPreverified(); } } @@ -4108,12 +4123,8 @@ static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics, return true; } -bool ClassLinker::IsInitialized() const { - return init_done_; -} - -bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_init_statics, - bool can_init_parents) { +bool ClassLinker::InitializeClass(Thread* self, ConstHandle<mirror::Class> klass, + bool can_init_statics, bool can_init_parents) { // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol // Are we already initialized and therefore done? @@ -4128,7 +4139,7 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini return false; } - Thread* self = Thread::Current(); + self->AllowThreadSuspension(); uint64_t t0; { ObjectLock<mirror::Class> lock(self, klass); @@ -4147,7 +4158,7 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini CHECK(klass->IsResolved()) << PrettyClass(klass.Get()) << ": state=" << klass->GetStatus(); if (!klass->IsVerified()) { - VerifyClass(klass); + VerifyClass(self, klass); if (!klass->IsVerified()) { // We failed to verify, expect either the klass to be erroneous or verification failed at // compile time. @@ -4186,6 +4197,7 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini klass->SetStatus(mirror::Class::kStatusError, self); return false; } + self->AllowThreadSuspension(); CHECK_EQ(klass->GetStatus(), mirror::Class::kStatusVerified) << PrettyClass(klass.Get()); @@ -4205,7 +4217,7 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini CHECK(can_init_parents); StackHandleScope<1> hs(self); Handle<mirror::Class> handle_scope_super(hs.NewHandle(super_class)); - bool super_initialized = InitializeClass(handle_scope_super, can_init_statics, true); + bool super_initialized = InitializeClass(self, handle_scope_super, can_init_statics, true); if (!super_initialized) { // The super class was verified ahead of entering initializing, we should only be here if // the super class became erroneous due to initialization. @@ -4258,6 +4270,7 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini clinit->Invoke(self, NULL, 0, &result, "V"); } + self->AllowThreadSuspension(); uint64_t t1 = NanoTime(); bool success = true; @@ -4374,15 +4387,14 @@ bool ClassLinker::ValidateSuperClassDescriptors(ConstHandle<mirror::Class> klass return true; } -bool ClassLinker::EnsureInitialized(ConstHandle<mirror::Class> c, bool can_init_fields, - bool can_init_parents) { +bool ClassLinker::EnsureInitialized(Thread* self, ConstHandle<mirror::Class> c, + bool can_init_fields, bool can_init_parents) { DCHECK(c.Get() != nullptr); if (c->IsInitialized()) { EnsurePreverifiedMethods(c); return true; } - const bool success = InitializeClass(c, can_init_fields, can_init_parents); - Thread* self = Thread::Current(); + const bool success = InitializeClass(self, c, can_init_fields, can_init_parents); if (!success) { if (can_init_fields && can_init_parents) { CHECK(self->IsExceptionPending()) << PrettyClass(c.Get()); @@ -4442,11 +4454,11 @@ bool ClassLinker::LinkClass(Thread* self, const char* descriptor, ConstHandle<mi if (!LinkMethods(self, klass, interfaces)) { return false; } - if (!LinkInstanceFields(klass)) { + if (!LinkInstanceFields(self, klass)) { return false; } size_t class_size; - if (!LinkStaticFields(klass, &class_size)) { + if (!LinkStaticFields(self, klass, &class_size)) { return false; } CreateReferenceInstanceOffsets(klass); @@ -4603,6 +4615,7 @@ bool ClassLinker::LinkSuperClass(ConstHandle<mirror::Class> klass) { // Populate the class vtable and itable. Compute return type indices. bool ClassLinker::LinkMethods(Thread* self, ConstHandle<mirror::Class> klass, ConstHandle<mirror::ObjectArray<mirror::Class>> interfaces) { + self->AllowThreadSuspension(); if (klass->IsInterface()) { // No vtable. size_t count = klass->NumVirtualMethods(); @@ -4780,6 +4793,7 @@ bool ClassLinker::LinkInterfaceMethods(ConstHandle<mirror::Class> klass, iftable->SetInterface(i, super_interface); } } + self->AllowThreadSuspension(); // Flatten the interface inheritance hierarchy. size_t idx = super_ifcount; for (size_t i = 0; i < num_interfaces; i++) { @@ -4823,6 +4837,7 @@ bool ClassLinker::LinkInterfaceMethods(ConstHandle<mirror::Class> klass, } } } + self->AllowThreadSuspension(); // Shrink iftable in case duplicates were found if (idx < ifcount) { iftable.Assign(down_cast<mirror::IfTable*>(iftable->CopyOf(self, idx * mirror::IfTable::kMax))); @@ -4840,6 +4855,7 @@ bool ClassLinker::LinkInterfaceMethods(ConstHandle<mirror::Class> klass, if (klass->IsInterface()) { return true; } + self->AllowThreadSuspension(); // Allocate imtable bool imtable_changed = false; Handle<mirror::ObjectArray<mirror::ArtMethod>> imtable( @@ -4858,6 +4874,7 @@ bool ClassLinker::LinkInterfaceMethods(ConstHandle<mirror::Class> klass, miranda_list(hs.NewHandle(AllocArtMethodArray(self, max_miranda_methods))); size_t miranda_list_size = 0; // The current size of miranda_list. for (size_t i = 0; i < ifcount; ++i) { + self->AllowThreadSuspension(); size_t num_methods = iftable->GetInterface(i)->NumVirtualMethods(); if (num_methods > 0) { StackHandleScope<2> hs(self); @@ -4984,19 +5001,19 @@ bool ClassLinker::LinkInterfaceMethods(ConstHandle<mirror::Class> klass, CHECK(vtable->Get(i) != NULL); } -// klass->DumpClass(std::cerr, Class::kDumpClassFullDetail); + self->AllowThreadSuspension(); return true; } -bool ClassLinker::LinkInstanceFields(ConstHandle<mirror::Class> klass) { +bool ClassLinker::LinkInstanceFields(Thread* self, ConstHandle<mirror::Class> klass) { CHECK(klass.Get() != NULL); - return LinkFields(klass, false, nullptr); + return LinkFields(self, klass, false, nullptr); } -bool ClassLinker::LinkStaticFields(ConstHandle<mirror::Class> klass, size_t* class_size) { +bool ClassLinker::LinkStaticFields(Thread* self, ConstHandle<mirror::Class> klass, size_t* class_size) { CHECK(klass.Get() != NULL); - return LinkFields(klass, true, class_size); + return LinkFields(self, klass, true, class_size); } struct LinkFieldsComparator { @@ -5026,7 +5043,9 @@ struct LinkFieldsComparator { } }; -bool ClassLinker::LinkFields(ConstHandle<mirror::Class> klass, bool is_static, size_t* class_size) { +bool ClassLinker::LinkFields(Thread* self, ConstHandle<mirror::Class> klass, bool is_static, + size_t* class_size) { + self->AllowThreadSuspension(); size_t num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields(); @@ -5057,7 +5076,7 @@ bool ClassLinker::LinkFields(ConstHandle<mirror::Class> klass, bool is_static, s // we want a relatively stable order so that adding new fields // minimizes disruption of C++ version such as Class and Method. std::deque<mirror::ArtField*> grouped_and_sorted_fields; - const char* old_no_suspend_cause = Thread::Current()->StartAssertNoThreadSuspension( + const char* old_no_suspend_cause = self->StartAssertNoThreadSuspension( "Naked ArtField references in deque"); for (size_t i = 0; i < num_fields; i++) { mirror::ArtField* f = fields->Get(i); @@ -5103,8 +5122,7 @@ bool ClassLinker::LinkFields(ConstHandle<mirror::Class> klass, bool is_static, s fields, &grouped_and_sorted_fields, &gaps); CHECK(grouped_and_sorted_fields.empty()) << "Missed " << grouped_and_sorted_fields.size() << " fields."; - - Thread::Current()->EndAssertNoThreadSuspension(old_no_suspend_cause); + self->EndAssertNoThreadSuspension(old_no_suspend_cause); // We lie to the GC about the java.lang.ref.Reference.referent field, so it doesn't scan it. if (!is_static && klass->DescriptorEquals("Ljava/lang/ref/Reference;")) { @@ -5520,10 +5538,12 @@ void ClassLinker::DumpAllClasses(int flags) { } void ClassLinker::DumpForSigQuit(std::ostream& os) { + Thread* self = Thread::Current(); if (dex_cache_image_class_lookup_required_) { + ScopedObjectAccess soa(self); MoveImageClassesToClassTable(); } - ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); + ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); os << "Loaded classes: " << class_table_.size() << " allocated classes\n"; } |