ObjPtr<>-ify RegTypeCache, fix 1 stale reference use.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 31113334
Change-Id: If8674fc712d9bc4d7d2fef1d154192b31b153627
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 287e3d6..cc71dc5 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3366,7 +3366,7 @@
           }
           break;
         }
-        auto* klass = declaring_class.GetClass();
+        ObjPtr<mirror::Class> klass = declaring_class.GetClass();
         for (uint32_t i = 0, num_fields = klass->NumInstanceFields(); i < num_fields; ++i) {
           if (klass->GetInstanceField(i)->IsFinal()) {
             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for "
@@ -3667,10 +3667,10 @@
       UninstantiableError(descriptor);
       precise = false;
     }
-    result = reg_types_.FindClass(klass.Ptr(), precise);
+    result = reg_types_.FindClass(klass, precise);
     if (result == nullptr) {
       const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
-      result = reg_types_.InsertClass(descriptor, klass.Ptr(), precise);
+      result = reg_types_.InsertClass(descriptor, klass, precise);
     }
   } else {
     const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
@@ -4943,7 +4943,7 @@
     const char* descriptor
         = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
     if (method_being_verified_ != nullptr) {
-      mirror::Class* klass = method_being_verified_->GetDeclaringClass();
+      ObjPtr<mirror::Class> klass = method_being_verified_->GetDeclaringClass();
       declaring_class_ = &FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes());
     } else {
       declaring_class_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
@@ -5045,7 +5045,7 @@
 }
 
 const RegType& MethodVerifier::FromClass(const char* descriptor,
-                                         mirror::Class* klass,
+                                         ObjPtr<mirror::Class> klass,
                                          bool precise) {
   DCHECK(klass != nullptr);
   if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) {
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 531d3da..b2adc62 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -691,7 +691,7 @@
   // non-precise reference will be returned.
   // Note: we reuse NO_CLASS as this will throw an exception at runtime, when the failing class is
   //       actually touched.
-  const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise)
+  const RegType& FromClass(const char* descriptor, ObjPtr<mirror::Class> klass, bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   ALWAYS_INLINE bool FailOrAbort(bool condition, const char* error_msg, uint32_t work_insn_idx);
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index e7864a2..cbfbb40 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -54,17 +54,19 @@
 const IntegerType* IntegerType::instance_ = nullptr;
 const NullType* NullType::instance_ = nullptr;
 
-PrimitiveType::PrimitiveType(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
+PrimitiveType::PrimitiveType(ObjPtr<mirror::Class> klass,
+                             const StringPiece& descriptor,
+                             uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
   CHECK(klass != nullptr);
   CHECK(!descriptor.empty());
 }
 
-Cat1Type::Cat1Type(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
+Cat1Type::Cat1Type(ObjPtr<mirror::Class> klass, const StringPiece& descriptor, uint16_t cache_id)
     : PrimitiveType(klass, descriptor, cache_id) {
 }
 
-Cat2Type::Cat2Type(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
+Cat2Type::Cat2Type(ObjPtr<mirror::Class> klass, const StringPiece& descriptor, uint16_t cache_id)
     : PrimitiveType(klass, descriptor, cache_id) {
 }
 
@@ -129,7 +131,7 @@
   return "Integer";
 }
 
-const DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass,
+const DoubleHiType* DoubleHiType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                  const StringPiece& descriptor,
                                                  uint16_t cache_id) {
   CHECK(instance_ == nullptr);
@@ -144,7 +146,7 @@
   }
 }
 
-const DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass,
+const DoubleLoType* DoubleLoType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                  const StringPiece& descriptor,
                                                  uint16_t cache_id) {
   CHECK(instance_ == nullptr);
@@ -159,14 +161,16 @@
   }
 }
 
-const LongLoType* LongLoType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const LongLoType* LongLoType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                             const StringPiece& descriptor,
                                              uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new LongLoType(klass, descriptor, cache_id);
   return instance_;
 }
 
-const LongHiType* LongHiType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const LongHiType* LongHiType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                             const StringPiece& descriptor,
                                              uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new LongHiType(klass, descriptor, cache_id);
@@ -187,7 +191,8 @@
   }
 }
 
-const FloatType* FloatType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const FloatType* FloatType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                           const StringPiece& descriptor,
                                            uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new FloatType(klass, descriptor, cache_id);
@@ -201,7 +206,8 @@
   }
 }
 
-const CharType* CharType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const CharType* CharType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                         const StringPiece& descriptor,
                                          uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new CharType(klass, descriptor, cache_id);
@@ -215,7 +221,8 @@
   }
 }
 
-const ShortType* ShortType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const ShortType* ShortType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                           const StringPiece& descriptor,
                                            uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new ShortType(klass, descriptor, cache_id);
@@ -229,7 +236,8 @@
   }
 }
 
-const ByteType* ByteType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const ByteType* ByteType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                         const StringPiece& descriptor,
                                          uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new ByteType(klass, descriptor, cache_id);
@@ -243,7 +251,8 @@
   }
 }
 
-const IntegerType* IntegerType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
+const IntegerType* IntegerType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                               const StringPiece& descriptor,
                                                uint16_t cache_id) {
   CHECK(instance_ == nullptr);
   instance_ = new IntegerType(klass, descriptor, cache_id);
@@ -257,7 +266,7 @@
   }
 }
 
-const ConflictType* ConflictType::CreateInstance(mirror::Class* klass,
+const ConflictType* ConflictType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                  const StringPiece& descriptor,
                                                  uint16_t cache_id) {
   CHECK(instance_ == nullptr);
@@ -272,8 +281,9 @@
   }
 }
 
-const BooleanType* BooleanType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
-                                         uint16_t cache_id) {
+const BooleanType* BooleanType::CreateInstance(ObjPtr<mirror::Class> klass,
+                                               const StringPiece& descriptor,
+                                               uint16_t cache_id) {
   CHECK(BooleanType::instance_ == nullptr);
   instance_ = new BooleanType(klass, descriptor, cache_id);
   return BooleanType::instance_;
@@ -290,7 +300,7 @@
   return "Undefined";
 }
 
-const UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass,
+const UndefinedType* UndefinedType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                    const StringPiece& descriptor,
                                                    uint16_t cache_id) {
   CHECK(instance_ == nullptr);
@@ -305,7 +315,8 @@
   }
 }
 
-PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const StringPiece& descriptor,
+PreciseReferenceType::PreciseReferenceType(ObjPtr<mirror::Class> klass,
+                                           const StringPiece& descriptor,
                                            uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
   // Note: no check for IsInstantiable() here. We may produce this in case an InstantiationError
@@ -505,7 +516,7 @@
 
 const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
   if (!IsUnresolvedTypes()) {
-    mirror::Class* super_klass = GetClass()->GetSuperClass();
+    ObjPtr<mirror::Class> super_klass = GetClass()->GetSuperClass();
     if (super_klass != nullptr) {
       // A super class of a precise type isn't precise as a precise type indicates the register
       // holds exactly that type.
@@ -543,7 +554,7 @@
     DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
     return descriptor_[0] == '[';
   } else if (HasClass()) {
-    mirror::Class* type = GetClass();
+    ObjPtr<mirror::Class> type = GetClass();
     return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
   } else {
     return false;
@@ -569,7 +580,7 @@
 
 bool RegType::IsJavaLangObjectArray() const {
   if (HasClass()) {
-    mirror::Class* type = GetClass();
+    ObjPtr<mirror::Class> type = GetClass();
     return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
   }
   return false;
@@ -712,11 +723,9 @@
       // mechanics to continue.
       return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
     } else {  // Two reference types, compute Join
-      mirror::Class* c1 = GetClass();
-      mirror::Class* c2 = incoming_type.GetClass();
-      DCHECK(c1 != nullptr && !c1->IsPrimitive());
-      DCHECK(c2 != nullptr && !c2->IsPrimitive());
-      mirror::Class* join_class = ClassJoin(c1, c2);
+      DCHECK(GetClass() != nullptr && !GetClass()->IsPrimitive());
+      DCHECK(incoming_type.GetClass() != nullptr && !incoming_type.GetClass()->IsPrimitive());
+      ObjPtr<mirror::Class> join_class = ClassJoin(GetClass(), incoming_type.GetClass());
       if (UNLIKELY(join_class == nullptr)) {
         // Internal error joining the classes (e.g., OOME). Report an unresolved reference type.
         // We cannot report an unresolved merge type, as that will attempt to merge the resolved
@@ -731,30 +740,37 @@
         // (In that case, it is likely a misconfiguration of dex2oat.)
         if (!kIsTargetBuild && Runtime::Current()->IsAotCompiler()) {
           LOG(FATAL) << "Could not create class join of "
-                     << c1->PrettyClass()
+                     << GetClass()->PrettyClass()
                      << " & "
-                     << c2->PrettyClass();
+                     << incoming_type.GetClass()->PrettyClass();
           UNREACHABLE();
         }
 
         return reg_types->MakeUnresolvedReference();
       }
 
-      // Record the dependency that both `c1` and `c2` are assignable to `join_class`.
-      // The `verifier` is null during unit tests.
+      // Record the dependency that both `GetClass()` and `incoming_type.GetClass()`
+      // are assignable to `join_class`. The `verifier` is null during unit tests.
       if (verifier != nullptr) {
-        VerifierDeps::MaybeRecordAssignability(
-            verifier->GetDexFile(), join_class, c1, true /* strict */, true /* is_assignable */);
-        VerifierDeps::MaybeRecordAssignability(
-            verifier->GetDexFile(), join_class, c2, true /* strict */, true /* is_assignable */);
+        VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(),
+                                               join_class,
+                                               GetClass(),
+                                               /* strict */ true,
+                                               /* is_assignable */ true);
+        VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(),
+                                               join_class,
+                                               incoming_type.GetClass(),
+                                               /* strict */ true,
+                                               /* is_assignable */ true);
       }
-      if (c1 == join_class && !IsPreciseReference()) {
+      if (GetClass() == join_class && !IsPreciseReference()) {
         return *this;
-      } else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
+      } else if (incoming_type.GetClass() == join_class && !incoming_type.IsPreciseReference()) {
         return incoming_type;
       } else {
         std::string temp;
-        return reg_types->FromClass(join_class->GetDescriptor(&temp), join_class, false);
+        const char* descriptor = join_class->GetDescriptor(&temp);
+        return reg_types->FromClass(descriptor, join_class, /* precise */ false);
       }
     }
   } else {
@@ -763,7 +779,7 @@
 }
 
 // See comment in reg_type.h
-mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
+ObjPtr<mirror::Class> RegType::ClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t) {
   DCHECK(!s->IsPrimitive()) << s->PrettyClass();
   DCHECK(!t->IsPrimitive()) << t->PrettyClass();
   if (s == t) {
@@ -773,12 +789,12 @@
   } else if (t->IsAssignableFrom(s)) {
     return t;
   } else if (s->IsArrayClass() && t->IsArrayClass()) {
-    mirror::Class* s_ct = s->GetComponentType();
-    mirror::Class* t_ct = t->GetComponentType();
+    ObjPtr<mirror::Class> s_ct = s->GetComponentType();
+    ObjPtr<mirror::Class> t_ct = t->GetComponentType();
     if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
       // Given the types aren't the same, if either array is of primitive types then the only
       // common parent is java.lang.Object
-      mirror::Class* result = s->GetSuperClass();  // short-cut to java.lang.Object
+      ObjPtr<mirror::Class> result = s->GetSuperClass();  // short-cut to java.lang.Object
       DCHECK(result->IsObjectClass());
       return result;
     }
@@ -788,8 +804,9 @@
       self->AssertPendingException();
       return nullptr;
     }
-    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-    mirror::Class* array_class = class_linker->FindArrayClass(self, &common_elem);
+    // Note: The following lookup invalidates existing ObjPtr<>s.
+    ObjPtr<mirror::Class> array_class =
+        Runtime::Current()->GetClassLinker()->FindArrayClass(self, &common_elem);
     if (UNLIKELY(array_class == nullptr)) {
       self->AssertPendingException();
       return nullptr;
@@ -971,7 +988,7 @@
   return cmp1.CanAssignArray(cmp2, reg_types, class_loader, verifier, soft_error);
 }
 
-const NullType* NullType::CreateInstance(mirror::Class* klass,
+const NullType* NullType::CreateInstance(ObjPtr<mirror::Class> klass,
                                          const StringPiece& descriptor,
                                          uint16_t cache_id) {
   CHECK(instance_ == nullptr);
diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h
index 3e99407..29da376 100644
--- a/runtime/verifier/reg_type.h
+++ b/runtime/verifier/reg_type.h
@@ -191,7 +191,7 @@
             !IsUnresolvedSuperClass()));
     return descriptor_;
   }
-  mirror::Class* GetClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
+  ObjPtr<mirror::Class> GetClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
     DCHECK(!IsUnresolvedReference());
     DCHECK(!klass_.IsNull()) << Dump();
     DCHECK(HasClass());
@@ -318,7 +318,7 @@
   }
 
  protected:
-  RegType(mirror::Class* klass,
+  RegType(ObjPtr<mirror::Class> klass,
           const StringPiece& descriptor,
           uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : descriptor_(descriptor),
@@ -365,7 +365,7 @@
    *
    * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
    */
-  static mirror::Class* ClassJoin(mirror::Class* s, mirror::Class* t)
+  static ObjPtr<mirror::Class> ClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   static bool AssignableFrom(const RegType& lhs,
@@ -388,7 +388,7 @@
   static const ConflictType* GetInstance() PURE;
 
   // Create the singleton instance.
-  static const ConflictType* CreateInstance(mirror::Class* klass,
+  static const ConflictType* CreateInstance(ObjPtr<mirror::Class> klass,
                                             const StringPiece& descriptor,
                                             uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -401,7 +401,8 @@
   }
 
  private:
-  ConflictType(mirror::Class* klass, const StringPiece& descriptor,
+  ConflictType(ObjPtr<mirror::Class> klass,
+               const StringPiece& descriptor,
                uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : RegType(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -423,7 +424,7 @@
   static const UndefinedType* GetInstance() PURE;
 
   // Create the singleton instance.
-  static const UndefinedType* CreateInstance(mirror::Class* klass,
+  static const UndefinedType* CreateInstance(ObjPtr<mirror::Class> klass,
                                              const StringPiece& descriptor,
                                              uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -436,7 +437,8 @@
   }
 
  private:
-  UndefinedType(mirror::Class* klass, const StringPiece& descriptor,
+  UndefinedType(ObjPtr<mirror::Class> klass,
+                const StringPiece& descriptor,
                 uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : RegType(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -447,7 +449,8 @@
 
 class PrimitiveType : public RegType {
  public:
-  PrimitiveType(mirror::Class* klass, const StringPiece& descriptor,
+  PrimitiveType(ObjPtr<mirror::Class> klass,
+                const StringPiece& descriptor,
                 uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_);
 
   bool HasClassVirtual() const OVERRIDE { return true; }
@@ -455,7 +458,7 @@
 
 class Cat1Type : public PrimitiveType {
  public:
-  Cat1Type(mirror::Class* klass, const StringPiece& descriptor,
+  Cat1Type(ObjPtr<mirror::Class> klass, const StringPiece& descriptor,
            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_);
 };
 
@@ -463,7 +466,7 @@
  public:
   bool IsInteger() const OVERRIDE { return true; }
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
-  static const IntegerType* CreateInstance(mirror::Class* klass,
+  static const IntegerType* CreateInstance(ObjPtr<mirror::Class> klass,
                                            const StringPiece& descriptor,
                                            uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -475,7 +478,8 @@
   }
 
  private:
-  IntegerType(mirror::Class* klass, const StringPiece& descriptor,
+  IntegerType(ObjPtr<mirror::Class> klass,
+              const StringPiece& descriptor,
               uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat1Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -487,7 +491,7 @@
  public:
   bool IsBoolean() const OVERRIDE { return true; }
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
-  static const BooleanType* CreateInstance(mirror::Class* klass,
+  static const BooleanType* CreateInstance(ObjPtr<mirror::Class> klass,
                                            const StringPiece& descriptor,
                                            uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -499,7 +503,8 @@
   }
 
  private:
-  BooleanType(mirror::Class* klass, const StringPiece& descriptor,
+  BooleanType(ObjPtr<mirror::Class> klass,
+              const StringPiece& descriptor,
               uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat1Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -512,7 +517,7 @@
  public:
   bool IsByte() const OVERRIDE { return true; }
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
-  static const ByteType* CreateInstance(mirror::Class* klass,
+  static const ByteType* CreateInstance(ObjPtr<mirror::Class> klass,
                                         const StringPiece& descriptor,
                                         uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -524,7 +529,8 @@
   }
 
  private:
-  ByteType(mirror::Class* klass, const StringPiece& descriptor,
+  ByteType(ObjPtr<mirror::Class> klass,
+           const StringPiece& descriptor,
            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat1Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -536,7 +542,7 @@
  public:
   bool IsShort() const OVERRIDE { return true; }
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
-  static const ShortType* CreateInstance(mirror::Class* klass,
+  static const ShortType* CreateInstance(ObjPtr<mirror::Class> klass,
                                          const StringPiece& descriptor,
                                          uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -548,7 +554,7 @@
   }
 
  private:
-  ShortType(mirror::Class* klass, const StringPiece& descriptor,
+  ShortType(ObjPtr<mirror::Class> klass, const StringPiece& descriptor,
             uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat1Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -560,7 +566,7 @@
  public:
   bool IsChar() const OVERRIDE { return true; }
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
-  static const CharType* CreateInstance(mirror::Class* klass,
+  static const CharType* CreateInstance(ObjPtr<mirror::Class> klass,
                                         const StringPiece& descriptor,
                                         uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -572,7 +578,8 @@
   }
 
  private:
-  CharType(mirror::Class* klass, const StringPiece& descriptor,
+  CharType(ObjPtr<mirror::Class> klass,
+           const StringPiece& descriptor,
            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat1Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -584,7 +591,7 @@
  public:
   bool IsFloat() const OVERRIDE { return true; }
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
-  static const FloatType* CreateInstance(mirror::Class* klass,
+  static const FloatType* CreateInstance(ObjPtr<mirror::Class> klass,
                                          const StringPiece& descriptor,
                                          uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -596,7 +603,8 @@
   }
 
  private:
-  FloatType(mirror::Class* klass, const StringPiece& descriptor,
+  FloatType(ObjPtr<mirror::Class> klass,
+            const StringPiece& descriptor,
             uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat1Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -606,7 +614,8 @@
 
 class Cat2Type : public PrimitiveType {
  public:
-  Cat2Type(mirror::Class* klass, const StringPiece& descriptor,
+  Cat2Type(ObjPtr<mirror::Class> klass,
+           const StringPiece& descriptor,
            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_);
 };
 
@@ -615,7 +624,7 @@
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
   bool IsLongLo() const OVERRIDE { return true; }
   bool IsLong() const OVERRIDE { return true; }
-  static const LongLoType* CreateInstance(mirror::Class* klass,
+  static const LongLoType* CreateInstance(ObjPtr<mirror::Class> klass,
                                           const StringPiece& descriptor,
                                           uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -627,7 +636,8 @@
   }
 
  private:
-  LongLoType(mirror::Class* klass, const StringPiece& descriptor,
+  LongLoType(ObjPtr<mirror::Class> klass,
+             const StringPiece& descriptor,
              uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat2Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -639,7 +649,7 @@
  public:
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
   bool IsLongHi() const OVERRIDE { return true; }
-  static const LongHiType* CreateInstance(mirror::Class* klass,
+  static const LongHiType* CreateInstance(ObjPtr<mirror::Class> klass,
                                           const StringPiece& descriptor,
                                           uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -651,7 +661,8 @@
   }
 
  private:
-  LongHiType(mirror::Class* klass, const StringPiece& descriptor,
+  LongHiType(ObjPtr<mirror::Class> klass,
+             const StringPiece& descriptor,
              uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat2Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -664,7 +675,7 @@
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
   bool IsDoubleLo() const OVERRIDE { return true; }
   bool IsDouble() const OVERRIDE { return true; }
-  static const DoubleLoType* CreateInstance(mirror::Class* klass,
+  static const DoubleLoType* CreateInstance(ObjPtr<mirror::Class> klass,
                                             const StringPiece& descriptor,
                                             uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -676,7 +687,8 @@
   }
 
  private:
-  DoubleLoType(mirror::Class* klass, const StringPiece& descriptor,
+  DoubleLoType(ObjPtr<mirror::Class> klass,
+               const StringPiece& descriptor,
                uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat2Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -688,9 +700,9 @@
  public:
   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
   virtual bool IsDoubleHi() const OVERRIDE { return true; }
-  static const DoubleHiType* CreateInstance(mirror::Class* klass,
-                                      const StringPiece& descriptor,
-                                      uint16_t cache_id)
+  static const DoubleHiType* CreateInstance(ObjPtr<mirror::Class> klass,
+                                            const StringPiece& descriptor,
+                                            uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
   static const DoubleHiType* GetInstance() PURE;
   static void Destroy();
@@ -700,7 +712,8 @@
   }
 
  private:
-  DoubleHiType(mirror::Class* klass, const StringPiece& descriptor,
+  DoubleHiType(ObjPtr<mirror::Class> klass,
+               const StringPiece& descriptor,
                uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : Cat2Type(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -872,7 +885,7 @@
   static const NullType* GetInstance() PURE;
 
   // Create the singleton instance.
-  static const NullType* CreateInstance(mirror::Class* klass,
+  static const NullType* CreateInstance(ObjPtr<mirror::Class> klass,
                                         const StringPiece& descriptor,
                                         uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -892,7 +905,7 @@
   }
 
  private:
-  NullType(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
+  NullType(ObjPtr<mirror::Class> klass, const StringPiece& descriptor, uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_)
       : RegType(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -906,8 +919,10 @@
 // instructions and must be passed to a constructor.
 class UninitializedType : public RegType {
  public:
-  UninitializedType(mirror::Class* klass, const StringPiece& descriptor,
-                    uint32_t allocation_pc, uint16_t cache_id)
+  UninitializedType(ObjPtr<mirror::Class> klass,
+                    const StringPiece& descriptor,
+                    uint32_t allocation_pc,
+                    uint16_t cache_id)
       : RegType(klass, descriptor, cache_id), allocation_pc_(allocation_pc) {}
 
   bool IsUninitializedTypes() const OVERRIDE;
@@ -929,9 +944,10 @@
 // Similar to ReferenceType but not yet having been passed to a constructor.
 class UninitializedReferenceType FINAL : public UninitializedType {
  public:
-  UninitializedReferenceType(mirror::Class* klass,
+  UninitializedReferenceType(ObjPtr<mirror::Class> klass,
                              const StringPiece& descriptor,
-                             uint32_t allocation_pc, uint16_t cache_id)
+                             uint32_t allocation_pc,
+                             uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_)
       : UninitializedType(klass, descriptor, allocation_pc, cache_id) {
     CheckConstructorInvariants(this);
@@ -969,7 +985,7 @@
 // of a constructor.
 class UninitializedThisReferenceType FINAL : public UninitializedType {
  public:
-  UninitializedThisReferenceType(mirror::Class* klass,
+  UninitializedThisReferenceType(ObjPtr<mirror::Class> klass,
                                  const StringPiece& descriptor,
                                  uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_)
@@ -1010,7 +1026,8 @@
 // sub-class.
 class ReferenceType FINAL : public RegType {
  public:
-  ReferenceType(mirror::Class* klass, const StringPiece& descriptor,
+  ReferenceType(ObjPtr<mirror::Class> klass,
+                const StringPiece& descriptor,
                 uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
       : RegType(klass, descriptor, cache_id) {
     CheckConstructorInvariants(this);
@@ -1034,7 +1051,8 @@
 // type.
 class PreciseReferenceType FINAL : public RegType {
  public:
-  PreciseReferenceType(mirror::Class* klass, const StringPiece& descriptor,
+  PreciseReferenceType(ObjPtr<mirror::Class> klass,
+                       const StringPiece& descriptor,
                        uint16_t cache_id)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
diff --git a/runtime/verifier/reg_type_cache-inl.h b/runtime/verifier/reg_type_cache-inl.h
index 0469a3b..9f87adf 100644
--- a/runtime/verifier/reg_type_cache-inl.h
+++ b/runtime/verifier/reg_type_cache-inl.h
@@ -125,7 +125,7 @@
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangClass() {
   const RegType* result = &FromClass("Ljava/lang/Class;",
-                                     GetClassRoot<mirror::Class>().Ptr(),
+                                     GetClassRoot<mirror::Class>(),
                                      /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
@@ -134,7 +134,7 @@
 inline const PreciseReferenceType& RegTypeCache::JavaLangString() {
   // String is final and therefore always precise.
   const RegType* result = &FromClass("Ljava/lang/String;",
-                                     GetClassRoot<mirror::String>().Ptr(),
+                                     GetClassRoot<mirror::String>(),
                                      /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
@@ -142,7 +142,7 @@
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodHandle() {
   const RegType* result = &FromClass("Ljava/lang/invoke/MethodHandle;",
-                                     GetClassRoot<mirror::MethodHandle>().Ptr(),
+                                     GetClassRoot<mirror::MethodHandle>(),
                                      /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
@@ -150,7 +150,7 @@
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodType() {
   const RegType* result = &FromClass("Ljava/lang/invoke/MethodType;",
-                                     GetClassRoot<mirror::MethodType>().Ptr(),
+                                     GetClassRoot<mirror::MethodType>(),
                                      /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
@@ -158,7 +158,7 @@
 
 inline const RegType&  RegTypeCache::JavaLangThrowable(bool precise) {
   const RegType* result = &FromClass("Ljava/lang/Throwable;",
-                                     GetClassRoot<mirror::Throwable>().Ptr(),
+                                     GetClassRoot<mirror::Throwable>(),
                                      precise);
   if (precise) {
     DCHECK(result->IsPreciseReference());
@@ -170,9 +170,7 @@
 }
 
 inline const RegType& RegTypeCache::JavaLangObject(bool precise) {
-  const RegType* result = &FromClass("Ljava/lang/Object;",
-                                     GetClassRoot<mirror::Object>().Ptr(),
-                                     precise);
+  const RegType* result = &FromClass("Ljava/lang/Object;", GetClassRoot<mirror::Object>(), precise);
   if (precise) {
     DCHECK(result->IsPreciseReference());
     return *down_cast<const PreciseReferenceType*>(result);
@@ -187,7 +185,7 @@
   DCHECK(new_entry != nullptr);
   entries_.push_back(new_entry);
   if (new_entry->HasClass()) {
-    mirror::Class* klass = new_entry->GetClass();
+    ObjPtr<mirror::Class> klass = new_entry->GetClass();
     DCHECK(!klass->IsPrimitive());
     klass_entries_.push_back(std::make_pair(GcRoot<mirror::Class>(klass), new_entry));
   }
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 87fc60b..f1f3488 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -77,7 +77,7 @@
   DCHECK_EQ(entries_.size(), primitive_count_);
 }
 
-const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader,
+const RegType& RegTypeCache::FromDescriptor(ObjPtr<mirror::ClassLoader> loader,
                                             const char* descriptor,
                                             bool precise) {
   DCHECK(RegTypeCache::primitive_initialized_);
@@ -149,14 +149,15 @@
   return true;
 }
 
-mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassLoader* loader) {
+ObjPtr<mirror::Class> RegTypeCache::ResolveClass(const char* descriptor,
+                                                 ObjPtr<mirror::ClassLoader> loader) {
   // Class was not found, must create new type.
   // Try resolving class
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   Thread* self = Thread::Current();
   StackHandleScope<1> hs(self);
   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(loader));
-  mirror::Class* klass = nullptr;
+  ObjPtr<mirror::Class> klass = nullptr;
   if (can_load_classes_) {
     klass = class_linker->FindClass(self, descriptor, class_loader);
   } else {
@@ -175,7 +176,7 @@
   return StringPiece(ptr, string_piece.length());
 }
 
-const RegType& RegTypeCache::From(mirror::ClassLoader* loader,
+const RegType& RegTypeCache::From(ObjPtr<mirror::ClassLoader> loader,
                                   const char* descriptor,
                                   bool precise) {
   StringPiece sp_descriptor(descriptor);
@@ -188,7 +189,7 @@
   }
   // Class not found in the cache, will create a new type for that.
   // Try resolving class.
-  mirror::Class* klass = ResolveClass(descriptor, loader);
+  ObjPtr<mirror::Class> klass = ResolveClass(descriptor, loader);
   if (klass != nullptr) {
     // Class resolved, first look for the class in the list of entries
     // Class was not found, must create new type.
@@ -234,7 +235,7 @@
   return AddEntry(new (&allocator_) UnresolvedReferenceType(AddString("a"), entries_.size()));
 }
 
-const RegType* RegTypeCache::FindClass(mirror::Class* klass, bool precise) const {
+const RegType* RegTypeCache::FindClass(ObjPtr<mirror::Class> klass, bool precise) const {
   DCHECK(klass != nullptr);
   if (klass->IsPrimitive()) {
     // Note: precise isn't used for primitive classes. A char is assignable to an int. All
@@ -242,7 +243,7 @@
     return &RegTypeFromPrimitiveType(klass->GetPrimitiveType());
   }
   for (auto& pair : klass_entries_) {
-    mirror::Class* const reg_klass = pair.first.Read();
+    ObjPtr<mirror::Class> const reg_klass = pair.first.Read();
     if (reg_klass == klass) {
       const RegType* reg_type = pair.second;
       if (MatchingPrecisionForClass(reg_type, precise)) {
@@ -254,7 +255,7 @@
 }
 
 const RegType* RegTypeCache::InsertClass(const StringPiece& descriptor,
-                                         mirror::Class* klass,
+                                         ObjPtr<mirror::Class> klass,
                                          bool precise) {
   // No reference to the class was found, create new reference.
   DCHECK(FindClass(klass, precise) == nullptr);
@@ -265,7 +266,9 @@
   return &AddEntry(reg_type);
 }
 
-const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) {
+const RegType& RegTypeCache::FromClass(const char* descriptor,
+                                       ObjPtr<mirror::Class> klass,
+                                       bool precise) {
   DCHECK(klass != nullptr);
   const RegType* reg_type = FindClass(klass, precise);
   if (reg_type == nullptr) {
@@ -342,7 +345,7 @@
   // code cannot leak to other users.
   auto create_primitive_type_instance = [&](auto type) REQUIRES_SHARED(Locks::mutator_lock_) {
     using Type = typename decltype(type)::type;
-    mirror::Class* klass = nullptr;
+    ObjPtr<mirror::Class> klass = nullptr;
     // Try loading the class from linker.
     DCHECK(type.descriptor != nullptr);
     if (strlen(type.descriptor) > 0) {
@@ -500,7 +503,7 @@
                                                              allocation_pc,
                                                              entries_.size());
   } else {
-    mirror::Class* klass = type.GetClass();
+    ObjPtr<mirror::Class> klass = type.GetClass();
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
       const RegType* cur_entry = entries_[i];
       if (cur_entry->IsUninitializedReference() &&
@@ -532,7 +535,7 @@
     }
     entry = new (&allocator_) UnresolvedReferenceType(descriptor, entries_.size());
   } else {
-    mirror::Class* klass = uninit_type.GetClass();
+    ObjPtr<mirror::Class> klass = uninit_type.GetClass();
     if (uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) {
       // For uninitialized "this reference" look for reference types that are not precise.
       for (size_t i = primitive_count_; i < entries_.size(); i++) {
@@ -583,7 +586,7 @@
     }
     entry = new (&allocator_) UnresolvedUninitializedThisRefType(descriptor, entries_.size());
   } else {
-    mirror::Class* klass = type.GetClass();
+    ObjPtr<mirror::Class> klass = type.GetClass();
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
       const RegType* cur_entry = entries_[i];
       if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) {
@@ -647,7 +650,8 @@
   return AddEntry(entry);
 }
 
-const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) {
+const RegType& RegTypeCache::GetComponentType(const RegType& array,
+                                              ObjPtr<mirror::ClassLoader> loader) {
   if (!array.IsArrayTypes()) {
     return Conflict();
   } else if (array.IsUnresolvedTypes()) {
@@ -655,7 +659,7 @@
     const std::string descriptor(array.GetDescriptor().as_string());
     return FromDescriptor(loader, descriptor.c_str() + 1, false);
   } else {
-    mirror::Class* klass = array.GetClass()->GetComponentType();
+    ObjPtr<mirror::Class> klass = array.GetClass()->GetComponentType();
     std::string temp;
     const char* descriptor = klass->GetDescriptor(&temp);
     if (klass->IsErroneous()) {
diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h
index b32dc11..d668222 100644
--- a/runtime/verifier/reg_type_cache.h
+++ b/runtime/verifier/reg_type_cache.h
@@ -74,16 +74,18 @@
   }
   static void ShutDown();
   const art::verifier::RegType& GetFromId(uint16_t id) const;
-  const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise)
+  const RegType& From(ObjPtr<mirror::ClassLoader> loader, const char* descriptor, bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
   // Find a RegType, returns null if not found.
-  const RegType* FindClass(mirror::Class* klass, bool precise) const
+  const RegType* FindClass(ObjPtr<mirror::Class> klass, bool precise) const
       REQUIRES_SHARED(Locks::mutator_lock_);
   // Insert a new class with a specified descriptor, must not already be in the cache.
-  const RegType* InsertClass(const StringPiece& descriptor, mirror::Class* klass, bool precise)
+  const RegType* InsertClass(const StringPiece& descriptor,
+                             ObjPtr<mirror::Class> klass,
+                             bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
   // Get or insert a reg type for a description, klass, and precision.
-  const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise)
+  const RegType& FromClass(const char* descriptor, ObjPtr<mirror::Class> klass, bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
   const ConstantType& FromCat1Const(int32_t value, bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -91,7 +93,9 @@
       REQUIRES_SHARED(Locks::mutator_lock_);
   const ConstantType& FromCat2ConstHi(int32_t value, bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise)
+  const RegType& FromDescriptor(ObjPtr<mirror::ClassLoader> loader,
+                                const char* descriptor,
+                                bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
   const RegType& FromUnresolvedMerge(const RegType& left,
                                      const RegType& right,
@@ -146,7 +150,7 @@
   const ImpreciseConstType& IntConstant() REQUIRES_SHARED(Locks::mutator_lock_);
   const ImpreciseConstType& PosByteConstant() REQUIRES_SHARED(Locks::mutator_lock_);
   const ImpreciseConstType& PosShortConstant() REQUIRES_SHARED(Locks::mutator_lock_);
-  const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader)
+  const RegType& GetComponentType(const RegType& array, ObjPtr<mirror::ClassLoader> loader)
       REQUIRES_SHARED(Locks::mutator_lock_);
   void Dump(std::ostream& os) REQUIRES_SHARED(Locks::mutator_lock_);
   const RegType& RegTypeFromPrimitiveType(Primitive::Type) const;
@@ -158,7 +162,7 @@
 
  private:
   void FillPrimitiveAndSmallConstantTypes() REQUIRES_SHARED(Locks::mutator_lock_);
-  mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader)
+  ObjPtr<mirror::Class> ResolveClass(const char* descriptor, ObjPtr<mirror::ClassLoader> loader)
       REQUIRES_SHARED(Locks::mutator_lock_);
   bool MatchDescriptor(size_t idx, const StringPiece& descriptor, bool precise)
       REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index fe839f7..500cc37 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -77,8 +77,8 @@
 static constexpr uint32_t kAccVdexAccessFlags =
     kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface;
 
-template <typename T>
-uint16_t VerifierDeps::GetAccessFlags(T* element) {
+template <typename Ptr>
+uint16_t VerifierDeps::GetAccessFlags(Ptr element) {
   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
   if (element == nullptr) {
     return VerifierDeps::kUnresolvedMarker;
@@ -277,7 +277,7 @@
 
 void VerifierDeps::AddClassResolution(const DexFile& dex_file,
                                       dex::TypeIndex type_idx,
-                                      mirror::Class* klass) {
+                                      ObjPtr<mirror::Class> klass) {
   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
   if (dex_deps == nullptr) {
     // This invocation is from verification of a dex file which is not being compiled.
@@ -336,12 +336,13 @@
   dex_deps->methods_.insert(method_tuple);
 }
 
-mirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination,
-                                                                  mirror::Class* source) const {
+ObjPtr<mirror::Class> VerifierDeps::FindOneClassPathBoundaryForInterface(
+    ObjPtr<mirror::Class> destination,
+    ObjPtr<mirror::Class> source) const {
   DCHECK(destination->IsInterface());
   DCHECK(IsInClassPath(destination));
   Thread* thread = Thread::Current();
-  mirror::Class* current = source;
+  ObjPtr<mirror::Class> current = source;
   // Record the classes that are at the boundary between the compiled DEX files and
   // the classpath. We will check those classes later to find one class that inherits
   // `destination`.
@@ -367,7 +368,7 @@
   int32_t iftable_count = source->GetIfTableCount();
   ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
   for (int32_t i = 0; i < iftable_count; ++i) {
-    mirror::Class* itf = iftable->GetInterface(i);
+    ObjPtr<mirror::Class> itf = iftable->GetInterface(i);
     if (!IsInClassPath(itf)) {
       for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
         ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
@@ -391,8 +392,8 @@
 }
 
 void VerifierDeps::AddAssignability(const DexFile& dex_file,
-                                    mirror::Class* destination,
-                                    mirror::Class* source,
+                                    ObjPtr<mirror::Class> destination,
+                                    ObjPtr<mirror::Class> source,
                                     bool is_strict,
                                     bool is_assignable) {
   // Test that the method is only called on reference types.
@@ -429,8 +430,8 @@
     // Both types are arrays. Break down to component types and add recursively.
     // This helps filter out destinations from compiled DEX files (see below)
     // and deduplicate entries with the same canonical component type.
-    mirror::Class* destination_component = destination->GetComponentType();
-    mirror::Class* source_component = source->GetComponentType();
+    ObjPtr<mirror::Class> destination_component = destination->GetComponentType();
+    ObjPtr<mirror::Class> source_component = source->GetComponentType();
 
     // Only perform the optimization if both types are resolved which guarantees
     // that they linked successfully, as required at the top of this method.
@@ -511,7 +512,7 @@
 
 void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
                                               dex::TypeIndex type_idx,
-                                              mirror::Class* klass) {
+                                              ObjPtr<mirror::Class> klass) {
   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
   if (thread_deps != nullptr) {
     thread_deps->AddClassResolution(dex_file, type_idx, klass);
@@ -537,8 +538,8 @@
 }
 
 void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
-                                            mirror::Class* destination,
-                                            mirror::Class* source,
+                                            ObjPtr<mirror::Class> destination,
+                                            ObjPtr<mirror::Class> source,
                                             bool is_strict,
                                             bool is_assignable) {
   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
@@ -858,12 +859,12 @@
 
 // TODO: share that helper with other parts of the compiler that have
 // the same lookup pattern.
-static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
-                                                 Thread* self,
-                                                 const char* name,
-                                                 Handle<mirror::ClassLoader> class_loader)
+static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker,
+                                                        Thread* self,
+                                                        const char* name,
+                                                        Handle<mirror::ClassLoader> class_loader)
     REQUIRES_SHARED(Locks::mutator_lock_) {
-  mirror::Class* result = class_linker->FindClass(self, name, class_loader);
+  ObjPtr<mirror::Class> result = class_linker->FindClass(self, name, class_loader);
   if (result == nullptr) {
     DCHECK(self->IsExceptionPending());
     self->ClearException();
@@ -971,7 +972,7 @@
     std::string expected_decl_klass = entry.IsResolved()
         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
         : dex_file.StringByTypeIdx(field_id.class_idx_);
-    mirror::Class* cls = FindClassAndClearException(
+    ObjPtr<mirror::Class> cls = FindClassAndClearException(
         class_linker, self, expected_decl_klass.c_str(), class_loader);
     if (cls == nullptr) {
       LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
@@ -1034,7 +1035,7 @@
         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
         : dex_file.StringByTypeIdx(method_id.class_idx_);
 
-    mirror::Class* cls = FindClassAndClearException(
+    ObjPtr<mirror::Class> cls = FindClassAndClearException(
         class_linker, self, expected_decl_klass.c_str(), class_loader);
     if (cls == nullptr) {
       LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h
index 94441da..0146b17 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -75,7 +75,7 @@
   // If `klass` is null, the class is assumed unresolved.
   static void MaybeRecordClassResolution(const DexFile& dex_file,
                                          dex::TypeIndex type_idx,
-                                         mirror::Class* klass)
+                                         ObjPtr<mirror::Class> klass)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::verifier_deps_lock_);
 
@@ -99,8 +99,8 @@
   // to `destination` as defined by RegType::AssignableFrom. `dex_file` is the
   // owner of the method for which MethodVerifier performed the assignability test.
   static void MaybeRecordAssignability(const DexFile& dex_file,
-                                       mirror::Class* destination,
-                                       mirror::Class* source,
+                                       ObjPtr<mirror::Class> destination,
+                                       ObjPtr<mirror::Class> source,
                                        bool is_strict,
                                        bool is_assignable)
       REQUIRES_SHARED(Locks::mutator_lock_)
@@ -218,8 +218,8 @@
   // Finds the class in the classpath that makes `source` inherit` from `destination`.
   // Returns null if a class defined in the compiled DEX files, and assignable to
   // `source`, direclty inherits from `destination`.
-  mirror::Class* FindOneClassPathBoundaryForInterface(mirror::Class* destination,
-                                                      mirror::Class* source) const
+  ObjPtr<mirror::Class> FindOneClassPathBoundaryForInterface(ObjPtr<mirror::Class> destination,
+                                                             ObjPtr<mirror::Class> source) const
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Returns the index of `str`. If it is defined in `dex_file_`, this is the dex
@@ -234,8 +234,8 @@
 
   // Returns the bytecode access flags of `element` (bottom 16 bits), or
   // `kUnresolvedMarker` if `element` is null.
-  template <typename T>
-  static uint16_t GetAccessFlags(T* element)
+  template <typename Ptr>
+  static uint16_t GetAccessFlags(Ptr element)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Returns a string ID of the descriptor of the declaring class of `element`,
@@ -256,7 +256,7 @@
 
   void AddClassResolution(const DexFile& dex_file,
                           dex::TypeIndex type_idx,
-                          mirror::Class* klass)
+                          ObjPtr<mirror::Class> klass)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::verifier_deps_lock_);
 
@@ -273,8 +273,8 @@
       REQUIRES(!Locks::verifier_deps_lock_);
 
   void AddAssignability(const DexFile& dex_file,
-                        mirror::Class* destination,
-                        mirror::Class* source,
+                        ObjPtr<mirror::Class> destination,
+                        ObjPtr<mirror::Class> source,
                         bool is_strict,
                         bool is_assignable)
       REQUIRES_SHARED(Locks::mutator_lock_);