Refactor Class::FixupNativePointers().
Simplify Class::FixupNativePointers() and fix verify flags
usage. Also clean up verify flags for a few array functions.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 77856493
Change-Id: I5370757827a2a5061b956034434bdc63164eda3f
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 8f064a3..ee4a0f4 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1029,9 +1029,7 @@
if (obj->IsClass<kVerifyNone>()) {
mirror::Class* as_klass = obj->AsClass<kVerifyNone>();
FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_);
- as_klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(as_klass,
- pointer_size_,
- visitor);
+ as_klass->FixupNativePointers<kVerifyNone>(as_klass, pointer_size_, visitor);
// Deal with the pointer arrays. Use the helper function since multiple classes can reference
// the same arrays.
mirror::PointerArray* const vtable = as_klass->GetVTable<kVerifyNone, kWithoutReadBarrier>();
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 8bdd561..a31a9144 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -189,8 +189,9 @@
T GetElementPtrSize(uint32_t idx, PointerSize ptr_size)
REQUIRES_SHARED(Locks::mutator_lock_);
+ template<VerifyObjectFlags kVerifyFlags = kVerifyNone>
void** ElementAddress(size_t index, PointerSize ptr_size) REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK_LT(index, static_cast<size_t>(GetLength()));
+ DCHECK_LT(index, static_cast<size_t>(GetLength<kVerifyFlags>()));
return reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(this) +
Array::DataOffset(static_cast<size_t>(ptr_size)).Uint32Value() +
static_cast<size_t>(ptr_size) * index);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 33822d1..df70fab 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -251,18 +251,14 @@
uint32_t num_direct,
uint32_t num_virtual) {
DCHECK_LE(num_direct + num_virtual, (new_methods == nullptr) ? 0 : new_methods->size());
- SetMethodsPtrInternal(new_methods);
+ SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, methods_),
+ static_cast<uint64_t>(reinterpret_cast<uintptr_t>(new_methods)));
SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_),
dchecked_integral_cast<uint16_t>(num_direct + num_virtual));
SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_),
dchecked_integral_cast<uint16_t>(num_direct));
}
-inline void Class::SetMethodsPtrInternal(LengthPrefixedArray<ArtMethod>* new_methods) {
- SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, methods_),
- static_cast<uint64_t>(reinterpret_cast<uintptr_t>(new_methods)));
-}
-
template<VerifyObjectFlags kVerifyFlags>
inline ArtMethod* Class::GetVirtualMethod(size_t i, PointerSize pointer_size) {
CheckPointerSize(pointer_size);
@@ -1069,49 +1065,42 @@
return arr != nullptr ? arr->size() : 0u;
}
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
+template <typename T, VerifyObjectFlags kVerifyFlags, typename Visitor>
+inline void Class::FixupNativePointer(
+ Class* dest, PointerSize pointer_size, const Visitor& visitor, MemberOffset member_offset) {
+ void** address =
+ reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) + member_offset.Uint32Value());
+ T old_value = GetFieldPtrWithSize<T, kVerifyFlags>(member_offset, pointer_size);
+ T new_value = visitor(old_value, address);
+ if (old_value != new_value) {
+ dest->SetFieldPtrWithSize</* kTransactionActive */ false,
+ /* kCheckTransaction */ true,
+ kVerifyNone>(member_offset, new_value, pointer_size);
+ }
+}
+
+template <VerifyObjectFlags kVerifyFlags, typename Visitor>
inline void Class::FixupNativePointers(Class* dest,
PointerSize pointer_size,
const Visitor& visitor) {
- auto dest_address_fn = [dest](MemberOffset offset) {
- return reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) + offset.Uint32Value());
- };
// Update the field arrays.
- LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr();
- void** sfields_dest_address = dest_address_fn(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
- LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields, sfields_dest_address);
- if (sfields != new_sfields) {
- dest->SetSFieldsPtrUnchecked(new_sfields);
- }
- LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr();
- void** ifields_dest_address = dest_address_fn(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
- LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields, ifields_dest_address);
- if (ifields != new_ifields) {
- dest->SetIFieldsPtrUnchecked(new_ifields);
- }
+ FixupNativePointer<LengthPrefixedArray<ArtField>*, kVerifyFlags>(
+ dest, pointer_size, visitor, OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+ FixupNativePointer<LengthPrefixedArray<ArtField>*, kVerifyFlags>(
+ dest, pointer_size, visitor, OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
// Update method array.
- LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
- void** methods_dest_address = dest_address_fn(OFFSET_OF_OBJECT_MEMBER(Class, methods_));
- LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods, methods_dest_address);
- if (methods != new_methods) {
- dest->SetMethodsPtrInternal(new_methods);
- }
+ FixupNativePointer<LengthPrefixedArray<ArtMethod>*, kVerifyFlags>(
+ dest, pointer_size, visitor, OFFSET_OF_OBJECT_MEMBER(Class, methods_));
// Fix up embedded tables.
if (!IsTemp<kVerifyNone>() && ShouldHaveEmbeddedVTable<kVerifyNone>()) {
- for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) {
- ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size);
- void** method_dest_addr = dest_address_fn(EmbeddedVTableEntryOffset(i, pointer_size));
- ArtMethod* new_method = visitor(method, method_dest_addr);
- if (method != new_method) {
- dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size);
- }
+ for (int32_t i = 0, count = GetEmbeddedVTableLength<kVerifyFlags>(); i < count; ++i) {
+ FixupNativePointer<ArtMethod*, kVerifyFlags>(
+ dest, pointer_size, visitor, EmbeddedVTableEntryOffset(i, pointer_size));
}
}
if (!IsTemp<kVerifyNone>() && ShouldHaveImt<kVerifyNone>()) {
- ImTable* imt = GetImt(pointer_size);
- void** imt_dest_addr = dest_address_fn(ImtPtrOffset(pointer_size));
- ImTable* new_imt = visitor(imt, imt_dest_addr);
- dest->SetImt(new_imt, pointer_size);
+ FixupNativePointer<ImTable*, kVerifyFlags>(
+ dest, pointer_size, visitor, ImtPtrOffset(pointer_size));
}
}
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 3d434f1..f640d3b 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1263,14 +1263,14 @@
// the corresponding entry in dest if visitor(obj) != obj to prevent dirty memory. Dest should be
// initialized to a copy of *this to prevent issues. Does not visit the ArtMethod and ArtField
// roots.
- template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
- typename Visitor>
+ template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, typename Visitor>
void FixupNativePointers(Class* dest, PointerSize pointer_size, const Visitor& visitor)
REQUIRES_SHARED(Locks::mutator_lock_);
private:
- ALWAYS_INLINE void SetMethodsPtrInternal(LengthPrefixedArray<ArtMethod>* new_methods)
+ template <typename T, VerifyObjectFlags kVerifyFlags, typename Visitor>
+ void FixupNativePointer(
+ Class* dest, PointerSize pointer_size, const Visitor& visitor, MemberOffset member_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
ALWAYS_INLINE static ArraySlice<ArtMethod> GetMethodsSliceRangeUnchecked(
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index ed0beaf..22ccd20 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -401,12 +401,14 @@
return GetField32<kVerifyFlags>(NumResolvedTypesOffset());
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
size_t NumResolvedMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetField32(NumResolvedMethodsOffset());
+ return GetField32<kVerifyFlags>(NumResolvedMethodsOffset());
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
size_t NumResolvedFields() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetField32(NumResolvedFieldsOffset());
+ return GetField32<kVerifyFlags>(NumResolvedFieldsOffset());
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
diff --git a/runtime/mirror/iftable.h b/runtime/mirror/iftable.h
index 9e3c9af..3d4c5a7 100644
--- a/runtime/mirror/iftable.h
+++ b/runtime/mirror/iftable.h
@@ -39,9 +39,15 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ PointerArray* GetMethodArrayOrNull(int32_t i) REQUIRES_SHARED(Locks::mutator_lock_) {
+ return down_cast<PointerArray*>(
+ Get<kVerifyFlags, kReadBarrierOption>((i * kMax) + kMethodArray));
+ }
+
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
+ ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
PointerArray* GetMethodArray(int32_t i) REQUIRES_SHARED(Locks::mutator_lock_) {
- auto* method_array = down_cast<PointerArray*>(Get<kVerifyFlags, kReadBarrierOption>(
- (i * kMax) + kMethodArray));
+ PointerArray* method_array = GetMethodArrayOrNull<kVerifyFlags, kReadBarrierOption>(i);
DCHECK(method_array != nullptr);
return method_array;
}
@@ -49,9 +55,8 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
size_t GetMethodArrayCount(int32_t i) REQUIRES_SHARED(Locks::mutator_lock_) {
- auto* method_array = down_cast<PointerArray*>(
- Get<kVerifyFlags, kReadBarrierOption>((i * kMax) + kMethodArray));
- return method_array == nullptr ? 0u : method_array->GetLength();
+ PointerArray* method_array = GetMethodArrayOrNull<kVerifyFlags, kReadBarrierOption>(i);
+ return method_array == nullptr ? 0u : method_array->GetLength<kVerifyFlags>();
}
void SetMethodArray(int32_t i, ObjPtr<PointerArray> arr) REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index 1d2f47f..7d101bf 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -67,7 +67,7 @@
template<class T> template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline T* ObjectArray<T>::Get(int32_t i) {
- if (!CheckIsValidIndex(i)) {
+ if (!CheckIsValidIndex<kVerifyFlags>(i)) {
DCHECK(Thread::Current()->IsExceptionPending());
return nullptr;
}