diff options
author | 2015-08-03 11:56:49 +0100 | |
---|---|---|
committer | 2015-09-03 17:30:57 +0100 | |
commit | 05792b98980741111b4d0a24d68cff2a8e070a3a (patch) | |
tree | bad79a387bcbdaefc87c07b388099960ca9caff3 /patchoat/patchoat.cc | |
parent | c26b4512a01d46756683a4f5e186a0b7f397f251 (diff) |
ART: Move DexCache arrays to native.
This CL has a companion CL in libcore/
https://android-review.googlesource.com/162985
Change-Id: Icbc9e20ad1b565e603195b12714762bb446515fa
Diffstat (limited to 'patchoat/patchoat.cc')
-rw-r--r-- | patchoat/patchoat.cc | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index a71197a6ce..88622ccc9b 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -523,18 +523,60 @@ void PatchOat::PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots 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())); + } + } + 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())); + } } - auto* methods = dex_cache->GetResolvedMethods(); - if (methods != nullptr) { - CHECK(!methods->IsObjectArray()); - CHECK(methods->IsArrayInstance()); - FixupNativePointerArray(methods); + 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 @@ void PatchOat::VisitObject(mirror::Object* object) { 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 @@ void PatchOat::FixupMethod(ArtMethod* object, ArtMethod* copy) { // 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( |