diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 144 |
1 files changed, 76 insertions, 68 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 210386aebb..17a179f2d9 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1083,13 +1083,14 @@ void ClassLinker::InitFromImage() { // reinit references to when reinitializing a ClassLinker from a // mapped image. void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty) { - visitor(class_roots_, arg); + class_roots_ = down_cast<mirror::ObjectArray<mirror::Class>*>(visitor(class_roots_, arg)); Thread* self = Thread::Current(); { ReaderMutexLock mu(self, dex_lock_); if (!only_dirty || dex_caches_dirty_) { - for (mirror::DexCache* dex_cache : dex_caches_) { - visitor(dex_cache, arg); + for (mirror::DexCache*& dex_cache : dex_caches_) { + dex_cache = down_cast<mirror::DexCache*>(visitor(dex_cache, arg)); + DCHECK(dex_cache != nullptr); } if (clean_dirty) { dex_caches_dirty_ = false; @@ -1100,8 +1101,9 @@ void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, b { ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); if (!only_dirty || class_table_dirty_) { - for (const std::pair<size_t, mirror::Class*>& it : class_table_) { - visitor(it.second, arg); + for (std::pair<const size_t, mirror::Class*>& it : class_table_) { + it.second = down_cast<mirror::Class*>(visitor(it.second, arg)); + DCHECK(it.second != nullptr); } if (clean_dirty) { class_table_dirty_ = false; @@ -1112,7 +1114,8 @@ void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, b // handle image roots by using the MS/CMS rescanning of dirty cards. } - visitor(array_iftable_, arg); + array_iftable_ = reinterpret_cast<mirror::IfTable*>(visitor(array_iftable_, arg)); + DCHECK(array_iftable_ != nullptr); } void ClassLinker::VisitClasses(ClassVisitor* visitor, void* arg) { @@ -1837,7 +1840,7 @@ mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file SirtRef<mirror::Class>& klass) { uint32_t dex_method_idx = it.GetMemberIndex(); const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx); - StringPiece method_name(dex_file.GetMethodName(method_id)); + StringPiece method_name(dex_file.StringDataAsStringPieceByIdx(method_id.name_idx_)); mirror::ArtMethod* dst = AllocArtMethod(self); if (UNLIKELY(dst == NULL)) { @@ -1866,7 +1869,7 @@ mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file klass->SetFinalizable(); } else { ClassHelper kh(klass.get()); - StringPiece klass_descriptor(kh.GetDescriptor()); + StringPiece klass_descriptor(kh.GetDescriptorAsStringPiece()); // The Enum class declares a "final" finalize() method to prevent subclasses from // introducing a finalizer. We don't want to set the finalizable flag for Enum or its // subclasses, so we exclude it here. @@ -2216,7 +2219,7 @@ bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* ++it) { mirror::Class* klass = it->second; kh.ChangeClass(klass); - if (strcmp(kh.GetDescriptor(), descriptor) == 0 && klass->GetClassLoader() == class_loader) { + if (kh.GetDescriptorAsStringPiece() == descriptor && klass->GetClassLoader() == class_loader) { class_table_.erase(it); return true; } @@ -2262,15 +2265,16 @@ mirror::Class* ClassLinker::LookupClassFromTableLocked(const char* descriptor, for (auto it = class_table_.lower_bound(hash); it != end && it->first == hash; ++it) { mirror::Class* klass = it->second; kh.ChangeClass(klass); - if (klass->GetClassLoader() == class_loader && strcmp(descriptor, kh.GetDescriptor()) == 0) { + if (klass->GetClassLoader() == class_loader && kh.GetDescriptorAsStringPiece() == descriptor) { if (kIsDebugBuild) { // Check for duplicates in the table. for (++it; it != end && it->first == hash; ++it) { mirror::Class* klass2 = it->second; kh.ChangeClass(klass2); - CHECK(!(strcmp(descriptor, kh.GetDescriptor()) == 0 && klass2->GetClassLoader() == class_loader)) - << PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " " - << PrettyClass(klass2) << " " << klass2 << " " << klass2->GetClassLoader(); + CHECK(!(kh.GetDescriptorAsStringPiece() == descriptor && + klass2->GetClassLoader() == class_loader)) + << PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " " + << PrettyClass(klass2) << " " << klass2 << " " << klass2->GetClassLoader(); } } return klass; @@ -2376,7 +2380,7 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Clas it != end && it->first == hash; ++it) { mirror::Class* klass = it->second; kh.ChangeClass(klass); - if (strcmp(descriptor, kh.GetDescriptor()) == 0) { + if (kh.GetDescriptorAsStringPiece() == descriptor) { result.push_back(klass); } } @@ -2535,11 +2539,11 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class CHECK(oat_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass); const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation()); CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass); - const char* descriptor = ClassHelper(klass).GetDescriptor(); uint16_t class_def_index = klass->GetDexClassDefIndex(); UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(class_def_index)); CHECK(oat_class.get() != NULL) - << dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor; + << dex_file.GetLocation() << " " << PrettyClass(klass) << " " + << ClassHelper(klass).GetDescriptor(); oat_file_class_status = oat_class->GetStatus(); if (oat_file_class_status == mirror::Class::kStatusVerified || oat_file_class_status == mirror::Class::kStatusInitialized) { @@ -2578,7 +2582,8 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class return false; } LOG(FATAL) << "Unexpected class status: " << oat_file_class_status - << " " << dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor; + << " " << dex_file.GetLocation() << " " << PrettyClass(klass) << " " + << ClassHelper(klass).GetDescriptor(); return false; } @@ -2818,12 +2823,12 @@ static void CheckProxyConstructor(mirror::ArtMethod* constructor) CHECK(constructor->IsConstructor()); MethodHelper mh(constructor); CHECK_STREQ(mh.GetName(), "<init>"); - CHECK_EQ(mh.GetSignature(), std::string("(Ljava/lang/reflect/InvocationHandler;)V")); + CHECK_STREQ(mh.GetSignature().ToString().c_str(), "(Ljava/lang/reflect/InvocationHandler;)V"); DCHECK(constructor->IsPublic()); } mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self, SirtRef<mirror::Class>& klass, - SirtRef<mirror::ArtMethod>& prototype) { + SirtRef<mirror::ArtMethod>& prototype) { // Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden // prototype method prototype->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(), @@ -2887,7 +2892,7 @@ static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics, } if (!can_init_statics) { // Check if there's a class initializer. - mirror::ArtMethod* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V"); + mirror::ArtMethod* clinit = klass->FindClassInitializer(); if (clinit != NULL) { return false; } @@ -3034,7 +3039,7 @@ bool ClassLinker::InitializeClass(mirror::Class* klass, bool can_init_statics, } } - mirror::ArtMethod* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V"); + mirror::ArtMethod* clinit = klass->FindClassInitializer(); if (clinit != NULL) { CHECK(can_init_statics); if (LIKELY(Runtime::Current()->IsStarted())) { @@ -3724,10 +3729,10 @@ struct LinkFieldsComparator { // same basic group? then sort by string. fh_->ChangeField(field1); - StringPiece name1(fh_->GetName()); + const char* name1 = fh_->GetName(); fh_->ChangeField(field2); - StringPiece name2(fh_->GetName()); - return name1 < name2; + const char* name2 = fh_->GetName(); + return strcmp(name1, name2) < 0; } FieldHelper* fh_; @@ -3761,7 +3766,9 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) { // minimizes disruption of C++ version such as Class and Method. std::deque<mirror::ArtField*> grouped_and_sorted_fields; for (size_t i = 0; i < num_fields; i++) { - grouped_and_sorted_fields.push_back(fields->Get(i)); + mirror::ArtField* f = fields->Get(i); + CHECK(f != NULL); + grouped_and_sorted_fields.push_back(f); } FieldHelper fh(NULL, this); std::sort(grouped_and_sorted_fields.begin(), @@ -3828,7 +3835,7 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) { // We lie to the GC about the java.lang.ref.Reference.referent field, so it doesn't scan it. if (!is_static && - StringPiece(ClassHelper(klass.get(), this).GetDescriptor()) == "Ljava/lang/ref/Reference;") { + (ClassHelper(klass.get(), this).GetDescriptorAsStringPiece() == "Ljava/lang/ref/Reference;")) { // We know there are no non-reference fields in the Reference classes, and we know // that 'referent' is alphabetically last, so this is easy... CHECK_EQ(num_reference_fields, num_fields); @@ -3837,39 +3844,39 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) { --num_reference_fields; } -#ifndef NDEBUG - // Make sure that all reference fields appear before - // non-reference fields, and all double-wide fields are aligned. - bool seen_non_ref = false; - for (size_t i = 0; i < num_fields; i++) { - mirror::ArtField* field = fields->Get(i); - if (false) { // enable to debug field layout - LOG(INFO) << "LinkFields: " << (is_static ? "static" : "instance") - << " class=" << PrettyClass(klass.get()) - << " field=" << PrettyField(field) - << " offset=" << field->GetField32(MemberOffset(mirror::ArtField::OffsetOffset()), - false); - } - fh.ChangeField(field); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); - bool is_primitive = type != Primitive::kPrimNot; - if (StringPiece(ClassHelper(klass.get(), this).GetDescriptor()) == "Ljava/lang/ref/Reference;" && - StringPiece(fh.GetName()) == "referent") { - is_primitive = true; // We lied above, so we have to expect a lie here. - } - if (is_primitive) { - if (!seen_non_ref) { - seen_non_ref = true; - DCHECK_EQ(num_reference_fields, i); + if (kIsDebugBuild) { + // Make sure that all reference fields appear before + // non-reference fields, and all double-wide fields are aligned. + bool seen_non_ref = false; + for (size_t i = 0; i < num_fields; i++) { + mirror::ArtField* field = fields->Get(i); + if (false) { // enable to debug field layout + LOG(INFO) << "LinkFields: " << (is_static ? "static" : "instance") + << " class=" << PrettyClass(klass.get()) + << " field=" << PrettyField(field) + << " offset=" << field->GetField32(MemberOffset(mirror::ArtField::OffsetOffset()), + false); + } + fh.ChangeField(field); + Primitive::Type type = fh.GetTypeAsPrimitiveType(); + bool is_primitive = type != Primitive::kPrimNot; + if (ClassHelper(klass.get(), this).GetDescriptorAsStringPiece() == "Ljava/lang/ref/Reference;" && + fh.GetNameAsStringPiece() == "referent") { + is_primitive = true; // We lied above, so we have to expect a lie here. + } + if (is_primitive) { + if (!seen_non_ref) { + seen_non_ref = true; + DCHECK_EQ(num_reference_fields, i); + } + } else { + DCHECK(!seen_non_ref); } - } else { - DCHECK(!seen_non_ref); + } + if (!seen_non_ref) { + DCHECK_EQ(num_fields, num_reference_fields); } } - if (!seen_non_ref) { - DCHECK_EQ(num_fields, num_reference_fields); - } -#endif size = field_offset.Uint32Value(); // Update klass if (is_static) { @@ -3985,11 +3992,11 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, } mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, - uint32_t method_idx, - mirror::DexCache* dex_cache, - mirror::ClassLoader* class_loader, - const mirror::ArtMethod* referrer, - InvokeType type) { + uint32_t method_idx, + mirror::DexCache* dex_cache, + mirror::ClassLoader* class_loader, + const mirror::ArtMethod* referrer, + InvokeType type) { DCHECK(dex_cache != NULL); // Check for hit in the dex cache. mirror::ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx); @@ -4024,7 +4031,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, if (resolved == NULL) { // Search by name, which works across dex files. const char* name = dex_file.StringDataByIdx(method_id.name_idx_); - std::string signature(dex_file.CreateMethodSignature(method_id.proto_idx_, NULL)); + const Signature signature = dex_file.GetMethodSignature(method_id); switch (type) { case kDirect: // Fall-through. case kStatic: @@ -4054,7 +4061,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, // We failed to find the method which means either an access error, an incompatible class // change, or no such method. First try to find the method among direct and virtual methods. const char* name = dex_file.StringDataByIdx(method_id.name_idx_); - std::string signature(dex_file.CreateMethodSignature(method_id.proto_idx_, NULL)); + const Signature signature = dex_file.GetMethodSignature(method_id); switch (type) { case kDirect: case kStatic: @@ -4172,9 +4179,9 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, } mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, - uint32_t field_idx, - mirror::DexCache* dex_cache, - mirror::ClassLoader* class_loader) { + uint32_t field_idx, + mirror::DexCache* dex_cache, + mirror::ClassLoader* class_loader) { DCHECK(dex_cache != NULL); mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx); if (resolved != NULL) { @@ -4187,8 +4194,9 @@ mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, return NULL; } - const char* name = dex_file.GetFieldName(field_id); - const char* type = dex_file.GetFieldTypeDescriptor(field_id); + StringPiece name(dex_file.StringDataAsStringPieceByIdx(field_id.name_idx_)); + StringPiece type(dex_file.StringDataAsStringPieceByIdx( + dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_)); resolved = klass->FindField(name, type); if (resolved != NULL) { dex_cache->SetResolvedField(field_idx, resolved); |