ART: Move DexCache arrays to native.
This CL has a companion CL in libcore/
https://android-review.googlesource.com/162985
Change-Id: Icbc9e20ad1b565e603195b12714762bb446515fa
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index a71197a..88622cc 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -523,18 +523,60 @@
auto* dex_caches = down_cast<mirror::ObjectArray<mirror::DexCache>*>(
img_roots->Get(ImageHeader::kDexCaches));
for (size_t i = 0, count = dex_caches->GetLength(); i < count; ++i) {
- auto* dex_cache = dex_caches->GetWithoutChecks(i);
- auto* fields = dex_cache->GetResolvedFields();
- if (fields != nullptr) {
- CHECK(!fields->IsObjectArray());
- CHECK(fields->IsArrayInstance());
- FixupNativePointerArray(fields);
+ auto* orig_dex_cache = dex_caches->GetWithoutChecks(i);
+ auto* copy_dex_cache = RelocatedCopyOf(orig_dex_cache);
+ const size_t pointer_size = InstructionSetPointerSize(isa_);
+ // Though the DexCache array fields are usually treated as native pointers, we set the full
+ // 64-bit values here, clearing the top 32 bits for 32-bit targets. The zero-extension is
+ // done by casting to the unsigned type uintptr_t before casting to int64_t, i.e.
+ // static_cast<int64_t>(reinterpret_cast<uintptr_t>(image_begin_ + offset))).
+ GcRoot<mirror::String>* orig_strings = orig_dex_cache->GetStrings();
+ GcRoot<mirror::String>* relocated_strings = RelocatedAddressOfPointer(orig_strings);
+ copy_dex_cache->SetField64<false>(
+ mirror::DexCache::StringsOffset(),
+ static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_strings)));
+ if (orig_strings != nullptr) {
+ GcRoot<mirror::String>* copy_strings = RelocatedCopyOf(orig_strings);
+ for (size_t j = 0, num = orig_dex_cache->NumStrings(); j != num; ++j) {
+ copy_strings[j] = GcRoot<mirror::String>(RelocatedAddressOfPointer(orig_strings[j].Read()));
+ }
}
- auto* methods = dex_cache->GetResolvedMethods();
- if (methods != nullptr) {
- CHECK(!methods->IsObjectArray());
- CHECK(methods->IsArrayInstance());
- FixupNativePointerArray(methods);
+ GcRoot<mirror::Class>* orig_types = orig_dex_cache->GetResolvedTypes();
+ GcRoot<mirror::Class>* relocated_types = RelocatedAddressOfPointer(orig_types);
+ copy_dex_cache->SetField64<false>(
+ mirror::DexCache::ResolvedTypesOffset(),
+ static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_types)));
+ if (orig_types != nullptr) {
+ GcRoot<mirror::Class>* copy_types = RelocatedCopyOf(orig_types);
+ for (size_t j = 0, num = orig_dex_cache->NumResolvedTypes(); j != num; ++j) {
+ copy_types[j] = GcRoot<mirror::Class>(RelocatedAddressOfPointer(orig_types[j].Read()));
+ }
+ }
+ ArtMethod** orig_methods = orig_dex_cache->GetResolvedMethods();
+ ArtMethod** relocated_methods = RelocatedAddressOfPointer(orig_methods);
+ copy_dex_cache->SetField64<false>(
+ mirror::DexCache::ResolvedMethodsOffset(),
+ static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_methods)));
+ if (orig_methods != nullptr) {
+ ArtMethod** copy_methods = RelocatedCopyOf(orig_methods);
+ for (size_t j = 0, num = orig_dex_cache->NumResolvedMethods(); j != num; ++j) {
+ ArtMethod* orig = mirror::DexCache::GetElementPtrSize(orig_methods, j, pointer_size);
+ ArtMethod* copy = RelocatedAddressOfPointer(orig);
+ mirror::DexCache::SetElementPtrSize(copy_methods, j, copy, pointer_size);
+ }
+ }
+ ArtField** orig_fields = orig_dex_cache->GetResolvedFields();
+ ArtField** relocated_fields = RelocatedAddressOfPointer(orig_fields);
+ copy_dex_cache->SetField64<false>(
+ mirror::DexCache::ResolvedFieldsOffset(),
+ static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_fields)));
+ if (orig_fields != nullptr) {
+ ArtField** copy_fields = RelocatedCopyOf(orig_fields);
+ for (size_t j = 0, num = orig_dex_cache->NumResolvedFields(); j != num; ++j) {
+ ArtField* orig = mirror::DexCache::GetElementPtrSize(orig_fields, j, pointer_size);
+ ArtField* copy = RelocatedAddressOfPointer(orig);
+ mirror::DexCache::SetElementPtrSize(copy_fields, j, copy, pointer_size);
+ }
}
}
}
@@ -627,6 +669,7 @@
if (object->IsClass<kVerifyNone>()) {
auto* klass = object->AsClass();
auto* copy_klass = down_cast<mirror::Class*>(copy);
+ copy_klass->SetDexCacheStrings(RelocatedAddressOfPointer(klass->GetDexCacheStrings()));
copy_klass->SetSFieldsPtrUnchecked(RelocatedAddressOfPointer(klass->GetSFieldsPtr()));
copy_klass->SetIFieldsPtrUnchecked(RelocatedAddressOfPointer(klass->GetIFieldsPtr()));
copy_klass->SetDirectMethodsPtrUnchecked(
@@ -673,8 +716,10 @@
// Just update the entry points if it looks like we should.
// TODO: sanity check all the pointers' values
copy->SetDeclaringClass(RelocatedAddressOfPointer(object->GetDeclaringClass()));
- copy->SetDexCacheResolvedMethods(RelocatedAddressOfPointer(object->GetDexCacheResolvedMethods()));
- copy->SetDexCacheResolvedTypes(RelocatedAddressOfPointer(object->GetDexCacheResolvedTypes()));
+ copy->SetDexCacheResolvedMethods(
+ RelocatedAddressOfPointer(object->GetDexCacheResolvedMethods(pointer_size)), pointer_size);
+ copy->SetDexCacheResolvedTypes(
+ RelocatedAddressOfPointer(object->GetDexCacheResolvedTypes(pointer_size)), pointer_size);
copy->SetEntryPointFromQuickCompiledCodePtrSize(RelocatedAddressOfPointer(
object->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)), pointer_size);
copy->SetEntryPointFromJniPtrSize(RelocatedAddressOfPointer(