Avoid unnecessary read barriers in mirror::Class.

Test: m test-art-host-gtest
Test: testrunner.py --host
Change-Id: Id98ebedf185bfc7f31eda506604c072f68b7a084
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 3c41836..6b9ba8c 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -294,16 +294,20 @@
 }
 
 inline bool Class::HasVTable() {
-  return GetVTable() != nullptr || ShouldHaveEmbeddedVTable();
+  // No read barrier is needed for comparing with null.
+  return GetVTable<kDefaultVerifyFlags, kWithoutReadBarrier>() != nullptr ||
+         ShouldHaveEmbeddedVTable();
 }
 
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
 inline int32_t Class::GetVTableLength() {
   if (ShouldHaveEmbeddedVTable<kVerifyFlags>()) {
     return GetEmbeddedVTableLength();
   }
-  return GetVTable<kVerifyFlags, kReadBarrierOption>() != nullptr ?
-      GetVTable<kVerifyFlags, kReadBarrierOption>()->GetLength() : 0;
+  // We do not need a read barrier here as the length is constant,
+  // both from-space and to-space vtables shall yield the same result.
+  ObjPtr<PointerArray> vtable = GetVTable<kVerifyFlags, kWithoutReadBarrier>();
+  return vtable != nullptr ? vtable->GetLength() : 0;
 }
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
@@ -311,9 +315,9 @@
   if (ShouldHaveEmbeddedVTable<kVerifyFlags>()) {
     return GetEmbeddedVTableEntry(i, pointer_size);
   }
-  auto* vtable = GetVTable<kVerifyFlags, kReadBarrierOption>();
+  ObjPtr<PointerArray> vtable = GetVTable<kVerifyFlags, kReadBarrierOption>();
   DCHECK(vtable != nullptr);
-  return vtable->template GetElementPtrSize<ArtMethod*, kVerifyFlags>(i, pointer_size);
+  return vtable->GetElementPtrSize<ArtMethod*, kVerifyFlags>(i, pointer_size);
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -623,9 +627,11 @@
   return ret.Ptr();
 }
 
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
 inline int32_t Class::GetIfTableCount() {
-  return GetIfTable<kVerifyFlags, kReadBarrierOption>()->Count();
+  // We do not need a read barrier here as the length is constant,
+  // both from-space and to-space iftables shall yield the same result.
+  return GetIfTable<kVerifyFlags, kWithoutReadBarrier>()->Count();
 }
 
 inline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) {
@@ -969,7 +975,17 @@
   // 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>();
+  constexpr VerifyObjectFlags kNewFlags = RemoveThisFlags(kVerifyFlags);
+  return component_type != nullptr && !component_type->IsPrimitive<kNewFlags>();
+}
+
+template<VerifyObjectFlags kVerifyFlags>
+bool Class::IsPrimitiveArray() {
+  // 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>();
+  constexpr VerifyObjectFlags kNewFlags = RemoveThisFlags(kVerifyFlags);
+  return component_type != nullptr && component_type->IsPrimitive<kNewFlags>();
 }
 
 inline bool Class::IsAssignableFrom(ObjPtr<Class> src) {