From 7fe56583220d813980f2241e0df13f5aa6627611 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Fri, 14 Oct 2016 18:49:12 +0100 Subject: [PATCH] Fix handling of dex cache arrays for method types. - Add support for relocating method type dex cache arrays. - Add missing call to MethodTypeDexCachePair::Initialize in the class_linker. - Fix alignment calculation for method_types in DexCacheArraysLayout. - Removed unused MethodTypeOffset(uint32_t) method. Fixes tests with --pic. Test: make test-art-host Bug: 30550796 Change-Id: I2bba7228762b9e9834e7659fe62090be78afdfa8 --- compiler/image_writer.cc | 14 ++++++++++++++ patchoat/patchoat.cc | 10 ++++++++++ runtime/class_linker.cc | 1 + runtime/gc/space/image_space.cc | 10 ++++++++++ runtime/mirror/dex_cache-inl.h | 13 +++++++++++++ runtime/mirror/dex_cache.h | 6 +++++- runtime/utils/dex_cache_arrays_layout-inl.h | 14 ++++++-------- runtime/utils/dex_cache_arrays_layout.h | 2 -- 8 files changed, 59 insertions(+), 11 deletions(-) diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 13c73dcf4..756001174 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -461,6 +461,12 @@ void ImageWriter::PrepareDexCacheArraySlots() { dex_cache); DCHECK_EQ(dex_file->NumStringIds() != 0u, dex_cache->GetStrings() != nullptr); AddDexCacheArrayRelocation(dex_cache->GetStrings(), start + layout.StringsOffset(), dex_cache); + + if (dex_cache->GetResolvedMethodTypes() != nullptr) { + AddDexCacheArrayRelocation(dex_cache->GetResolvedMethodTypes(), + start + layout.MethodTypesOffset(), + dex_cache); + } } } @@ -2164,6 +2170,14 @@ void ImageWriter::FixupDexCache(mirror::DexCache* orig_dex_cache, mirror::DexCache::SetElementPtrSize(copy_fields, i, copy, target_ptr_size_); } } + mirror::MethodTypeDexCacheType* orig_method_types = orig_dex_cache->GetResolvedMethodTypes(); + if (orig_method_types != nullptr) { + copy_dex_cache->SetFieldPtrWithSize(mirror::DexCache::ResolvedMethodTypesOffset(), + NativeLocationInImage(orig_method_types), + PointerSize::k64); + orig_dex_cache->FixupResolvedMethodTypes(NativeCopyLocation(orig_method_types, orig_dex_cache), + ImageAddressVisitor(this)); + } // Remove the DexFile pointers. They will be fixed up when the runtime loads the oat file. Leaving // compiler pointers in here will make the output non-deterministic. diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index f3eb663cb..b5c252d91 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -677,6 +677,16 @@ void PatchOat::PatchDexFileArrays(mirror::ObjectArray* img_roots mirror::DexCache::SetElementPtrSize(copy_fields, j, copy, pointer_size); } } + mirror::MethodTypeDexCacheType* orig_method_types = orig_dex_cache->GetResolvedMethodTypes(); + mirror::MethodTypeDexCacheType* relocated_method_types = + RelocatedAddressOfPointer(orig_method_types); + copy_dex_cache->SetField64( + mirror::DexCache::ResolvedMethodTypesOffset(), + static_cast(reinterpret_cast(relocated_method_types))); + if (orig_method_types != nullptr) { + orig_dex_cache->FixupResolvedMethodTypes(RelocatedCopyOf(orig_method_types), + RelocatedPointerVisitor(this)); + } } } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index eb2316b0c..d7d6f2b02 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1377,6 +1377,7 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( std::memory_order_relaxed); } + mirror::MethodTypeDexCachePair::Initialize(method_types); dex_cache->SetResolvedMethodTypes(method_types); } } diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index a40e408bc..bc63b38d2 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1254,6 +1254,16 @@ class ImageSpaceLoader { } } } + + mirror::MethodTypeDexCacheType* method_types = dex_cache->GetResolvedMethodTypes(); + if (method_types != nullptr) { + mirror::MethodTypeDexCacheType* new_method_types = + fixup_adapter.ForwardObject(method_types); + if (method_types != new_method_types) { + dex_cache->SetResolvedMethodTypes(new_method_types); + } + dex_cache->FixupResolvedMethodTypes(new_method_types, fixup_adapter); + } } } { diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index b388f65d8..cf45748bb 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -207,6 +207,19 @@ inline void DexCache::FixupResolvedTypes(GcRoot* dest, const Visi } } +template +inline void DexCache::FixupResolvedMethodTypes(mirror::MethodTypeDexCacheType* dest, + const Visitor& visitor) { + mirror::MethodTypeDexCacheType* src = GetResolvedMethodTypes(); + for (size_t i = 0, count = NumResolvedMethodTypes(); i < count; ++i) { + MethodTypeDexCachePair source = src[i].load(std::memory_order_relaxed); + mirror::MethodType* ptr = source.object.Read(); + mirror::MethodType* new_source = visitor(ptr); + source.object = GcRoot(new_source); + dest[i].store(source, std::memory_order_relaxed); + } +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 2fcabb507..7538c20ff 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -160,6 +160,10 @@ class MANAGED DexCache FINAL : public Object { void FixupResolvedTypes(GcRoot* dest, const Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_); + template + void FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, const Visitor& visitor) + REQUIRES_SHARED(Locks::mutator_lock_); + String* GetLocation() REQUIRES_SHARED(Locks::mutator_lock_) { return GetFieldObject(OFFSET_OF_OBJECT_MEMBER(DexCache, location_)); } @@ -282,7 +286,7 @@ class MANAGED DexCache FINAL : public Object { MethodTypeDexCacheType* GetResolvedMethodTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) { - return GetFieldPtr(ResolvedMethodTypesOffset()); + return GetFieldPtr64(ResolvedMethodTypesOffset()); } void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types) diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h index 5ccd446e0..5ca768456 100644 --- a/runtime/utils/dex_cache_arrays_layout-inl.h +++ b/runtime/utils/dex_cache_arrays_layout-inl.h @@ -39,7 +39,7 @@ inline DexCacheArraysLayout::DexCacheArraysLayout(PointerSize pointer_size, fields_offset_( RoundUp(strings_offset_ + StringsSize(header.string_ids_size_), FieldsAlignment())), method_types_offset_( - RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), Alignment())), + RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), MethodTypesAlignment())), size_( RoundUp(method_types_offset_ + MethodTypesSize(header.proto_ids_size_), Alignment())) { } @@ -51,7 +51,11 @@ inline DexCacheArraysLayout::DexCacheArraysLayout(PointerSize pointer_size, cons inline constexpr size_t DexCacheArraysLayout::Alignment() { // GcRoot<> alignment is 4, i.e. lower than or equal to the pointer alignment. static_assert(alignof(GcRoot) == 4, "Expecting alignof(GcRoot<>) == 4"); - static_assert(alignof(mirror::StringDexCacheType) == 8, "Expecting alignof(StringDexCacheType) == 8"); + static_assert(alignof(mirror::StringDexCacheType) == 8, + "Expecting alignof(StringDexCacheType) == 8"); + static_assert(alignof(mirror::MethodTypeDexCacheType) == 8, + "Expecting alignof(MethodTypeDexCacheType) == 8"); + // This is the same as alignof(MethodTypeDexCacheType). return alignof(mirror::StringDexCacheType); } @@ -120,12 +124,6 @@ inline size_t DexCacheArraysLayout::FieldsAlignment() const { return static_cast(pointer_size_); } -inline size_t DexCacheArraysLayout::MethodTypeOffset(uint32_t proto_idx) const { - return strings_offset_ - + ElementOffset(PointerSize::k64, - proto_idx % mirror::DexCache::kDexCacheMethodTypeCacheSize); -} - inline size_t DexCacheArraysLayout::MethodTypesSize(size_t num_elements) const { size_t cache_size = mirror::DexCache::kDexCacheMethodTypeCacheSize; if (num_elements < cache_size) { diff --git a/runtime/utils/dex_cache_arrays_layout.h b/runtime/utils/dex_cache_arrays_layout.h index e222b46ef..ae3bfab38 100644 --- a/runtime/utils/dex_cache_arrays_layout.h +++ b/runtime/utils/dex_cache_arrays_layout.h @@ -99,8 +99,6 @@ class DexCacheArraysLayout { return method_types_offset_; } - size_t MethodTypeOffset(uint32_t method_type_idx) const; - size_t MethodTypesSize(size_t num_elements) const; size_t MethodTypesAlignment() const; -- 2.11.0