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.cc67
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);
}
}