diff options
Diffstat (limited to 'runtime/class_linker.cc')
| -rw-r--r-- | runtime/class_linker.cc | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index be636d80a8..4a5da1f1e9 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -805,7 +805,7 @@ void ClassLinker::FinishInit(Thread* self) { // Note: we hard code the field indexes here rather than using FindInstanceField // as the types of the field can't be resolved prior to the runtime being // fully initialized - StackHandleScope<2> hs(self); + StackHandleScope<3> hs(self); Handle<mirror::Class> java_lang_ref_Reference = hs.NewHandle(GetClassRoot<mirror::Reference>(this)); Handle<mirror::Class> java_lang_ref_FinalizerReference = @@ -847,11 +847,24 @@ void ClassLinker::FinishInit(Thread* self) { // that Object, Class, and Object[] are setup init_done_ = true; + // Under sanitization, the small carve-out to handle stack overflow might not be enough to + // initialize the StackOverflowError class (as it might require running the verifier). Instead, + // ensure that the class will be initialized. + if (kMemoryToolIsAvailable && !Runtime::Current()->IsAotCompiler()) { + verifier::MethodVerifier::Init(); // Need to prepare the verifier. + + ObjPtr<mirror::Class> soe_klass = FindSystemClass(self, "Ljava/lang/StackOverflowError;"); + if (soe_klass == nullptr || !EnsureInitialized(self, hs.NewHandle(soe_klass), true, true)) { + // Strange, but don't crash. + LOG(WARNING) << "Could not prepare StackOverflowError."; + self->ClearException(); + } + } + VLOG(startup) << "ClassLinker::FinishInit exiting"; } -void ClassLinker::RunRootClinits() { - Thread* self = Thread::Current(); +void ClassLinker::RunRootClinits(Thread* self) { for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); ++i) { ObjPtr<mirror::Class> c = GetClassRoot(ClassRoot(i), this); if (!c->IsArrayClass() && !c->IsPrimitive()) { @@ -859,6 +872,8 @@ void ClassLinker::RunRootClinits() { Handle<mirror::Class> h_class(hs.NewHandle(c)); EnsureInitialized(self, h_class, true, true); self->AssertNoPendingException(); + } else { + DCHECK(c->IsInitialized()); } } } @@ -990,8 +1005,7 @@ bool ClassLinker::InitFromBootImage(std::string* error_msg) { class_roots_ = GcRoot<mirror::ObjectArray<mirror::Class>>( ObjPtr<mirror::ObjectArray<mirror::Class>>::DownCast(MakeObjPtr( spaces[0]->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)))); - DCHECK_EQ(GetClassRoot(ClassRoot::kJavaLangClass, this)->GetClassFlags(), - mirror::kClassFlagClass); + DCHECK_EQ(GetClassRoot<mirror::Class>(this)->GetClassFlags(), mirror::kClassFlagClass); ObjPtr<mirror::Class> java_lang_Object = GetClassRoot<mirror::Object>(this); java_lang_Object->SetObjectSize(sizeof(mirror::Object)); @@ -1243,12 +1257,12 @@ void AppImageClassLoadersAndDexCachesHelper::Update( ObjPtr<mirror::Class> klass = types[j].load(std::memory_order_relaxed).object.Read(); if (space->HasAddress(klass.Ptr())) { DCHECK(!klass->IsErroneous()) << klass->GetStatus(); - auto it = new_class_set->Find(ClassTable::TableSlot(klass)); + auto it = new_class_set->find(ClassTable::TableSlot(klass)); DCHECK(it != new_class_set->end()); DCHECK_EQ(it->Read(), klass); ObjPtr<mirror::Class> super_class = klass->GetSuperClass(); if (super_class != nullptr && !heap->ObjectIsInBootImageSpace(super_class)) { - auto it2 = new_class_set->Find(ClassTable::TableSlot(super_class)); + auto it2 = new_class_set->find(ClassTable::TableSlot(super_class)); DCHECK(it2 != new_class_set->end()); DCHECK_EQ(it2->Read(), super_class); } @@ -1325,7 +1339,7 @@ static std::unique_ptr<const DexFile> OpenOatDexFile(const OatFile* oat_file, REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(error_msg != nullptr); std::unique_ptr<const DexFile> dex_file; - const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, nullptr, error_msg); + const OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, nullptr, error_msg); if (oat_dex_file == nullptr) { return std::unique_ptr<const DexFile>(); } @@ -1610,10 +1624,9 @@ bool ClassLinker::AddImageSpace( hs.NewHandle(dex_caches_object->AsObjectArray<mirror::DexCache>())); Handle<mirror::ObjectArray<mirror::Class>> class_roots(hs.NewHandle( header.GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>())); - static_assert(ImageHeader::kClassLoader + 1u == ImageHeader::kImageRootsMax, - "Class loader should be the last image root."); MutableHandle<mirror::ClassLoader> image_class_loader(hs.NewHandle( - app_image ? header.GetImageRoot(ImageHeader::kClassLoader)->AsClassLoader() : nullptr)); + app_image ? header.GetImageRoot(ImageHeader::kAppImageClassLoader)->AsClassLoader() + : nullptr)); DCHECK(class_roots != nullptr); if (class_roots->GetLength() != static_cast<int32_t>(ClassRoot::kMax)) { *error_msg = StringPrintf("Expected %d class roots but got %d", @@ -2530,7 +2543,7 @@ ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self, old = result_ptr; // For the comparison below, after releasing the lock. if (descriptor_equals) { class_table->InsertWithHash(result_ptr, hash); - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader.Get()); + WriteBarrier::ForEveryFieldWrite(class_loader.Get()); } // else throw below, after releasing the lock. } } @@ -2863,9 +2876,9 @@ void ClassLinker::FixupStaticTrampolines(ObjPtr<mirror::Class> klass) { } const DexFile& dex_file = klass->GetDexFile(); - const DexFile::ClassDef* dex_class_def = klass->GetClassDef(); - CHECK(dex_class_def != nullptr); - ClassAccessor accessor(dex_file, *dex_class_def); + const uint16_t class_def_idx = klass->GetDexClassDefIndex(); + CHECK_NE(class_def_idx, DexFile::kDexNoIndex16); + ClassAccessor accessor(dex_file, class_def_idx); // There should always be class data if there were direct methods. CHECK(accessor.HasClassData()) << klass->PrettyDescriptor(); bool has_oat_class; @@ -3145,7 +3158,7 @@ void ClassLinker::LoadClass(Thread* self, DCHECK_EQ(klass->NumInstanceFields(), num_ifields); } // Ensure that the card is marked so that remembered sets pick up native roots. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(klass.Get()); + WriteBarrier::ForEveryFieldWrite(klass.Get()); self->AllowThreadSuspension(); } @@ -3332,7 +3345,7 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, if (class_loader != nullptr) { // Since we added a strong root to the class table, do the write barrier as required for // remembered sets and generational GCs. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader); + WriteBarrier::ForEveryFieldWrite(class_loader); } dex_caches_.push_back(data); } @@ -3392,7 +3405,7 @@ void ClassLinker::RegisterExistingDexCache(ObjPtr<mirror::DexCache> dex_cache, if (h_class_loader.Get() != nullptr) { // Since we added a strong root to the class table, do the write barrier as required for // remembered sets and generational GCs. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(h_class_loader.Get()); + WriteBarrier::ForEveryFieldWrite(h_class_loader.Get()); } } @@ -3463,7 +3476,7 @@ ObjPtr<mirror::DexCache> ClassLinker::RegisterDexFile(const DexFile& dex_file, if (h_class_loader.Get() != nullptr) { // Since we added a strong root to the class table, do the write barrier as required for // remembered sets and generational GCs. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(h_class_loader.Get()); + WriteBarrier::ForEveryFieldWrite(h_class_loader.Get()); } return h_dex_cache.Get(); } @@ -3763,7 +3776,7 @@ ObjPtr<mirror::Class> ClassLinker::InsertClass(const char* descriptor, class_table->InsertWithHash(klass, hash); if (class_loader != nullptr) { // This is necessary because we need to have the card dirtied for remembered sets. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader); + WriteBarrier::ForEveryFieldWrite(class_loader); } if (log_new_roots_) { new_class_roots_.push_back(GcRoot<mirror::Class>(klass)); @@ -3793,7 +3806,7 @@ void ClassLinker::UpdateClassMethods(ObjPtr<mirror::Class> klass, klass->NumDirectMethods(), klass->NumDeclaredVirtualMethods()); // Need to mark the card so that the remembered sets and mod union tables get updated. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(klass); + WriteBarrier::ForEveryFieldWrite(klass); } ObjPtr<mirror::Class> ClassLinker::LookupClass(Thread* self, @@ -4169,7 +4182,7 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, } } - const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile(); + const 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 || oat_dex_file->GetOatFile() == nullptr) { return false; @@ -4442,8 +4455,8 @@ void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* // Find the <init>(InvocationHandler)V method. The exact method offset varies depending // on which front-end compiler was used to build the libcore DEX files. - ArtMethod* proxy_constructor = proxy_class->FindConstructor( - "(Ljava/lang/reflect/InvocationHandler;)V", image_pointer_size_); + ArtMethod* proxy_constructor = + jni::DecodeArtMethod(WellKnownClasses::java_lang_reflect_Proxy_init); DCHECK(proxy_constructor != nullptr) << "Could not find <init> method in java.lang.reflect.Proxy"; @@ -5197,7 +5210,7 @@ void ClassLinker::FixupTemporaryDeclaringClass(ObjPtr<mirror::Class> temp_class, // Make sure the remembered set and mod-union tables know that we updated some of the native // roots. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(new_class); + WriteBarrier::ForEveryFieldWrite(new_class); } void ClassLinker::RegisterClassLoader(ObjPtr<mirror::ClassLoader> class_loader) { @@ -5355,7 +5368,7 @@ bool ClassLinker::LinkClass(Thread* self, if (class_loader != nullptr) { // We updated the class in the class table, perform the write barrier so that the GC knows // about the change. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader); + WriteBarrier::ForEveryFieldWrite(class_loader); } CHECK_EQ(existing, klass.Get()); if (log_new_roots_) { @@ -8762,7 +8775,7 @@ void ClassLinker::InsertDexFileInToClassLoader(ObjPtr<mirror::Object> dex_file, if (table->InsertStrongRoot(dex_file) && class_loader != nullptr) { // It was not already inserted, perform the write barrier to let the GC know the class loader's // class table was modified. - Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader); + WriteBarrier::ForEveryFieldWrite(class_loader); } } |