Merge "Fix handling of dex cache arrays for method types."
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index fbdb115..8f15ea4 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -461,6 +461,12 @@
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);
+ }
}
}
@@ -2170,6 +2176,14 @@
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<false>(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 50076f9..986f265 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -677,6 +677,16 @@
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<false>(
+ mirror::DexCache::ResolvedMethodTypesOffset(),
+ static_cast<int64_t>(reinterpret_cast<uintptr_t>(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 239cdae..d07aa89 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1374,6 +1374,7 @@
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 81850067..e9c8b95 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1255,6 +1255,16 @@
}
}
}
+
+ 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<kWithoutReadBarrier>(new_method_types, fixup_adapter);
+ }
}
}
{
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index 13d0108..86b5e7a 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -208,6 +208,19 @@
}
}
+template <ReadBarrierOption kReadBarrierOption, typename Visitor>
+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<kReadBarrierOption>();
+ mirror::MethodType* new_source = visitor(ptr);
+ source.object = GcRoot<MethodType>(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 bbe98c2..c3c7ab4 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -160,6 +160,10 @@
void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor)
REQUIRES_SHARED(Locks::mutator_lock_);
+ template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
+ void FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, const Visitor& visitor)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
String* GetLocation() REQUIRES_SHARED(Locks::mutator_lock_) {
return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
}
@@ -283,7 +287,7 @@
MethodTypeDexCacheType* GetResolvedMethodTypes()
ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetFieldPtr<MethodTypeDexCacheType*>(ResolvedMethodTypesOffset());
+ return GetFieldPtr64<MethodTypeDexCacheType*>(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 5ccd446..5ca7684 100644
--- a/runtime/utils/dex_cache_arrays_layout-inl.h
+++ b/runtime/utils/dex_cache_arrays_layout-inl.h
@@ -39,7 +39,7 @@
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 constexpr size_t DexCacheArraysLayout::Alignment() {
// GcRoot<> alignment is 4, i.e. lower than or equal to the pointer alignment.
static_assert(alignof(GcRoot<mirror::Class>) == 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 @@
return static_cast<size_t>(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 e222b46..ae3bfab 100644
--- a/runtime/utils/dex_cache_arrays_layout.h
+++ b/runtime/utils/dex_cache_arrays_layout.h
@@ -99,8 +99,6 @@
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;