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/object-inl.h b/runtime/mirror/object-inl.h
index 1b03956..99a0d92 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -142,7 +142,7 @@
// OK to look at from-space copies since java.lang.Class.class is not movable.
// See b/114413743
ObjPtr<Class> klass = GetClass<kVerifyFlags, kWithoutReadBarrier>();
- ObjPtr<Class> java_lang_Class = klass->template GetClass<kVerifyFlags, kWithoutReadBarrier>();
+ ObjPtr<Class> java_lang_Class = klass->GetClass<kVerifyFlags, kWithoutReadBarrier>();
return klass == java_lang_Class;
}
@@ -152,24 +152,27 @@
return down_cast<Class*>(this);
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Object::IsObjectArray() {
+ // 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.
constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags);
- return IsArrayInstance<kVerifyFlags, kReadBarrierOption>() &&
- !GetClass<kNewFlags, kReadBarrierOption>()->
- template GetComponentType<kNewFlags, kReadBarrierOption>()->IsPrimitive();
+ return IsArrayInstance<kVerifyFlags>() &&
+ !GetClass<kNewFlags, kWithoutReadBarrier>()->
+ template GetComponentType<kNewFlags, kWithoutReadBarrier>()->IsPrimitive();
}
-template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<class T, VerifyObjectFlags kVerifyFlags>
inline ObjectArray<T>* Object::AsObjectArray() {
- DCHECK((IsObjectArray<kVerifyFlags, kReadBarrierOption>()));
+ DCHECK((IsObjectArray<kVerifyFlags>()));
return down_cast<ObjectArray<T>*>(this);
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Object::IsArrayInstance() {
- return GetClass<kVerifyFlags, kReadBarrierOption>()->
- template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
+ // We do not need a read barrier here, both from-space and to-space version of the class
+ // shall return the same result from IsArrayClass().
+ return GetClass<kVerifyFlags, kWithoutReadBarrier>()->template IsArrayClass<kVerifyFlags>();
}
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
@@ -183,9 +186,9 @@
return down_cast<Reference*>(this);
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline Array* Object::AsArray() {
- DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
+ DCHECK((IsArrayInstance<kVerifyFlags>()));
return down_cast<Array*>(this);
}
@@ -349,14 +352,14 @@
static constexpr ReadBarrierOption kRBO = kWithoutReadBarrier;
size_t result;
constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags);
- if (IsArrayInstance<kVerifyFlags, kRBO>()) {
- result = AsArray<kNewFlags, kRBO>()->template SizeOf<kNewFlags, kRBO>();
+ if (IsArrayInstance<kVerifyFlags>()) {
+ result = AsArray<kNewFlags>()->template SizeOf<kNewFlags, kRBO>();
} else if (IsClass<kNewFlags>()) {
result = AsClass<kNewFlags>()->template SizeOf<kNewFlags, kRBO>();
} else if (GetClass<kNewFlags, kRBO>()->IsStringClass()) {
result = AsString<kNewFlags, kRBO>()->template SizeOf<kNewFlags>();
} else {
- result = GetClass<kNewFlags, kRBO>()->template GetObjectSize<kNewFlags, kRBO>();
+ result = GetClass<kNewFlags, kRBO>()->template GetObjectSize<kNewFlags>();
}
DCHECK_GE(result, sizeof(Object)) << " class=" << Class::PrettyClass(GetClass<kNewFlags, kRBO>());
return result;
@@ -880,7 +883,7 @@
// Presumably GC can happen when we are cross compiling, it should not cause performance
// problems to do pointer size logic.
MemberOffset field_offset = kIsStatic
- ? klass->GetFirstReferenceStaticFieldOffset<kVerifyFlags, kReadBarrierOption>(
+ ? klass->GetFirstReferenceStaticFieldOffset<kVerifyFlags>(
Runtime::Current()->GetClassLinker()->GetImagePointerSize())
: klass->GetFirstReferenceInstanceFieldOffset<kVerifyFlags, kReadBarrierOption>();
for (size_t i = 0u; i < num_reference_fields; ++i) {
@@ -903,13 +906,13 @@
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
inline void Object::VisitStaticFieldsReferences(ObjPtr<Class> klass, const Visitor& visitor) {
- DCHECK(!klass->IsTemp());
+ DCHECK(!klass->IsTemp<kVerifyFlags>());
klass->VisitFieldsReferences<true, kVerifyFlags, kReadBarrierOption>(0, visitor);
}
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline bool Object::IsClassLoader() {
- return GetClass<kVerifyFlags, kReadBarrierOption>()->IsClassLoaderClass();
+ return GetClass<kVerifyFlags, kReadBarrierOption>()->template IsClassLoaderClass<kVerifyFlags>();
}
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
@@ -920,7 +923,7 @@
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline bool Object::IsDexCache() {
- return GetClass<kVerifyFlags, kReadBarrierOption>()->IsDexCacheClass();
+ return GetClass<kVerifyFlags, kReadBarrierOption>()->template IsDexCacheClass<kVerifyFlags>();
}
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>