diff options
Diffstat (limited to 'compiler/image_writer.cc')
| -rw-r--r-- | compiler/image_writer.cc | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index a8fdecaa4a..1c73dfab37 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -398,12 +398,18 @@ void ImageWriter::SetImageBinSlot(mirror::Object* object, BinSlot bin_slot) { // Before we stomp over the lock word, save the hash code for later. LockWord lw(object->GetLockWord(false)); switch (lw.GetState()) { - case LockWord::kFatLocked: { - LOG(FATAL) << "Fat locked object " << object << " found during object copy"; - break; - } + case LockWord::kFatLocked: + FALLTHROUGH_INTENDED; case LockWord::kThinLocked: { - LOG(FATAL) << "Thin locked object " << object << " found during object copy"; + std::ostringstream oss; + bool thin = (lw.GetState() == LockWord::kThinLocked); + oss << (thin ? "Thin" : "Fat") + << " locked object " << object << "(" << object->PrettyTypeOf() + << ") found during object copy"; + if (thin) { + oss << ". Lock owner:" << lw.ThinLockOwner(); + } + LOG(FATAL) << oss.str(); break; } case LockWord::kUnlocked: @@ -473,6 +479,11 @@ void ImageWriter::PrepareDexCacheArraySlots() { start + layout.MethodTypesOffset(), dex_cache); } + if (dex_cache->GetResolvedCallSites() != nullptr) { + AddDexCacheArrayRelocation(dex_cache->GetResolvedCallSites(), + start + layout.CallSitesOffset(), + dex_cache); + } } } @@ -946,11 +957,18 @@ void ImageWriter::PruneAndPreloadDexCache(ObjPtr<mirror::DexCache> dex_cache, ArtMethod* method = mirror::DexCache::GetElementPtrSize(resolved_methods, i, target_ptr_size_); DCHECK(method != nullptr) << "Expected resolution method instead of null method"; - mirror::Class* declaring_class = method->GetDeclaringClass(); + // Check if the referenced class is in the image. Note that we want to check the referenced + // class rather than the declaring class to preserve the semantics, i.e. using a MethodId + // results in resolving the referenced class and that can for example throw OOME. + ObjPtr<mirror::Class> referencing_class = class_linker->LookupResolvedType( + dex_file, + dex_file.GetMethodId(i).class_idx_, + dex_cache, + class_loader); // Copied methods may be held live by a class which was not an image class but have a // declaring class which is an image class. Set it to the resolution method to be safe and // prevent dangling pointers. - if (method->IsCopied() || !KeepClass(declaring_class)) { + if (method->IsCopied() || !KeepClass(referencing_class)) { mirror::DexCache::SetElementPtrSize(resolved_methods, i, resolution_method, @@ -958,8 +976,8 @@ void ImageWriter::PruneAndPreloadDexCache(ObjPtr<mirror::DexCache> dex_cache, } else if (kIsDebugBuild) { // Check that the class is still in the classes table. ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); - CHECK(class_linker->ClassInClassTable(declaring_class)) << "Class " - << Class::PrettyClass(declaring_class) << " not in class linker table"; + CHECK(class_linker->ClassInClassTable(referencing_class)) << "Class " + << Class::PrettyClass(referencing_class) << " not in class linker table"; } } // Prune fields and make the contents of the field array deterministic. |