summaryrefslogtreecommitdiff
path: root/compiler/image_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/image_writer.cc')
-rw-r--r--compiler/image_writer.cc36
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.