diff options
Diffstat (limited to 'runtime/class_linker.cc')
| -rw-r--r-- | runtime/class_linker.cc | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index eaa35fe12d..b611aa2132 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1025,7 +1025,8 @@ bool ClassLinker::IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa, class_loader->GetClass(); } -static mirror::String* GetDexPathListElementName(ObjPtr<mirror::Object> element) +static bool GetDexPathListElementName(ObjPtr<mirror::Object> element, + ObjPtr<mirror::String>* out_name) REQUIRES_SHARED(Locks::mutator_lock_) { ArtField* const dex_file_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); @@ -1037,17 +1038,20 @@ static mirror::String* GetDexPathListElementName(ObjPtr<mirror::Object> element) CHECK_EQ(dex_file_field->GetDeclaringClass(), element->GetClass()) << element->PrettyTypeOf(); ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element); if (dex_file == nullptr) { - return nullptr; + // Null dex file means it was probably a jar with no dex files, return a null string. + *out_name = nullptr; + return true; } ObjPtr<mirror::Object> name_object = dex_file_name_field->GetObject(dex_file); if (name_object != nullptr) { - return name_object->AsString(); + *out_name = name_object->AsString(); + return true; } - return nullptr; + return false; } static bool FlattenPathClassLoader(ObjPtr<mirror::ClassLoader> class_loader, - std::list<mirror::String*>* out_dex_file_names, + std::list<ObjPtr<mirror::String>>* out_dex_file_names, std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(out_dex_file_names != nullptr); @@ -1083,12 +1087,14 @@ static bool FlattenPathClassLoader(ObjPtr<mirror::ClassLoader> class_loader, *error_msg = StringPrintf("Null dex element at index %d", i); return false; } - ObjPtr<mirror::String> const name = GetDexPathListElementName(element); - if (name == nullptr) { - *error_msg = StringPrintf("Null name for dex element at index %d", i); + ObjPtr<mirror::String> name; + if (!GetDexPathListElementName(element, &name)) { + *error_msg = StringPrintf("Invalid dex path list element at index %d", i); return false; } - out_dex_file_names->push_front(name.Ptr()); + if (name != nullptr) { + out_dex_file_names->push_front(name.Ptr()); + } } } } @@ -1769,14 +1775,14 @@ bool ClassLinker::AddImageSpace( *error_msg = "Unexpected BootClassLoader in app image"; return false; } - std::list<mirror::String*> image_dex_file_names; + std::list<ObjPtr<mirror::String>> image_dex_file_names; std::string temp_error_msg; if (!FlattenPathClassLoader(image_class_loader.Get(), &image_dex_file_names, &temp_error_msg)) { *error_msg = StringPrintf("Failed to flatten image class loader hierarchy '%s'", temp_error_msg.c_str()); return false; } - std::list<mirror::String*> loader_dex_file_names; + std::list<ObjPtr<mirror::String>> loader_dex_file_names; if (!FlattenPathClassLoader(class_loader.Get(), &loader_dex_file_names, &temp_error_msg)) { *error_msg = StringPrintf("Failed to flatten class loader hierarchy '%s'", temp_error_msg.c_str()); @@ -1788,7 +1794,10 @@ bool ClassLinker::AddImageSpace( ObjPtr<mirror::Object> element = elements->GetWithoutChecks(i); if (element != nullptr) { // If we are somewhere in the middle of the array, there may be nulls at the end. - loader_dex_file_names.push_back(GetDexPathListElementName(element)); + ObjPtr<mirror::String> name; + if (GetDexPathListElementName(element, &name) && name != nullptr) { + loader_dex_file_names.push_back(name); + } } } // Ignore the number of image dex files since we are adding those to the class loader anyways. @@ -3891,8 +3900,10 @@ bool ClassLinker::AttemptSupertypeVerification(Thread* self, if (!supertype->IsVerified() && !supertype->IsErroneous()) { VerifyClass(self, supertype); } - if (supertype->IsCompileTimeVerified()) { - // Either we are verified or we soft failed and need to retry at runtime. + + if (supertype->IsVerified() || supertype->ShouldVerifyAtRuntime()) { + // The supertype is either verified, or we soft failed at AOT time. + DCHECK(supertype->IsVerified() || Runtime::Current()->IsAotCompiler()); return true; } // If we got this far then we have a hard failure. @@ -3958,13 +3969,16 @@ verifier::MethodVerifier::FailureKind ClassLinker::VerifyClass( return verifier::MethodVerifier::kHardFailure; } - // Don't attempt to re-verify if already sufficiently verified. + // Don't attempt to re-verify if already verified. if (klass->IsVerified()) { EnsureSkipAccessChecksMethods(klass, image_pointer_size_); return verifier::MethodVerifier::kNoFailure; } - if (klass->IsCompileTimeVerified() && Runtime::Current()->IsAotCompiler()) { - return verifier::MethodVerifier::kNoFailure; + + // For AOT, don't attempt to re-verify if we have already found we should + // verify at runtime. + if (Runtime::Current()->IsAotCompiler() && klass->ShouldVerifyAtRuntime()) { + return verifier::MethodVerifier::kSoftFailure; } if (klass->GetStatus() == mirror::Class::kStatusResolved) { @@ -4917,7 +4931,15 @@ bool ClassLinker::InitializeDefaultInterfaceRecursive(Thread* self, // First we initialize all of iface's super-interfaces recursively. for (size_t i = 0; i < num_direct_ifaces; i++) { ObjPtr<mirror::Class> super_iface = mirror::Class::GetDirectInterface(self, iface.Get(), i); - DCHECK(super_iface != nullptr); + if (UNLIKELY(super_iface == nullptr)) { + const char* iface_descriptor = + iface->GetDexFile().StringByTypeIdx(iface->GetDirectInterfaceTypeIdx(i)); + LOG(FATAL) << "Check failed: super_iface != nullptr " + << "Debug data for bug 34839984: " + << iface->PrettyDescriptor() << " iface #" << i << " " << iface_descriptor + << " space: " << DescribeSpace(iface.Get()) + << " loaders: " << DescribeLoaders(iface.Get(), iface_descriptor); + } if (!super_iface->HasBeenRecursivelyInitialized()) { // Recursive step handle_super_iface.Assign(super_iface); @@ -8924,7 +8946,7 @@ std::set<DexCacheResolvedClasses> ClassLinker::GetResolvedClasses(bool ignore_bo return ret; } -std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForProfileKeys( +std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForResolvedClasses( const std::set<DexCacheResolvedClasses>& classes) { ScopedTrace trace(__PRETTY_FUNCTION__); std::unordered_set<std::string> ret; @@ -8939,14 +8961,13 @@ std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForProfileKeys( if (dex_cache != nullptr) { const DexFile* dex_file = dex_cache->GetDexFile(); // There could be duplicates if two dex files with the same location are mapped. - location_to_dex_file.emplace( - ProfileCompilationInfo::GetProfileDexFileKey(dex_file->GetLocation()), dex_file); + location_to_dex_file.emplace(dex_file->GetLocation(), dex_file); } } } for (const DexCacheResolvedClasses& info : classes) { - const std::string& profile_key = info.GetDexLocation(); - auto found = location_to_dex_file.find(profile_key); + const std::string& location = info.GetDexLocation(); + auto found = location_to_dex_file.find(location); if (found != location_to_dex_file.end()) { const DexFile* dex_file = found->second; VLOG(profiler) << "Found opened dex file for " << dex_file->GetLocation() << " with " @@ -8958,7 +8979,7 @@ std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForProfileKeys( ret.insert(descriptor); } } else { - VLOG(class_linker) << "Failed to find opened dex file for profile key " << profile_key; + VLOG(class_linker) << "Failed to find opened dex file for location " << location; } } return ret; |