Merge "Add read barriers to the constant roots."
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 65799cd..43bdf49 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -168,8 +168,7 @@
 
 template<typename T>
 inline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
-  DCHECK(array_class_ != NULL);
-  Array* raw_array = Array::Alloc<true>(self, array_class_, length, sizeof(T),
+  Array* raw_array = Array::Alloc<true>(self, GetArrayClass(), length, sizeof(T),
                                         Runtime::Current()->GetHeap()->GetCurrentAllocator());
   return down_cast<PrimitiveArray<T>*>(raw_array);
 }
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 64e2317..25a4535 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -20,6 +20,7 @@
 #include "gc/allocator_type.h"
 #include "object.h"
 #include "object_callbacks.h"
+#include "read_barrier.h"
 
 namespace art {
 
@@ -160,9 +161,10 @@
     array_class_ = array_class;
   }
 
-  static Class* GetArrayClass() {
+  static Class* GetArrayClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(array_class_ != nullptr);
-    return array_class_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(
+        &array_class_);
   }
 
   static void ResetArrayClass() {
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
index 4858613..502cec7 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/mirror/art_field.h
@@ -23,6 +23,7 @@
 #include "modifiers.h"
 #include "object.h"
 #include "object_callbacks.h"
+#include "read_barrier.h"
 
 namespace art {
 
@@ -121,9 +122,11 @@
   template<bool kTransactionActive>
   void SetObj(Object* object, Object* new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  static Class* GetJavaLangReflectArtField() {
+  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+  static Class* GetJavaLangReflectArtField()  SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(java_lang_reflect_ArtField_ != nullptr);
-    return java_lang_reflect_ArtField_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kReadBarrierOption>(
+        &java_lang_reflect_ArtField_);
   }
 
   static void SetClass(Class* java_lang_reflect_ArtField);
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index 1c21b81..a55c48b 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -24,6 +24,7 @@
 #include "object.h"
 #include "object_callbacks.h"
 #include "quick/quick_method_frame_info.h"
+#include "read_barrier.h"
 
 namespace art {
 
@@ -409,9 +410,11 @@
 
   static void SetClass(Class* java_lang_reflect_ArtMethod);
 
-  static Class* GetJavaLangReflectArtMethod() {
+  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+  static Class* GetJavaLangReflectArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(java_lang_reflect_ArtMethod_ != nullptr);
-    return java_lang_reflect_ArtMethod_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kReadBarrierOption>(
+        &java_lang_reflect_ArtMethod_);
   }
 
   static void ResetClass();
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 6205f70..451235c 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -511,12 +511,14 @@
   VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
 }
 
+template<ReadBarrierOption kReadBarrierOption>
 inline bool Class::IsArtFieldClass() const {
-  return this == ArtField::GetJavaLangReflectArtField();
+  return this == ArtField::GetJavaLangReflectArtField<kReadBarrierOption>();
 }
 
+template<ReadBarrierOption kReadBarrierOption>
 inline bool Class::IsArtMethodClass() const {
-  return this == ArtMethod::GetJavaLangReflectArtMethod();
+  return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
 }
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index c798180..c6472c6 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -40,7 +40,9 @@
 Class* Class::java_lang_Class_ = nullptr;
 
 void Class::SetClassClass(Class* java_lang_Class) {
-  CHECK(java_lang_Class_ == nullptr) << java_lang_Class_ << " " << java_lang_Class;
+  CHECK(java_lang_Class_ == nullptr)
+      << ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(&java_lang_Class_)
+      << " " << java_lang_Class;
   CHECK(java_lang_Class != nullptr);
   java_lang_Class_ = java_lang_Class;
 }
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index c83f411..e735c45 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -24,6 +24,7 @@
 #include "object.h"
 #include "object_callbacks.h"
 #include "primitive.h"
+#include "read_barrier.h"
 
 /*
  * A magic value for refOffsets. Ignore the bits and walk the super
@@ -376,8 +377,10 @@
 
   bool IsThrowableClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsArtFieldClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsArtMethodClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static MemberOffset ComponentTypeOffset() {
@@ -845,13 +848,14 @@
     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx);
   }
 
-  static Class* GetJavaLangClass() {
+  static Class* GetJavaLangClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(java_lang_Class_ != NULL);
-    return java_lang_Class_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(
+        &java_lang_Class_);
   }
 
   // Can't call this SetClass or else gets called instead of Object::SetClass in places.
-  static void SetClassClass(Class* java_lang_Class);
+  static void SetClassClass(Class* java_lang_Class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static void ResetClass();
   static void VisitRoots(RootCallback* callback, void* arg)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 15ecd3c..62c1162 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -218,7 +218,8 @@
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsArtField() {
-  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsArtFieldClass();
+  return GetClass<kVerifyFlags, kReadBarrierOption>()->
+      template IsArtFieldClass<kReadBarrierOption>();
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -229,7 +230,8 @@
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsArtMethod() {
-  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsArtMethodClass();
+  return GetClass<kVerifyFlags, kReadBarrierOption>()->
+      template IsArtMethodClass<kReadBarrierOption>();
 }
 
 template<VerifyObjectFlags kVerifyFlags>
diff --git a/runtime/mirror/stack_trace_element.h b/runtime/mirror/stack_trace_element.h
index e094e8b..abecbc5 100644
--- a/runtime/mirror/stack_trace_element.h
+++ b/runtime/mirror/stack_trace_element.h
@@ -19,6 +19,7 @@
 
 #include "object.h"
 #include "object_callbacks.h"
+#include "read_barrier.h"
 
 namespace art {
 
@@ -55,9 +56,10 @@
   static void ResetClass();
   static void VisitRoots(RootCallback* callback, void* arg)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static Class* GetStackTraceElement() {
+  static Class* GetStackTraceElement() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(java_lang_StackTraceElement_ != NULL);
-    return java_lang_StackTraceElement_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(
+        &java_lang_StackTraceElement_);
   }
 
  private:
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 6c3015f..b8acede 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -21,6 +21,7 @@
 
 #include "class.h"
 #include "object_callbacks.h"
+#include "read_barrier.h"
 
 namespace art {
 
@@ -102,9 +103,10 @@
 
   int32_t CompareTo(String* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  static Class* GetJavaLangString() {
+  static Class* GetJavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(java_lang_String_ != NULL);
-    return java_lang_String_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(
+        &java_lang_String_);
   }
 
   static void SetClass(Class* java_lang_String);
diff --git a/runtime/mirror/throwable.h b/runtime/mirror/throwable.h
index c4127e0..cf54ad6 100644
--- a/runtime/mirror/throwable.h
+++ b/runtime/mirror/throwable.h
@@ -19,6 +19,7 @@
 
 #include "object.h"
 #include "object_callbacks.h"
+#include "read_barrier.h"
 #include "string.h"
 
 namespace art {
@@ -45,9 +46,10 @@
   void SetStackState(Object* state) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   bool IsCheckedException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  static Class* GetJavaLangThrowable() {
+  static Class* GetJavaLangThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     DCHECK(java_lang_Throwable_ != NULL);
-    return java_lang_Throwable_;
+    return ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(
+        &java_lang_Throwable_);
   }
 
   static void SetClass(Class* java_lang_Throwable);