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/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 9f82b04..ae9acd6d 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -2611,15 +2611,15 @@
if (ReadBarrier::kEnableToSpaceInvariantChecks) {
AssertToSpaceInvariant(nullptr, MemberOffset(0), java_lang_Object_);
}
- CHECK_EQ(byte_size, (java_lang_Object_->GetObjectSize<kVerifyNone, kWithoutReadBarrier>()));
+ CHECK_EQ(byte_size, java_lang_Object_->GetObjectSize<kVerifyNone>());
dummy_obj->SetClass(java_lang_Object_);
CHECK_EQ(byte_size, (dummy_obj->SizeOf<kVerifyNone>()));
} else {
// Use an int array.
dummy_obj->SetClass(int_array_class);
- CHECK((dummy_obj->IsArrayInstance<kVerifyNone, kWithoutReadBarrier>()));
+ CHECK(dummy_obj->IsArrayInstance<kVerifyNone>());
int32_t length = (byte_size - data_offset) / component_size;
- mirror::Array* dummy_arr = dummy_obj->AsArray<kVerifyNone, kWithoutReadBarrier>();
+ mirror::Array* dummy_arr = dummy_obj->AsArray<kVerifyNone>();
dummy_arr->SetLength(length);
CHECK_EQ(dummy_arr->GetLength(), length)
<< "byte_size=" << byte_size << " length=" << length
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index b6877f5..8f064a3 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1247,7 +1247,7 @@
CHECK_EQ(image_header.GetImageBegin(), target_base);
// Fix up dex cache DexFile pointers.
auto* dex_caches = image_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kDexCaches)->
- AsObjectArray<mirror::DexCache, kVerifyNone, kWithoutReadBarrier>();
+ AsObjectArray<mirror::DexCache, kVerifyNone>();
for (int32_t i = 0, count = dex_caches->GetLength(); i < count; ++i) {
mirror::DexCache* dex_cache = dex_caches->Get<kVerifyNone, kWithoutReadBarrier>(i);
// Fix up dex cache pointers.
diff --git a/runtime/gc/verification.cc b/runtime/gc/verification.cc
index 5d234ea..2c31c65 100644
--- a/runtime/gc/verification.cc
+++ b/runtime/gc/verification.cc
@@ -58,8 +58,8 @@
oss << " klass=" << klass;
if (IsValidClass(klass)) {
oss << "(" << klass->PrettyClass() << ")";
- if (klass->IsArrayClass<kVerifyNone, kWithoutReadBarrier>()) {
- oss << " length=" << obj->AsArray<kVerifyNone, kWithoutReadBarrier>()->GetLength();
+ if (klass->IsArrayClass<kVerifyNone>()) {
+ oss << " length=" << obj->AsArray<kVerifyNone>()->GetLength();
}
} else {
oss << " <invalid address>";
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);
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 4015bd2..3d434f1 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -191,8 +191,9 @@
}
// Returns true if the class is an interface.
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsInterface() REQUIRES_SHARED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccInterface) != 0;
+ return (GetAccessFlags<kVerifyFlags>() & kAccInterface) != 0;
}
// Returns true if the class is declared public.
@@ -235,24 +236,27 @@
SetAccessFlags(flags | kAccClassIsFinalizable);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsStringClass() REQUIRES_SHARED(Locks::mutator_lock_) {
- return (GetClassFlags() & kClassFlagString) != 0;
+ return (GetClassFlags<kVerifyFlags>() & kClassFlagString) != 0;
}
ALWAYS_INLINE void SetStringClass() REQUIRES_SHARED(Locks::mutator_lock_) {
SetClassFlags(kClassFlagString | kClassFlagNoReferenceFields);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsClassLoaderClass() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetClassFlags() == kClassFlagClassLoader;
+ return GetClassFlags<kVerifyFlags>() == kClassFlagClassLoader;
}
ALWAYS_INLINE void SetClassLoaderClass() REQUIRES_SHARED(Locks::mutator_lock_) {
SetClassFlags(kClassFlagClassLoader);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsDexCacheClass() REQUIRES_SHARED(Locks::mutator_lock_) {
- return (GetClassFlags() & kClassFlagDexCache) != 0;
+ return (GetClassFlags<kVerifyFlags>() & kClassFlagDexCache) != 0;
}
ALWAYS_INLINE void SetDexCacheClass() REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -260,8 +264,9 @@
}
// Returns true if the class is abstract.
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsAbstract() REQUIRES_SHARED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccAbstract) != 0;
+ return (GetAccessFlags<kVerifyFlags>() & kAccAbstract) != 0;
}
// Returns true if the class is an annotation.
@@ -324,11 +329,12 @@
// Returns true if this class is the placeholder and should retire and
// be replaced with a class with the right size for embedded imt/vtable.
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsTemp() REQUIRES_SHARED(Locks::mutator_lock_) {
- ClassStatus s = GetStatus();
+ ClassStatus s = GetStatus<kVerifyFlags>();
return s < ClassStatus::kResolving &&
s != ClassStatus::kErrorResolved &&
- ShouldHaveEmbeddedVTable();
+ ShouldHaveEmbeddedVTable<kVerifyFlags>();
}
String* GetName() REQUIRES_SHARED(Locks::mutator_lock_); // Returns the cached name.
@@ -426,8 +432,7 @@
// Depth of class from java.lang.Object
uint32_t Depth() REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -468,15 +473,15 @@
return !IsPrimitive() && !IsInterface() && !IsAbstract() && !IsArrayClass();
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsInstantiable() REQUIRES_SHARED(Locks::mutator_lock_) {
- return (!IsPrimitive() && !IsInterface() && !IsAbstract()) ||
- (IsAbstract() && IsArrayClass<kVerifyFlags, kReadBarrierOption>());
+ return (!IsPrimitive<kVerifyFlags>() &&
+ !IsInterface<kVerifyFlags>() &&
+ !IsAbstract<kVerifyFlags>()) ||
+ (IsAbstract<kVerifyFlags>() && IsArrayClass<kVerifyFlags>());
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsObjectArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -503,8 +508,7 @@
ObjPtr<Object> AllocNonMovableObject(Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ALWAYS_INLINE bool IsVariableSize() REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
@@ -543,8 +547,7 @@
return ComputeClassSize(false, 0, 0, 0, 0, 0, 0, pointer_size);
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
uint32_t GetObjectSize() REQUIRES_SHARED(Locks::mutator_lock_);
static MemberOffset ObjectSizeOffset() {
return OFFSET_OF_OBJECT_MEMBER(Class, object_size_);
@@ -557,8 +560,7 @@
void SetObjectSizeAllocFastPath(uint32_t new_object_size) REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
uint32_t GetObjectSizeAllocFastPath() REQUIRES_SHARED(Locks::mutator_lock_);
void SetObjectSizeWithoutChecks(uint32_t new_object_size)
@@ -796,16 +798,14 @@
static_cast<size_t>(pointer_size)));
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool ShouldHaveImt() REQUIRES_SHARED(Locks::mutator_lock_) {
- return ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>();
+ return ShouldHaveEmbeddedVTable<kVerifyFlags>();
}
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool ShouldHaveEmbeddedVTable() REQUIRES_SHARED(Locks::mutator_lock_) {
- return IsInstantiable<kVerifyFlags, kReadBarrierOption>();
+ return IsInstantiable<kVerifyFlags>();
}
bool HasVTable() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -821,6 +821,7 @@
ArtMethod* GetVTableEntry(uint32_t i, PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
int32_t GetEmbeddedVTableLength() REQUIRES_SHARED(Locks::mutator_lock_);
void SetEmbeddedVTableLength(int32_t len) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -976,9 +977,10 @@
// Returns the number of instance fields containing reference types. Does not count fields in any
// super classes.
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
uint32_t NumReferenceInstanceFields() REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(IsResolved());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_));
+ DCHECK(IsResolved<kVerifyFlags>());
+ return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_));
}
uint32_t NumReferenceInstanceFieldsDuringLinking() REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1004,9 +1006,10 @@
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the number of static fields containing reference types.
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
uint32_t NumReferenceStaticFields() REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(IsResolved());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_));
+ DCHECK(IsResolved<kVerifyFlags>());
+ return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_));
}
uint32_t NumReferenceStaticFieldsDuringLinking() REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1020,8 +1023,7 @@
}
// Get the offset of the first reference static field. Other reference static fields follow.
- template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
MemberOffset GetFirstReferenceStaticFieldOffset(PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/class_loader-inl.h b/runtime/mirror/class_loader-inl.h
index 39c8ee0..64b4e74 100644
--- a/runtime/mirror/class_loader-inl.h
+++ b/runtime/mirror/class_loader-inl.h
@@ -33,7 +33,7 @@
VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
if (kVisitClasses) {
// Visit classes loaded after.
- ClassTable* const class_table = GetClassTable();
+ ClassTable* const class_table = GetClassTable<kVerifyFlags>();
if (class_table != nullptr) {
class_table->VisitRoots(visitor);
}
diff --git a/runtime/mirror/class_loader.h b/runtime/mirror/class_loader.h
index f25f18f..e3cb12f 100644
--- a/runtime/mirror/class_loader.h
+++ b/runtime/mirror/class_loader.h
@@ -44,9 +44,10 @@
return GetFieldObject<ClassLoader>(OFFSET_OF_OBJECT_MEMBER(ClassLoader, parent_));
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ClassTable* GetClassTable() REQUIRES_SHARED(Locks::mutator_lock_) {
return reinterpret_cast<ClassTable*>(
- GetField64(OFFSET_OF_OBJECT_MEMBER(ClassLoader, class_table_)));
+ GetField64<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(ClassLoader, class_table_)));
}
void SetClassTable(ClassTable* class_table) REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index bbe15ac..6efb747 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -310,16 +310,17 @@
// Visit arrays after.
if (kVisitNativeRoots) {
VisitDexCachePairs<String, kReadBarrierOption, Visitor>(
- GetStrings(), NumStrings(), visitor);
+ GetStrings<kVerifyFlags>(), NumStrings<kVerifyFlags>(), visitor);
VisitDexCachePairs<Class, kReadBarrierOption, Visitor>(
- GetResolvedTypes(), NumResolvedTypes(), visitor);
+ GetResolvedTypes<kVerifyFlags>(), NumResolvedTypes<kVerifyFlags>(), visitor);
VisitDexCachePairs<MethodType, kReadBarrierOption, Visitor>(
- GetResolvedMethodTypes(), NumResolvedMethodTypes(), visitor);
+ GetResolvedMethodTypes<kVerifyFlags>(), NumResolvedMethodTypes<kVerifyFlags>(), visitor);
- GcRoot<mirror::CallSite>* resolved_call_sites = GetResolvedCallSites();
- for (size_t i = 0, num_call_sites = NumResolvedCallSites(); i != num_call_sites; ++i) {
+ GcRoot<mirror::CallSite>* resolved_call_sites = GetResolvedCallSites<kVerifyFlags>();
+ size_t num_call_sites = NumResolvedCallSites<kVerifyFlags>();
+ for (size_t i = 0; i != num_call_sites; ++i) {
visitor.VisitRootIfNonNull(resolved_call_sites[i].AddressWithoutBarrier());
}
}
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 8401b66..ed0beaf 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -326,16 +326,18 @@
ObjPtr<CallSite> SetResolvedCallSite(uint32_t call_site_idx, ObjPtr<CallSite> resolved)
REQUIRES_SHARED(Locks::mutator_lock_) WARN_UNUSED;
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
StringDexCacheType* GetStrings() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetFieldPtr64<StringDexCacheType*>(StringsOffset());
+ return GetFieldPtr64<StringDexCacheType*, kVerifyFlags>(StringsOffset());
}
void SetStrings(StringDexCacheType* strings) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
SetFieldPtr<false>(StringsOffset(), strings);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
TypeDexCacheType* GetResolvedTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetFieldPtr<TypeDexCacheType*>(ResolvedTypesOffset());
+ return GetFieldPtr<TypeDexCacheType*, kVerifyFlags>(ResolvedTypesOffset());
}
void SetResolvedTypes(TypeDexCacheType* resolved_types)
@@ -364,9 +366,10 @@
SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
MethodTypeDexCacheType* GetResolvedMethodTypes()
ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetFieldPtr64<MethodTypeDexCacheType*>(ResolvedMethodTypesOffset());
+ return GetFieldPtr64<MethodTypeDexCacheType*, kVerifyFlags>(ResolvedMethodTypesOffset());
}
void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types)
@@ -375,10 +378,11 @@
SetFieldPtr<false>(ResolvedMethodTypesOffset(), resolved_method_types);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
GcRoot<CallSite>* GetResolvedCallSites()
ALWAYS_INLINE
REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetFieldPtr<GcRoot<CallSite>*>(ResolvedCallSitesOffset());
+ return GetFieldPtr<GcRoot<CallSite>*, kVerifyFlags>(ResolvedCallSitesOffset());
}
void SetResolvedCallSites(GcRoot<CallSite>* resolved_call_sites)
@@ -387,12 +391,14 @@
SetFieldPtr<false>(ResolvedCallSitesOffset(), resolved_call_sites);
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
size_t NumStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetField32(NumStringsOffset());
+ return GetField32<kVerifyFlags>(NumStringsOffset());
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
size_t NumResolvedTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetField32(NumResolvedTypesOffset());
+ return GetField32<kVerifyFlags>(NumResolvedTypesOffset());
}
size_t NumResolvedMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -403,12 +409,14 @@
return GetField32(NumResolvedFieldsOffset());
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
size_t NumResolvedMethodTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetField32(NumResolvedMethodTypesOffset());
+ return GetField32<kVerifyFlags>(NumResolvedMethodTypesOffset());
}
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
size_t NumResolvedCallSites() REQUIRES_SHARED(Locks::mutator_lock_) {
- return GetField32(NumResolvedCallSitesOffset());
+ return GetField32<kVerifyFlags>(NumResolvedCallSitesOffset());
}
const DexFile* GetDexFile() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
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>
diff --git a/runtime/mirror/object-refvisitor-inl.h b/runtime/mirror/object-refvisitor-inl.h
index bd23971..748f03b 100644
--- a/runtime/mirror/object-refvisitor-inl.h
+++ b/runtime/mirror/object-refvisitor-inl.h
@@ -37,23 +37,23 @@
visitor(this, ClassOffset(), false);
const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>();
if (LIKELY(class_flags == kClassFlagNormal)) {
- DCHECK((!klass->IsVariableSize<kVerifyFlags, kReadBarrierOption>()));
+ DCHECK((!klass->IsVariableSize<kVerifyFlags>()));
VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
DCHECK((!klass->IsClassClass<kVerifyFlags>()));
- DCHECK(!klass->IsStringClass());
- DCHECK(!klass->IsClassLoaderClass());
- DCHECK((!klass->IsArrayClass<kVerifyFlags, kReadBarrierOption>()));
+ DCHECK(!klass->IsStringClass<kVerifyFlags>());
+ DCHECK(!klass->IsClassLoaderClass<kVerifyFlags>());
+ DCHECK((!klass->IsArrayClass<kVerifyFlags>()));
} else {
if ((class_flags & kClassFlagNoReferenceFields) == 0) {
- DCHECK(!klass->IsStringClass());
+ DCHECK(!klass->IsStringClass<kVerifyFlags>());
if (class_flags == kClassFlagClass) {
DCHECK((klass->IsClassClass<kVerifyFlags>()));
ObjPtr<Class> as_klass = AsClass<kVerifyNone>();
as_klass->VisitReferences<kVisitNativeRoots, kVerifyFlags, kReadBarrierOption>(klass,
visitor);
} else if (class_flags == kClassFlagObjectArray) {
- DCHECK((klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
- AsObjectArray<mirror::Object, kVerifyNone, kReadBarrierOption>()->VisitReferences(visitor);
+ DCHECK((klass->IsObjectArrayClass<kVerifyFlags>()));
+ AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences(visitor);
} else if ((class_flags & kClassFlagReference) != 0) {
VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
ref_visitor(klass, AsReference<kVerifyFlags, kReadBarrierOption>());
@@ -70,14 +70,15 @@
}
} else if (kIsDebugBuild) {
CHECK((!klass->IsClassClass<kVerifyFlags>()));
- CHECK((!klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
+ CHECK((!klass->IsObjectArrayClass<kVerifyFlags>()));
// String still has instance fields for reflection purposes but these don't exist in
// actual string instances.
- if (!klass->IsStringClass()) {
+ if (!klass->IsStringClass<kVerifyFlags>()) {
size_t total_reference_instance_fields = 0;
ObjPtr<Class> super_class = klass;
do {
- total_reference_instance_fields += super_class->NumReferenceInstanceFields();
+ total_reference_instance_fields +=
+ super_class->NumReferenceInstanceFields<kVerifyFlags>();
super_class = super_class->GetSuperClass<kVerifyFlags, kReadBarrierOption>();
} while (super_class != nullptr);
// The only reference field should be the object's class. This field is handled at the
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 48ce5c1..8fe9923 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -174,12 +174,9 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Class* AsClass() REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsObjectArray() REQUIRES_SHARED(Locks::mutator_lock_);
- template<class T,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<class T, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ObjectArray<T>* AsObjectArray() REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
@@ -196,11 +193,9 @@
ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
DexCache* AsDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsArrayInstance() REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Array* AsArray() REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>