Move most mirror:: args to ObjPtr

Fixed possible moving GC bugs in ClinitImageUpdate class.

Bug: 31113334

Test: test-art-host
Change-Id: I0bf6578553d58b944aaa17665f1350bdf5ed15ec
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index d18781a..3789081 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -150,8 +150,11 @@
 };
 
 template <bool kIsInstrumented, bool kFillUsable>
-inline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count,
-                           size_t component_size_shift, gc::AllocatorType allocator_type) {
+inline Array* Array::Alloc(Thread* self,
+                           ObjPtr<Class> array_class,
+                           int32_t component_count,
+                           size_t component_size_shift,
+                           gc::AllocatorType allocator_type) {
   DCHECK(allocator_type != gc::kAllocatorTypeLOS);
   DCHECK(array_class != nullptr);
   DCHECK(array_class->IsArrayClass());
@@ -204,7 +207,9 @@
 
 template<typename T>
 inline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
-  Array* raw_array = Array::Alloc<true>(self, GetArrayClass(), length,
+  Array* raw_array = Array::Alloc<true>(self,
+                                        GetArrayClass(),
+                                        length,
                                         ComponentSizeShiftWidth(sizeof(T)),
                                         Runtime::Current()->GetHeap()->GetCurrentAllocator());
   return down_cast<PrimitiveArray<T>*>(raw_array);
@@ -275,7 +280,9 @@
 }
 
 template<class T>
-inline void PrimitiveArray<T>::Memmove(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos,
+inline void PrimitiveArray<T>::Memmove(int32_t dst_pos,
+                                       ObjPtr<PrimitiveArray<T>> src,
+                                       int32_t src_pos,
                                        int32_t count) {
   if (UNLIKELY(count == 0)) {
     return;
@@ -335,7 +342,9 @@
 }
 
 template<class T>
-inline void PrimitiveArray<T>::Memcpy(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos,
+inline void PrimitiveArray<T>::Memcpy(int32_t dst_pos,
+                                      ObjPtr<PrimitiveArray<T>> src,
+                                      int32_t src_pos,
                                       int32_t count) {
   if (UNLIKELY(count == 0)) {
     return;
@@ -415,6 +424,13 @@
   }
 }
 
+template<typename T>
+inline void PrimitiveArray<T>::SetArrayClass(ObjPtr<Class> array_class) {
+  CHECK(array_class_.IsNull());
+  CHECK(array_class != nullptr);
+  array_class_ = GcRoot<Class>(array_class);
+}
+
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 04d02f7..994e9b2 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -39,13 +39,19 @@
   // least component_count size, however, if there's usable space at the end of the allocation the
   // array will fill it.
   template <bool kIsInstrumented, bool kFillUsable = false>
-  ALWAYS_INLINE static Array* Alloc(Thread* self, Class* array_class, int32_t component_count,
-                                    size_t component_size_shift, gc::AllocatorType allocator_type)
-      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
+  ALWAYS_INLINE static Array* Alloc(Thread* self,
+                                    ObjPtr<Class> array_class,
+                                    int32_t component_count,
+                                    size_t component_size_shift,
+                                    gc::AllocatorType allocator_type)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Roles::uninterruptible_);
 
-  static Array* CreateMultiArray(Thread* self, Handle<Class> element_class,
+  static Array* CreateMultiArray(Thread* self,
+                                 Handle<Class> element_class,
                                  Handle<IntArray> dimensions)
-      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Roles::uninterruptible_);
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
@@ -147,7 +153,7 @@
    * smaller than element size copies). Arguments are assumed to be within the bounds of the array
    * and the arrays non-null.
    */
-  void Memmove(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos, int32_t count)
+  void Memmove(int32_t dst_pos, ObjPtr<PrimitiveArray<T>> src, int32_t src_pos, int32_t count)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   /*
@@ -155,14 +161,10 @@
    * smaller than element size copies). Arguments are assumed to be within the bounds of the array
    * and the arrays non-null.
    */
-  void Memcpy(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos, int32_t count)
+  void Memcpy(int32_t dst_pos, ObjPtr<PrimitiveArray<T>> src, int32_t src_pos, int32_t count)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static void SetArrayClass(Class* array_class) {
-    CHECK(array_class_.IsNull());
-    CHECK(array_class != nullptr);
-    array_class_ = GcRoot<Class>(array_class);
-  }
+  static void SetArrayClass(ObjPtr<Class> array_class);
 
   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   static Class* GetArrayClass() REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/runtime/mirror/class_loader-inl.h b/runtime/mirror/class_loader-inl.h
index cc910b0..f5ecdae 100644
--- a/runtime/mirror/class_loader-inl.h
+++ b/runtime/mirror/class_loader-inl.h
@@ -21,6 +21,7 @@
 
 #include "base/mutex-inl.h"
 #include "class_table-inl.h"
+#include "obj_ptr-inl.h"
 
 namespace art {
 namespace mirror {
@@ -29,7 +30,7 @@
           VerifyObjectFlags kVerifyFlags,
           ReadBarrierOption kReadBarrierOption,
           typename Visitor>
-inline void ClassLoader::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
+inline void ClassLoader::VisitReferences(ObjPtr<mirror::Class> klass, const Visitor& visitor) {
   // Visit instance fields first.
   VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
   if (kVisitClasses) {
diff --git a/runtime/mirror/class_loader.h b/runtime/mirror/class_loader.h
index 407678a..a62a460 100644
--- a/runtime/mirror/class_loader.h
+++ b/runtime/mirror/class_loader.h
@@ -67,7 +67,7 @@
             VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
             ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
             typename Visitor>
-  void VisitReferences(mirror::Class* klass, const Visitor& visitor)
+  void VisitReferences(ObjPtr<Class> klass, const Visitor& visitor)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::classlinker_classes_lock_);
 
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index b388f65..13d0108 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -27,6 +27,7 @@
 #include "mirror/class.h"
 #include "mirror/method_type.h"
 #include "runtime.h"
+#include "obj_ptr.h"
 
 #include <atomic>
 
@@ -72,7 +73,7 @@
   return GetResolvedTypes()[type_idx].Read();
 }
 
-inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
+inline void DexCache::SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved) {
   DCHECK_LT(type_idx, NumResolvedTypes());  // NOTE: Unchecked, i.e. not throwing AIOOB.
   // TODO default transaction support.
   GetResolvedTypes()[type_idx] = GcRoot<Class>(resolved);
@@ -162,7 +163,7 @@
           VerifyObjectFlags kVerifyFlags,
           ReadBarrierOption kReadBarrierOption,
           typename Visitor>
-inline void DexCache::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
+inline void DexCache::VisitReferences(ObjPtr<Class> klass, const Visitor& visitor) {
   // Visit instance fields first.
   VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
   // Visit arrays after.
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 2fcabb5..bbe98c2 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -220,7 +220,8 @@
 
   Class* GetResolvedType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
 
-  void SetResolvedType(uint32_t type_idx, Class* resolved) REQUIRES_SHARED(Locks::mutator_lock_);
+  void SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved)
+      REQUIRES_SHARED(Locks::mutator_lock_);
 
   ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, PointerSize ptr_size)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -337,7 +338,7 @@
             VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
             ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
             typename Visitor>
-  void VisitReferences(mirror::Class* klass, const Visitor& visitor)
+  void VisitReferences(ObjPtr<mirror::Class> klass, const Visitor& visitor)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_);
 
   HeapReference<Object> dex_;
diff --git a/runtime/mirror/executable.cc b/runtime/mirror/executable.cc
index 33ebd81..17c16a2 100644
--- a/runtime/mirror/executable.cc
+++ b/runtime/mirror/executable.cc
@@ -32,14 +32,10 @@
   return true;
 }
 
-template bool Executable::CreateFromArtMethod<PointerSize::k32, false>(
-    ArtMethod* method);
-template bool Executable::CreateFromArtMethod<PointerSize::k32, true>(
-    ArtMethod* method);
-template bool Executable::CreateFromArtMethod<PointerSize::k64, false>(
-    ArtMethod* method);
-template bool Executable::CreateFromArtMethod<PointerSize::k64, true>(
-    ArtMethod* method);
+template bool Executable::CreateFromArtMethod<PointerSize::k32, false>(ArtMethod* method);
+template bool Executable::CreateFromArtMethod<PointerSize::k32, true>(ArtMethod* method);
+template bool Executable::CreateFromArtMethod<PointerSize::k64, false>(ArtMethod* method);
+template bool Executable::CreateFromArtMethod<PointerSize::k64, true>(ArtMethod* method);
 
 ArtMethod* Executable::GetArtMethod() {
   return reinterpret_cast<ArtMethod*>(GetField64(ArtMethodOffset()));
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index adc5107..c03f20a 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -79,10 +79,15 @@
 }
 
 template<bool kTransactionActive>
-void Field::SetDeclaringClass(ObjPtr<mirror::Class> c) {
+inline void Field::SetDeclaringClass(ObjPtr<mirror::Class> c) {
   SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), c);
 }
 
+template<bool kTransactionActive>
+inline void Field::SetType(ObjPtr<mirror::Class> type) {
+  SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, type_), type);
+}
+
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index 65f6b16..f6b6489 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -27,7 +27,7 @@
 GcRoot<Class> Field::static_class_;
 GcRoot<Class> Field::array_class_;
 
-void Field::SetClass(Class* klass) {
+void Field::SetClass(ObjPtr<Class> klass) {
   CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
   CHECK(klass != nullptr);
   static_class_ = GcRoot<Class>(klass);
@@ -38,7 +38,7 @@
   static_class_ = GcRoot<Class>(nullptr);
 }
 
-void Field::SetArrayClass(Class* klass) {
+void Field::SetArrayClass(ObjPtr<Class> klass) {
   CHECK(array_class_.IsNull()) << array_class_.Read() << " " << klass;
   CHECK(klass != nullptr);
   array_class_ = GcRoot<Class>(klass);
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index c5357c9..222d709 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -83,10 +83,10 @@
     return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_));
   }
 
-  static void SetClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
+  static void SetClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
   static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static void SetArrayClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
+  static void SetArrayClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
   static void ResetArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
 
   static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -113,9 +113,7 @@
   void SetDeclaringClass(ObjPtr<mirror::Class> c) REQUIRES_SHARED(Locks::mutator_lock_);
 
   template<bool kTransactionActive>
-  void SetType(mirror::Class* type) REQUIRES_SHARED(Locks::mutator_lock_) {
-    SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, type_), type);
-  }
+  void SetType(ObjPtr<mirror::Class> type) REQUIRES_SHARED(Locks::mutator_lock_);
 
   template<bool kTransactionActive>
   void SetAccessFlags(uint32_t flags) REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/runtime/mirror/iftable-inl.h b/runtime/mirror/iftable-inl.h
index b465d07..d6191c2 100644
--- a/runtime/mirror/iftable-inl.h
+++ b/runtime/mirror/iftable-inl.h
@@ -18,11 +18,12 @@
 #define ART_RUNTIME_MIRROR_IFTABLE_INL_H_
 
 #include "iftable.h"
+#include "obj_ptr-inl.h"
 
 namespace art {
 namespace mirror {
 
-inline void IfTable::SetInterface(int32_t i, Class* interface) {
+inline void IfTable::SetInterface(int32_t i, ObjPtr<Class> interface) {
   DCHECK(interface != nullptr);
   DCHECK(interface->IsInterface());
   const size_t idx = i * kMax + kInterface;
@@ -30,6 +31,13 @@
   SetWithoutChecks<false>(idx, interface);
 }
 
+inline void IfTable::SetMethodArray(int32_t i, ObjPtr<PointerArray> arr) {
+  DCHECK(arr != nullptr);
+  auto idx = i * kMax + kMethodArray;
+  DCHECK(Get(idx) == nullptr);
+  Set<false>(idx, arr);
+}
+
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/iftable.h b/runtime/mirror/iftable.h
index a1a2f98..296c163 100644
--- a/runtime/mirror/iftable.h
+++ b/runtime/mirror/iftable.h
@@ -31,7 +31,7 @@
     return interface;
   }
 
-  ALWAYS_INLINE void SetInterface(int32_t i, Class* interface)
+  ALWAYS_INLINE void SetInterface(int32_t i, ObjPtr<Class> interface)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
@@ -51,12 +51,7 @@
     return method_array == nullptr ? 0u : method_array->GetLength();
   }
 
-  void SetMethodArray(int32_t i, PointerArray* arr) REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK(arr != nullptr);
-    auto idx = i * kMax + kMethodArray;
-    DCHECK(Get(idx) == nullptr);
-    Set<false>(idx, arr);
-  }
+  void SetMethodArray(int32_t i, ObjPtr<PointerArray> arr) REQUIRES_SHARED(Locks::mutator_lock_);
 
   size_t Count() REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetLength() / kMax;
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 3e7bca7..f555c80 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -392,8 +392,8 @@
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsIntArray() {
   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
-  mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
-  mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
+  ObjPtr<Class> klass = GetClass<kVerifyFlags, kReadBarrierOption>();
+  ObjPtr<Class> component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
   return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>();
 }
 
@@ -406,8 +406,8 @@
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsLongArray() {
   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
-  mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
-  mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
+  ObjPtr<Class> klass = GetClass<kVerifyFlags, kReadBarrierOption>();
+  ObjPtr<Class> component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
   return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>();
 }
 
@@ -1117,7 +1117,7 @@
     // There is no reference offset bitmap. In the non-static case, walk up the class
     // inheritance hierarchy and find reference offsets the hard way. In the static case, just
     // consider this class.
-    for (mirror::Class* klass = kIsStatic
+    for (ObjPtr<Class> klass = kIsStatic
             ? AsClass<kVerifyFlags, kReadBarrierOption>()
             : GetClass<kVerifyFlags, kReadBarrierOption>();
         klass != nullptr;
@@ -1146,13 +1146,13 @@
 }
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
-inline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
+inline void Object::VisitInstanceFieldsReferences(ObjPtr<Class> klass, const Visitor& visitor) {
   VisitFieldsReferences<false, kVerifyFlags, kReadBarrierOption>(
       klass->GetReferenceInstanceOffsets<kVerifyFlags>(), visitor);
 }
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
-inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
+inline void Object::VisitStaticFieldsReferences(ObjPtr<Class> klass, const Visitor& visitor) {
   DCHECK(!klass->IsTemp());
   klass->VisitFieldsReferences<true, kVerifyFlags, kReadBarrierOption>(0, visitor);
 }
@@ -1186,7 +1186,7 @@
           typename JavaLangRefVisitor>
 inline void Object::VisitReferences(const Visitor& visitor,
                                     const JavaLangRefVisitor& ref_visitor) {
-  mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
+  ObjPtr<Class> klass = GetClass<kVerifyFlags, kReadBarrierOption>();
   visitor(this, ClassOffset(), false);
   const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>();
   if (LIKELY(class_flags == kClassFlagNormal)) {
@@ -1201,7 +1201,7 @@
       DCHECK(!klass->IsStringClass());
       if (class_flags == kClassFlagClass) {
         DCHECK((klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
-        mirror::Class* as_klass = AsClass<kVerifyNone, kReadBarrierOption>();
+        ObjPtr<Class> as_klass = AsClass<kVerifyNone, kReadBarrierOption>();
         as_klass->VisitReferences<kVisitNativeRoots, kVerifyFlags, kReadBarrierOption>(klass,
                                                                                        visitor);
       } else if (class_flags == kClassFlagObjectArray) {
@@ -1228,7 +1228,7 @@
       // actual string instances.
       if (!klass->IsStringClass()) {
         size_t total_reference_instance_fields = 0;
-        mirror::Class* super_class = klass;
+        ObjPtr<Class> super_class = klass;
         do {
           total_reference_instance_fields += super_class->NumReferenceInstanceFields();
           super_class = super_class->GetSuperClass<kVerifyFlags, kReadBarrierOption>();
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index daee727..7e92c53 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -49,7 +49,7 @@
   void operator()(ObjPtr<Object> obj, MemberOffset offset, bool /* is_static */) const
       ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
     // GetFieldObject() contains a RB.
-    Object* ref = obj->GetFieldObject<Object>(offset);
+    ObjPtr<Object> ref = obj->GetFieldObject<Object>(offset);
     // No WB here as a large object space does not have a card table
     // coverage. Instead, cards will be marked separately.
     dest_obj_->SetFieldObjectWithoutWriteBarrier<false, false>(offset, ref);
@@ -118,7 +118,7 @@
   }
   gc::Heap* heap = Runtime::Current()->GetHeap();
   // Perform write barriers on copied object references.
-  Class* c = src->GetClass();
+  ObjPtr<Class> c = src->GetClass();
   if (c->IsArrayClass()) {
     if (!c->GetComponentType()->IsPrimitive()) {
       ObjectArray<Object>* array = dest->AsObjectArray<Object>();
@@ -182,8 +182,8 @@
   hash_code_seed.StoreRelaxed(new_seed);
 }
 
-int32_t Object::IdentityHashCode() const {
-  mirror::Object* current_this = const_cast<mirror::Object*>(this);
+int32_t Object::IdentityHashCode() {
+  ObjPtr<Object> current_this = this;  // The this pointer may get invalidated by thread suspension.
   while (true) {
     LockWord lw = current_this->GetLockWord(false);
     switch (lw.GetState()) {
@@ -192,7 +192,7 @@
         // loop iteration.
         LockWord hash_word = LockWord::FromHashCode(GenerateIdentityHashCode(), lw.GCState());
         DCHECK_EQ(hash_word.GetState(), LockWord::kHashCode);
-        if (const_cast<Object*>(this)->CasLockWordWeakRelaxed(lw, hash_word)) {
+        if (current_this->CasLockWordWeakRelaxed(lw, hash_word)) {
           return hash_word.GetHashCode();
         }
         break;
@@ -227,13 +227,13 @@
 }
 
 void Object::CheckFieldAssignmentImpl(MemberOffset field_offset, ObjPtr<Object> new_value) {
-  Class* c = GetClass();
+  ObjPtr<Class> c = GetClass();
   Runtime* runtime = Runtime::Current();
   if (runtime->GetClassLinker() == nullptr || !runtime->IsStarted() ||
       !runtime->GetHeap()->IsObjectValidationEnabled() || !c->IsResolved()) {
     return;
   }
-  for (Class* cur = c; cur != nullptr; cur = cur->GetSuperClass()) {
+  for (ObjPtr<Class> cur = c; cur != nullptr; cur = cur->GetSuperClass()) {
     for (ArtField& field : cur->GetIFields()) {
       StackHandleScope<1> hs(Thread::Current());
       Handle<Object> h_object(hs.NewHandle(new_value));
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 84aa96c..13f4028 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -130,9 +130,10 @@
   Object* Clone(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
-  int32_t IdentityHashCode() const
+  int32_t IdentityHashCode()
       REQUIRES_SHARED(Locks::mutator_lock_)
-      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
+      REQUIRES(!Locks::thread_list_lock_,
+               !Locks::thread_suspend_count_lock_);
 
   static MemberOffset MonitorOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Object, monitor_);
@@ -578,12 +579,12 @@
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
            ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
            typename Visitor>
-  void VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) HOT_ATTR
+  void VisitInstanceFieldsReferences(ObjPtr<mirror::Class> klass, const Visitor& visitor) HOT_ATTR
       REQUIRES_SHARED(Locks::mutator_lock_);
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
            ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
            typename Visitor>
-  void VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) HOT_ATTR
+  void VisitStaticFieldsReferences(ObjPtr<mirror::Class> klass, const Visitor& visitor) HOT_ATTR
       REQUIRES_SHARED(Locks::mutator_lock_);
 
  private:
diff --git a/runtime/mirror/stack_trace_element.cc b/runtime/mirror/stack_trace_element.cc
index e2050cc..c00cf91 100644
--- a/runtime/mirror/stack_trace_element.cc
+++ b/runtime/mirror/stack_trace_element.cc
@@ -28,7 +28,7 @@
 
 GcRoot<Class> StackTraceElement::java_lang_StackTraceElement_;
 
-void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {
+void StackTraceElement::SetClass(ObjPtr<Class> java_lang_StackTraceElement) {
   CHECK(java_lang_StackTraceElement_.IsNull());
   CHECK(java_lang_StackTraceElement != nullptr);
   java_lang_StackTraceElement_ = GcRoot<Class>(java_lang_StackTraceElement);
@@ -39,30 +39,34 @@
   java_lang_StackTraceElement_ = GcRoot<Class>(nullptr);
 }
 
-StackTraceElement* StackTraceElement::Alloc(Thread* self, Handle<String> declaring_class,
-                                            Handle<String> method_name, Handle<String> file_name,
+StackTraceElement* StackTraceElement::Alloc(Thread* self,
+                                            Handle<String> declaring_class,
+                                            Handle<String> method_name,
+                                            Handle<String> file_name,
                                             int32_t line_number) {
   ObjPtr<StackTraceElement> trace =
       ObjPtr<StackTraceElement>::DownCast(GetStackTraceElement()->AllocObject(self));
   if (LIKELY(trace != nullptr)) {
     if (Runtime::Current()->IsActiveTransaction()) {
-      trace->Init<true>(declaring_class, method_name, file_name, line_number);
+      trace->Init<true>(declaring_class.Get(), method_name.Get(), file_name.Get(), line_number);
     } else {
-      trace->Init<false>(declaring_class, method_name, file_name, line_number);
+      trace->Init<false>(declaring_class.Get(), method_name.Get(), file_name.Get(), line_number);
     }
   }
   return trace.Ptr();
 }
 
 template<bool kTransactionActive>
-void StackTraceElement::Init(Handle<String> declaring_class, Handle<String> method_name,
-                             Handle<String> file_name, int32_t line_number) {
+void StackTraceElement::Init(ObjPtr<String> declaring_class,
+                             ObjPtr<String> method_name,
+                             ObjPtr<String> file_name,
+                             int32_t line_number) {
   SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_),
-                                     declaring_class.Get());
+                                     declaring_class);
   SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_),
-                                     method_name.Get());
+                                     method_name);
   SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_),
-                                     file_name.Get());
+                                     file_name);
   SetField32<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_),
                                  line_number);
 }
diff --git a/runtime/mirror/stack_trace_element.h b/runtime/mirror/stack_trace_element.h
index 4b3d9d0..d32d8dc 100644
--- a/runtime/mirror/stack_trace_element.h
+++ b/runtime/mirror/stack_trace_element.h
@@ -47,12 +47,14 @@
     return GetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_));
   }
 
-  static StackTraceElement* Alloc(Thread* self, Handle<String> declaring_class,
-                                  Handle<String> method_name, Handle<String> file_name,
+  static StackTraceElement* Alloc(Thread* self,
+                                  Handle<String> declaring_class,
+                                  Handle<String> method_name,
+                                  Handle<String> file_name,
                                   int32_t line_number)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static void SetClass(Class* java_lang_StackTraceElement);
+  static void SetClass(ObjPtr<Class> java_lang_StackTraceElement);
   static void ResetClass();
   static void VisitRoots(RootVisitor* visitor)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -69,7 +71,9 @@
   int32_t line_number_;
 
   template<bool kTransactionActive>
-  void Init(Handle<String> declaring_class, Handle<String> method_name, Handle<String> file_name,
+  void Init(ObjPtr<String> declaring_class,
+            ObjPtr<String> method_name,
+            ObjPtr<String> file_name,
             int32_t line_number)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc
index 46caa4d..ed1103f 100644
--- a/runtime/mirror/string.cc
+++ b/runtime/mirror/string.cc
@@ -48,7 +48,7 @@
   }
 }
 
-void String::SetClass(Class* java_lang_String) {
+void String::SetClass(ObjPtr<Class> java_lang_String) {
   CHECK(java_lang_String_.IsNull());
   CHECK(java_lang_String != nullptr);
   CHECK(java_lang_String->IsStringClass());
@@ -93,12 +93,13 @@
   int32_t length = string->GetLength();
   int32_t length2 = string2->GetLength();
   gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
-  const bool compressible = kUseStringCompression && (string->IsCompressed() && string2->IsCompressed());
-  const int32_t length_with_flag = (compressible) ? String::GetFlaggedCount(length + length2)
-                                                  : (length + length2);
+  const bool compressible = kUseStringCompression &&
+      (string->IsCompressed() && string2->IsCompressed());
+  const int32_t length_with_flag = compressible ? String::GetFlaggedCount(length + length2)
+                                                : (length + length2);
 
   SetStringCountVisitor visitor(length_with_flag);
-  String* new_string = Alloc<true>(self, length_with_flag, allocator_type, visitor);
+  ObjPtr<String> new_string = Alloc<true>(self, length_with_flag, allocator_type, visitor);
   if (UNLIKELY(new_string == nullptr)) {
     return nullptr;
   }
@@ -123,7 +124,7 @@
       memcpy(new_value + length, string2->GetValue(), length2 * sizeof(uint16_t));
     }
   }
-  return new_string;
+  return new_string.Ptr();
 }
 
 String* String::AllocFromUtf16(Thread* self, int32_t utf16_length, const uint16_t* utf16_data_in) {
@@ -134,7 +135,7 @@
   int32_t length_with_flag = (compressible) ? String::GetFlaggedCount(utf16_length)
                                             : utf16_length;
   SetStringCountVisitor visitor(length_with_flag);
-  String* string = Alloc<true>(self, length_with_flag, allocator_type, visitor);
+  ObjPtr<String> string = Alloc<true>(self, length_with_flag, allocator_type, visitor);
   if (UNLIKELY(string == nullptr)) {
     return nullptr;
   }
@@ -146,7 +147,7 @@
     uint16_t* array = string->GetValue();
     memcpy(array, utf16_data_in, utf16_length * sizeof(uint16_t));
   }
-  return string;
+  return string.Ptr();
 }
 
 String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
@@ -156,18 +157,22 @@
   return AllocFromModifiedUtf8(self, char_count, utf, byte_count);
 }
 
-String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, const char* utf8_data_in) {
+String* String::AllocFromModifiedUtf8(Thread* self,
+                                      int32_t utf16_length,
+                                      const char* utf8_data_in) {
   return AllocFromModifiedUtf8(self, utf16_length, utf8_data_in, strlen(utf8_data_in));
 }
 
-String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
-                                      const char* utf8_data_in, int32_t utf8_length) {
+String* String::AllocFromModifiedUtf8(Thread* self,
+                                      int32_t utf16_length,
+                                      const char* utf8_data_in,
+                                      int32_t utf8_length) {
   gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
   const bool compressible = kUseStringCompression && (utf16_length == utf8_length);
   const int32_t utf16_length_with_flag = (compressible) ? String::GetFlaggedCount(utf16_length)
                                                         : utf16_length;
   SetStringCountVisitor visitor(utf16_length_with_flag);
-  String* string = Alloc<true>(self, utf16_length_with_flag, allocator_type, visitor);
+  ObjPtr<String> string = Alloc<true>(self, utf16_length_with_flag, allocator_type, visitor);
   if (UNLIKELY(string == nullptr)) {
     return nullptr;
   }
@@ -177,10 +182,10 @@
     uint16_t* utf16_data_out = string->GetValue();
     ConvertModifiedUtf8ToUtf16(utf16_data_out, utf16_length, utf8_data_in, utf8_length);
   }
-  return string;
+  return string.Ptr();
 }
 
-bool String::Equals(String* that) {
+bool String::Equals(ObjPtr<String> that) {
   if (this == that) {
     // Quick reference equality test
     return true;
@@ -281,9 +286,9 @@
   return result;
 }
 
-int32_t String::CompareTo(String* rhs) {
+int32_t String::CompareTo(ObjPtr<String> rhs) {
   // Quick test for comparison of a string with itself.
-  String* lhs = this;
+  ObjPtr<String> lhs = this;
   if (lhs == rhs) {
     return 0;
   }
@@ -298,7 +303,9 @@
   int32_t countDiff = lhsCount - rhsCount;
   int32_t minCount = (countDiff < 0) ? lhsCount : rhsCount;
   if (lhs->IsCompressed() && rhs->IsCompressed()) {
-    int32_t comparison = memcmp(lhs->GetValueCompressed(), rhs->GetValueCompressed(), minCount * sizeof(uint8_t));
+    int32_t comparison = memcmp(lhs->GetValueCompressed(),
+                                rhs->GetValueCompressed(),
+                                minCount * sizeof(uint8_t));
     if (comparison != 0) {
       return comparison;
     }
@@ -326,7 +333,7 @@
 CharArray* String::ToCharArray(Thread* self) {
   StackHandleScope<1> hs(self);
   Handle<String> string(hs.NewHandle(this));
-  CharArray* result = CharArray::Alloc(self, GetLength());
+  ObjPtr<CharArray> result = CharArray::Alloc(self, GetLength());
   if (result != nullptr) {
     if (string->IsCompressed()) {
       int32_t length = string->GetLength();
@@ -339,7 +346,7 @@
   } else {
     self->AssertPendingOOMException();
   }
-  return result;
+  return result.Ptr();
 }
 
 void String::GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index) {
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index a18692f..cfb1153 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -146,7 +146,7 @@
   bool Equals(const StringPiece& modified_utf8)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  bool Equals(String* that) REQUIRES_SHARED(Locks::mutator_lock_);
+  bool Equals(ObjPtr<String> that) REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Compare UTF-16 code point values not in a locale-sensitive manner
   int Compare(int32_t utf16_length, const char* utf8_data_in);
@@ -165,7 +165,7 @@
   int32_t FastIndexOf(MemoryType* chars, int32_t ch, int32_t start)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  int32_t CompareTo(String* other) REQUIRES_SHARED(Locks::mutator_lock_);
+  int32_t CompareTo(ObjPtr<String> other) REQUIRES_SHARED(Locks::mutator_lock_);
 
   CharArray* ToCharArray(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
@@ -200,7 +200,7 @@
     return java_lang_String_.Read();
   }
 
-  static void SetClass(Class* java_lang_String) REQUIRES_SHARED(Locks::mutator_lock_);
+  static void SetClass(ObjPtr<Class> java_lang_String) REQUIRES_SHARED(Locks::mutator_lock_);
   static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
   static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
 
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index 8f3ed84..7aff3de 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -33,7 +33,7 @@
 
 GcRoot<Class> Throwable::java_lang_Throwable_;
 
-void Throwable::SetDetailMessage(String* new_detail_message) {
+void Throwable::SetDetailMessage(ObjPtr<String> new_detail_message) {
   if (Runtime::Current()->IsActiveTransaction()) {
     SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_), new_detail_message);
   } else {
@@ -42,7 +42,7 @@
   }
 }
 
-void Throwable::SetCause(Throwable* cause) {
+void Throwable::SetCause(ObjPtr<Throwable> cause) {
   CHECK(cause != nullptr);
   CHECK(cause != this);
   Throwable* current_cause = GetFieldObject<Throwable>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_));
@@ -54,7 +54,7 @@
   }
 }
 
-void Throwable::SetStackState(Object* state) REQUIRES_SHARED(Locks::mutator_lock_) {
+void Throwable::SetStackState(ObjPtr<Object> state) REQUIRES_SHARED(Locks::mutator_lock_) {
   CHECK(state != nullptr);
   if (Runtime::Current()->IsActiveTransaction()) {
     SetFieldObjectVolatile<true>(OFFSET_OF_OBJECT_MEMBER(Throwable, backtrace_), state);
@@ -71,11 +71,11 @@
 }
 
 int32_t Throwable::GetStackDepth() {
-  Object* stack_state = GetStackState();
+  ObjPtr<Object> stack_state = GetStackState();
   if (stack_state == nullptr || !stack_state->IsObjectArray()) {
     return -1;
   }
-  mirror::ObjectArray<mirror::Object>* const trace = stack_state->AsObjectArray<mirror::Object>();
+  ObjPtr<mirror::ObjectArray<Object>> const trace = stack_state->AsObjectArray<Object>();
   const int32_t array_len = trace->GetLength();
   DCHECK_GT(array_len, 0);
   // See method BuildInternalStackTraceVisitor::Init for the format.
@@ -85,22 +85,21 @@
 std::string Throwable::Dump() {
   std::string result(PrettyTypeOf(this));
   result += ": ";
-  String* msg = GetDetailMessage();
+  ObjPtr<String> msg = GetDetailMessage();
   if (msg != nullptr) {
     result += msg->ToModifiedUtf8();
   }
   result += "\n";
-  Object* stack_state = GetStackState();
+  ObjPtr<Object> stack_state = GetStackState();
   // check stack state isn't missing or corrupt
   if (stack_state != nullptr && stack_state->IsObjectArray()) {
-    mirror::ObjectArray<mirror::Object>* object_array =
-        stack_state->AsObjectArray<mirror::Object>();
+    ObjPtr<ObjectArray<Object>> object_array = stack_state->AsObjectArray<Object>();
     // Decode the internal stack trace into the depth and method trace
     // See method BuildInternalStackTraceVisitor::Init for the format.
     DCHECK_GT(object_array->GetLength(), 0);
-    mirror::Object* methods_and_dex_pcs = object_array->Get(0);
+    ObjPtr<Object> methods_and_dex_pcs = object_array->Get(0);
     DCHECK(methods_and_dex_pcs->IsIntArray() || methods_and_dex_pcs->IsLongArray());
-    mirror::PointerArray* method_trace = down_cast<mirror::PointerArray*>(methods_and_dex_pcs);
+    ObjPtr<PointerArray> method_trace = ObjPtr<PointerArray>::DownCast(methods_and_dex_pcs);
     const int32_t array_len = method_trace->GetLength();
     CHECK_EQ(array_len % 2, 0);
     const auto depth = array_len / 2;
@@ -118,11 +117,12 @@
       }
     }
   } else {
-    Object* stack_trace = GetStackTrace();
+    ObjPtr<Object> stack_trace = GetStackTrace();
     if (stack_trace != nullptr && stack_trace->IsObjectArray()) {
       CHECK_EQ(stack_trace->GetClass()->GetComponentType(),
                StackTraceElement::GetStackTraceElement());
-      auto* ste_array = down_cast<ObjectArray<StackTraceElement>*>(stack_trace);
+      ObjPtr<ObjectArray<StackTraceElement>> ste_array =
+          ObjPtr<ObjectArray<StackTraceElement>>::DownCast(stack_trace);
       if (ste_array->GetLength() == 0) {
         result += "(Throwable with empty stack trace)";
       } else {
@@ -142,7 +142,7 @@
       result += "(Throwable with no stack trace)";
     }
   }
-  Throwable* cause = GetFieldObject<Throwable>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_));
+  ObjPtr<Throwable> cause = GetFieldObject<Throwable>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_));
   if (cause != nullptr && cause != this) {  // Constructor makes cause == this by default.
     result += "Caused by: ";
     result += cause->Dump();
@@ -150,7 +150,7 @@
   return result;
 }
 
-void Throwable::SetClass(Class* java_lang_Throwable) {
+void Throwable::SetClass(ObjPtr<Class> java_lang_Throwable) {
   CHECK(java_lang_Throwable_.IsNull());
   CHECK(java_lang_Throwable != nullptr);
   java_lang_Throwable_ = GcRoot<Class>(java_lang_Throwable);
diff --git a/runtime/mirror/throwable.h b/runtime/mirror/throwable.h
index 76824cb..0a4ab6f 100644
--- a/runtime/mirror/throwable.h
+++ b/runtime/mirror/throwable.h
@@ -31,7 +31,7 @@
 // C++ mirror of java.lang.Throwable
 class MANAGED Throwable : public Object {
  public:
-  void SetDetailMessage(String* new_detail_message) REQUIRES_SHARED(Locks::mutator_lock_);
+  void SetDetailMessage(ObjPtr<String> new_detail_message) REQUIRES_SHARED(Locks::mutator_lock_);
 
   String* GetDetailMessage() REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_));
@@ -42,8 +42,8 @@
   // This is a runtime version of initCause, you shouldn't use it if initCause may have been
   // overridden. Also it asserts rather than throwing exceptions. Currently this is only used
   // in cases like the verifier where the checks cannot fail and initCause isn't overridden.
-  void SetCause(Throwable* cause) REQUIRES_SHARED(Locks::mutator_lock_);
-  void SetStackState(Object* state) REQUIRES_SHARED(Locks::mutator_lock_);
+  void SetCause(ObjPtr<Throwable> cause) REQUIRES_SHARED(Locks::mutator_lock_);
+  void SetStackState(ObjPtr<Object> state) REQUIRES_SHARED(Locks::mutator_lock_);
   bool IsCheckedException() REQUIRES_SHARED(Locks::mutator_lock_);
 
   static Class* GetJavaLangThrowable() REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -53,7 +53,7 @@
 
   int32_t GetStackDepth() REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static void SetClass(Class* java_lang_Throwable);
+  static void SetClass(ObjPtr<Class> java_lang_Throwable);
   static void ResetClass();
   static void VisitRoots(RootVisitor* visitor)
       REQUIRES_SHARED(Locks::mutator_lock_);