ART: Clean up verify and read barrier flags.
Remove read barrier option from Class::IsArrayClass() and
related functions. Comparison with null does not need the
read barrier and the primitive type should be the same when
read from the from-space version of a class as when read
from the to-space version.
Propagate the verify flags to a few more functions and
simplify Class::IsClassClass().
Remove pointer size check from Class::EmbeddedVTableOffset()
in preparation for patching the boot image in place before
the Runtime and Thread are fully initialized.
Test: m test-art-host-gtest
Test: testrunner.py --host --gcstress
Bug: 77856493
Change-Id: I8b7a6165fa8e25efd37778e0e6ea049fc2147b24
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index d3f8921..33822d1 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -42,17 +42,17 @@
namespace art {
namespace mirror {
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline uint32_t Class::GetObjectSize() {
// Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
- DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
+ DCHECK((!IsVariableSize<kVerifyFlags>())) << "class=" << PrettyTypeOf();
return GetField32(ObjectSizeOffset());
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline uint32_t Class::GetObjectSizeAllocFastPath() {
// Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
- DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
+ DCHECK((!IsVariableSize<kVerifyFlags>())) << "class=" << PrettyTypeOf();
return GetField32(ObjectSizeAllocFastPathOffset());
}
@@ -304,7 +304,7 @@
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline int32_t Class::GetVTableLength() {
- if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
+ if (ShouldHaveEmbeddedVTable<kVerifyFlags>()) {
return GetEmbeddedVTableLength();
}
return GetVTable<kVerifyFlags, kReadBarrierOption>() != nullptr ?
@@ -313,7 +313,7 @@
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline ArtMethod* Class::GetVTableEntry(uint32_t i, PointerSize pointer_size) {
- if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
+ if (ShouldHaveEmbeddedVTable<kVerifyFlags>()) {
return GetEmbeddedVTableEntry(i, pointer_size);
}
auto* vtable = GetVTable<kVerifyFlags, kReadBarrierOption>();
@@ -322,8 +322,9 @@
i, pointer_size);
}
+template<VerifyObjectFlags kVerifyFlags>
inline int32_t Class::GetEmbeddedVTableLength() {
- return GetField32(MemberOffset(EmbeddedVTableLengthOffset()));
+ return GetField32<kVerifyFlags>(MemberOffset(EmbeddedVTableLengthOffset()));
}
inline void Class::SetEmbeddedVTableLength(int32_t len) {
@@ -374,13 +375,13 @@
return false;
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Class::IsVariableSize() {
// Classes, arrays, and strings vary in size, and so the object_size_ field cannot
// be used to Get their instance size
return IsClassClass<kVerifyFlags>() ||
- IsArrayClass<kVerifyFlags, kReadBarrierOption>() ||
- IsStringClass();
+ IsArrayClass<kVerifyFlags>() ||
+ IsStringClass<kVerifyFlags>();
}
inline void Class::SetObjectSize(uint32_t new_object_size) {
@@ -647,19 +648,18 @@
inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
ObjPtr<Class> super_class = GetSuperClass<kVerifyFlags, kReadBarrierOption>();
return (super_class != nullptr)
- ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags, kReadBarrierOption>(),
- kHeapReferenceSize))
+ ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags>(), kHeapReferenceSize))
: ClassOffset();
}
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template <VerifyObjectFlags kVerifyFlags>
inline MemberOffset Class::GetFirstReferenceStaticFieldOffset(PointerSize pointer_size) {
- DCHECK(IsResolved());
+ DCHECK(IsResolved<kVerifyFlags>());
uint32_t base = sizeof(Class); // Static fields come after the class.
- if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
+ if (ShouldHaveEmbeddedVTable<kVerifyFlags>()) {
// Static fields come after the embedded tables.
base = Class::ComputeClassSize(
- true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size);
+ true, GetEmbeddedVTableLength<kVerifyFlags>(), 0, 0, 0, 0, 0, pointer_size);
}
return MemberOffset(base);
}
@@ -857,8 +857,7 @@
inline bool Class::IsClassClass() {
// OK to look at from-space copies since java.lang.Class.class is not movable.
// See b/114413743
- ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kWithoutReadBarrier>()->
- template GetClass<kVerifyFlags, kWithoutReadBarrier>();
+ ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kWithoutReadBarrier>();
return this == java_lang_Class;
}
@@ -1005,7 +1004,6 @@
}
inline MemberOffset Class::EmbeddedVTableOffset(PointerSize pointer_size) {
- CheckPointerSize(pointer_size);
return MemberOffset(ImtPtrOffset(pointer_size).Uint32Value() + static_cast<size_t>(pointer_size));
}
@@ -1018,15 +1016,18 @@
return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ComponentTypeOffset());
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Class::IsArrayClass() {
- return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr;
+ // We do not need a read barrier for comparing with null.
+ return GetComponentType<kVerifyFlags, kWithoutReadBarrier>() != nullptr;
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Class::IsObjectArrayClass() {
- ObjPtr<Class> const component_type = GetComponentType<kVerifyFlags, kReadBarrierOption>();
- return component_type != nullptr && !component_type->IsPrimitive();
+ // We do not need a read barrier here as the primitive type is constant,
+ // both from-space and to-space component type classes shall yield the same result.
+ ObjPtr<Class> const component_type = GetComponentType<kVerifyFlags, kWithoutReadBarrier>();
+ return component_type != nullptr && !component_type->IsPrimitive<kVerifyFlags>();
}
inline bool Class::IsAssignableFrom(ObjPtr<Class> src) {
@@ -1096,7 +1097,7 @@
dest->SetMethodsPtrInternal(new_methods);
}
// Fix up embedded tables.
- if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) {
+ 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));
@@ -1106,7 +1107,7 @@
}
}
}
- if (!IsTemp() && ShouldHaveImt<kVerifyNone, kReadBarrierOption>()) {
+ 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);