diff options
author | 2018-09-07 11:45:46 +0100 | |
---|---|---|
committer | 2018-09-17 18:11:54 +0100 | |
commit | 98db89cef0be48e4b8cdd6738f1af26b0d908f45 (patch) | |
tree | bea405e4f48784305c6709d3f5b0c7355ed645fe | |
parent | c3776b8e1220bf33a596bb69d613adf5db9d8bd1 (diff) |
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
-rw-r--r-- | runtime/gc/collector/concurrent_copying.cc | 6 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 2 | ||||
-rw-r--r-- | runtime/gc/verification.cc | 4 | ||||
-rw-r--r-- | runtime/mirror/class-inl.h | 53 | ||||
-rw-r--r-- | runtime/mirror/class.h | 68 | ||||
-rw-r--r-- | runtime/mirror/class_loader-inl.h | 2 | ||||
-rw-r--r-- | runtime/mirror/class_loader.h | 3 | ||||
-rw-r--r-- | runtime/mirror/dex_cache-inl.h | 11 | ||||
-rw-r--r-- | runtime/mirror/dex_cache.h | 24 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 41 | ||||
-rw-r--r-- | runtime/mirror/object-refvisitor-inl.h | 21 | ||||
-rw-r--r-- | runtime/mirror/object.h | 13 |
12 files changed, 130 insertions, 118 deletions
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc index 9f82b04f79..ae9acd6d9b 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -2611,15 +2611,15 @@ void ConcurrentCopying::FillWithDummyObject(Thread* const self, 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 b6877f59ae..8f064a3dc2 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1247,7 +1247,7 @@ class ImageSpace::Loader { 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 5d234eaac3..2c31c65514 100644 --- a/runtime/gc/verification.cc +++ b/runtime/gc/verification.cc @@ -58,8 +58,8 @@ std::string Verification::DumpObjectInfo(const void* addr, const char* tag) cons 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 d3f89216b9..33822d1b27 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 @@ inline bool Class::HasVTable() { 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 @@ inline int32_t Class::GetVTableLength() { 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 @@ inline ArtMethod* Class::GetVTableEntry(uint32_t i, PointerSize pointer_size) { 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 @@ inline bool Class::Implements(ObjPtr<Class> klass) { 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 @@ template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 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 @@ template<VerifyObjectFlags kVerifyFlags> 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 IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() { } 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 @@ inline Class* Class::GetComponentType() { 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 @@ inline void Class::FixupNativePointers(Class* dest, 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 @@ inline void Class::FixupNativePointers(Class* dest, } } } - 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 4015bd2f1a..3d434f1f7d 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -191,8 +191,9 @@ class MANAGED Class final : public Object { } // 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { } // 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 @@ class MANAGED Class final : public Object { // 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 @@ class MANAGED Class final : public Object { // 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { // 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 @@ class MANAGED Class final : public Object { 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 @@ class MANAGED Class final : public Object { } // 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 39c8ee0d60..64b4e74f4c 100644 --- a/runtime/mirror/class_loader-inl.h +++ b/runtime/mirror/class_loader-inl.h @@ -33,7 +33,7 @@ inline void ClassLoader::VisitReferences(ObjPtr<mirror::Class> klass, const Visi 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 f25f18fce8..e3cb12f16f 100644 --- a/runtime/mirror/class_loader.h +++ b/runtime/mirror/class_loader.h @@ -44,9 +44,10 @@ class MANAGED ClassLoader : public Object { 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 bbe15ac1bb..6efb7474e0 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -310,16 +310,17 @@ inline void DexCache::VisitReferences(ObjPtr<Class> klass, const Visitor& visito // 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 8401b66ee4..ed0beafa08 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -326,16 +326,18 @@ class MANAGED DexCache final : public Object { 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 @@ class MANAGED DexCache final : public Object { 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 @@ class MANAGED DexCache final : public Object { 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 @@ class MANAGED DexCache final : public Object { 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 @@ class MANAGED DexCache final : public Object { 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 1b03956123..99a0d92f21 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -142,7 +142,7 @@ inline bool Object::IsClass() { // 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 @@ inline Class* Object::AsClass() { 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 @@ inline Reference* Object::AsReference() { 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 @@ inline size_t Object::SizeOf() { 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 @@ inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& v // 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 @@ inline void Object::VisitInstanceFieldsReferences(ObjPtr<Class> klass, const Vis 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 @@ inline mirror::ClassLoader* Object::AsClassLoader() { 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 bd239713c5..748f03b862 100644 --- a/runtime/mirror/object-refvisitor-inl.h +++ b/runtime/mirror/object-refvisitor-inl.h @@ -37,23 +37,23 @@ inline void Object::VisitReferences(const Visitor& visitor, 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 @@ inline void Object::VisitReferences(const Visitor& visitor, } } 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 48ce5c1c42..8fe9923974 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -174,12 +174,9 @@ class MANAGED LOCKABLE Object { 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 @@ class MANAGED LOCKABLE Object { 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> |