Simplify Class::IsArtFieldClass().

Fix the slight glitch that when ImageSpace::VerifyImageAllocations()
called in ImageSpace::Create(), the ArtField and ArtMethod class roots
weren't set, which were used by DCHECKs in Object::Size(), which
VerifyImageAllocations() calls, by delaying the point of the
VerifyImageAllocations() call to Runtime::Init() at which point the
class linker has set the class roots.

To completely disable read barriers from Object::SizeOf(), the
ReadBarrierOption template parameter should have been added to
Class::GetInstanceField(), which calls GetFieldObject(), when it's
called from Class::IsArtFieldClass(). This change fixes this by
removing the need for the call, instead of adding the
ReadBarrierOption parameter.

Bug: 12687968
Change-Id: Ibbecc08f4e3b898851805d690dff8ccac55e94f2
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 5036095..6ea94a9 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -253,9 +253,12 @@
 
   std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename, image_location,
                                              map.release(), bitmap.release()));
-  if (kIsDebugBuild) {
-    space->VerifyImageAllocations();
-  }
+
+  // VerifyImageAllocations() will be called later in Runtime::Init()
+  // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_
+  // and ArtField::java_lang_reflect_ArtField_, which are used from
+  // Object::SizeOf() which VerifyImageAllocations() calls, are not
+  // set yet at this point.
 
   space->oat_file_.reset(space->OpenOatFile(image_filename, error_msg));
   if (space->oat_file_.get() == nullptr) {
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
index 36e62c2..30cd180 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/mirror/art_field.h
@@ -122,7 +122,7 @@
   void SetObj(Object* object, Object* new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static Class* GetJavaLangReflectArtField() {
-    DCHECK(java_lang_reflect_ArtField_ != NULL);
+    DCHECK(java_lang_reflect_ArtField_ != nullptr);
     return java_lang_reflect_ArtField_;
   }
 
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index 1c2954e..34fe0bf 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -407,9 +407,8 @@
 
   static void SetClass(Class* java_lang_reflect_ArtMethod);
 
-  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   static Class* GetJavaLangReflectArtMethod() {
-    // This does not need a RB because it is a root.
+    DCHECK(java_lang_reflect_ArtMethod_ != nullptr);
     return java_lang_reflect_ArtMethod_;
   }
 
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 18be2f1..512a66f 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -509,17 +509,12 @@
   VisitStaticFieldsReferences<kVisitClass>(this, visitor);
 }
 
-template<ReadBarrierOption kReadBarrierOption>
-inline bool Class::IsArtFieldClass() {
-  Class* java_lang_Class = GetClass<kVerifyNone, kReadBarrierOption>();
-  Class* java_lang_reflect_ArtField =
-      java_lang_Class->GetInstanceField(0)->GetClass<kVerifyNone, kReadBarrierOption>();
-  return this == java_lang_reflect_ArtField;
+inline bool Class::IsArtFieldClass() const {
+  return this == ArtField::GetJavaLangReflectArtField();
 }
 
-template<ReadBarrierOption kReadBarrierOption>
-inline bool Class::IsArtMethodClass() {
-  return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
+inline bool Class::IsArtMethodClass() const {
+  return this == ArtMethod::GetJavaLangReflectArtMethod();
 }
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index d8cbb32..40c9975 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -371,15 +371,13 @@
            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsClassClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  bool IsStringClass() const;
+  bool IsStringClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool IsThrowableClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  bool IsArtFieldClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool IsArtFieldClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  bool IsArtMethodClass();
+  bool IsArtMethodClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static MemberOffset ComponentTypeOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Class, component_type_);
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index a2072a2..62ab2c1 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -217,8 +217,7 @@
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsArtField() {
-  return GetClass<kVerifyFlags, kReadBarrierOption>()->
-      template IsArtFieldClass<kReadBarrierOption>();
+  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsArtFieldClass();
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -229,8 +228,7 @@
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsArtMethod() {
-  return GetClass<kVerifyFlags, kReadBarrierOption>()->
-      template IsArtMethodClass<kReadBarrierOption>();
+  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsArtMethodClass();
 }
 
 template<VerifyObjectFlags kVerifyFlags>
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 95a6b39..dcbf42d 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -622,6 +622,9 @@
   class_linker_ = new ClassLinker(intern_table_);
   if (GetHeap()->HasImageSpace()) {
     class_linker_->InitFromImage();
+    if (kIsDebugBuild) {
+      GetHeap()->GetImageSpace()->VerifyImageAllocations();
+    }
   } else {
     CHECK(options->boot_class_path_ != NULL);
     CHECK_NE(options->boot_class_path_->size(), 0U);