ObjPtr<>-ify tests using ClassLinker::FindClass().

ClassLinker::FindClass() returns a non-ObjPtr<> reference
but it has a lot of uses, so we shall change the uses in
a few steps. This change deals with several tests.

Test: Rely on TreeHugger.
Bug: 31113334
Change-Id: Ib75e20e7ebaff01fb607a09f96675f8cf397ae52
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 8cd0604..6ed029c 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -62,9 +62,10 @@
     Thread* self = Thread::Current();
     EXPECT_TRUE(class_linker_->FindSystemClass(self, descriptor.c_str()) == nullptr);
     EXPECT_TRUE(self->IsExceptionPending());
-    mirror::Object* exception = self->GetException();
+    StackHandleScope<1> hs(self);
+    Handle<mirror::Object> exception = hs.NewHandle<mirror::Object>(self->GetException());
     self->ClearException();
-    mirror::Class* exception_class =
+    ObjPtr<mirror::Class> exception_class =
         class_linker_->FindSystemClass(self, "Ljava/lang/NoClassDefFoundError;");
     EXPECT_TRUE(exception->InstanceOf(exception_class));
   }
@@ -75,7 +76,7 @@
     AssertPrimitiveClass(descriptor, class_linker_->FindSystemClass(self, descriptor.c_str()));
   }
 
-  void AssertPrimitiveClass(const std::string& descriptor, mirror::Class* primitive)
+  void AssertPrimitiveClass(const std::string& descriptor, ObjPtr<mirror::Class> primitive)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     ASSERT_TRUE(primitive != nullptr);
     ASSERT_TRUE(primitive->GetClass() != nullptr);
@@ -113,13 +114,13 @@
     EXPECT_EQ(kAccPublic | kAccFinal | kAccAbstract, primitive->GetAccessFlags());
   }
 
-  void AssertObjectClass(mirror::Class* JavaLangObject)
+  void AssertObjectClass(ObjPtr<mirror::Class> JavaLangObject)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     ASSERT_TRUE(JavaLangObject != nullptr);
     ASSERT_TRUE(JavaLangObject->GetClass() != nullptr);
     ASSERT_EQ(JavaLangObject->GetClass(),
               JavaLangObject->GetClass()->GetClass());
-    EXPECT_EQ(JavaLangObject, JavaLangObject->GetClass()->GetSuperClass());
+    EXPECT_OBJ_PTR_EQ(JavaLangObject, JavaLangObject->GetClass()->GetSuperClass());
     std::string temp;
     ASSERT_STREQ(JavaLangObject->GetDescriptor(&temp), "Ljava/lang/Object;");
     EXPECT_TRUE(JavaLangObject->GetSuperClass() == nullptr);
@@ -172,7 +173,7 @@
 
   void AssertArrayClass(const std::string& array_descriptor,
                         const std::string& component_type,
-                        mirror::ClassLoader* class_loader)
+                        ObjPtr<mirror::ClassLoader> class_loader)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     Thread* self = Thread::Current();
     StackHandleScope<2> hs(self);
@@ -181,7 +182,7 @@
         hs.NewHandle(class_linker_->FindClass(self, array_descriptor.c_str(), loader)));
     std::string temp;
     EXPECT_STREQ(component_type.c_str(), array->GetComponentType()->GetDescriptor(&temp));
-    EXPECT_EQ(class_loader, array->GetClassLoader());
+    EXPECT_OBJ_PTR_EQ(loader.Get(), array->GetClassLoader());
     EXPECT_EQ(kAccFinal | kAccAbstract, (array->GetAccessFlags() & (kAccFinal | kAccAbstract)));
     AssertArrayClass(array_descriptor, array);
   }
@@ -234,7 +235,7 @@
     EXPECT_OBJ_PTR_EQ(class_linker_->FindArrayClass(self, &array_ptr), array.Get());
 
     PointerSize pointer_size = class_linker_->GetImagePointerSize();
-    mirror::Class* JavaLangObject =
+    ObjPtr<mirror::Class> JavaLangObject =
         class_linker_->FindSystemClass(self, "Ljava/lang/Object;");
     ImTable* JavaLangObject_imt = JavaLangObject->GetImt(pointer_size);
     // IMT of a array class should be shared with the IMT of the java.lag.Object
@@ -292,9 +293,9 @@
       }
     }
     EXPECT_EQ(klass->IsInterface(), !klass->HasVTable());
-    mirror::IfTable* iftable = klass->GetIfTable();
+    ObjPtr<mirror::IfTable> iftable = klass->GetIfTable();
     for (int i = 0; i < klass->GetIfTableCount(); i++) {
-      mirror::Class* interface = iftable->GetInterface(i);
+      ObjPtr<mirror::Class> interface = iftable->GetInterface(i);
       ASSERT_TRUE(interface != nullptr);
       if (klass->IsInterface()) {
         EXPECT_EQ(0U, iftable->GetMethodArrayCount(i));
@@ -322,13 +323,13 @@
     for (ArtMethod& method : klass->GetDirectMethods(kRuntimePointerSize)) {
       AssertMethod(&method);
       EXPECT_TRUE(method.IsDirect());
-      EXPECT_EQ(klass.Get(), method.GetDeclaringClass());
+      EXPECT_OBJ_PTR_EQ(klass.Get(), method.GetDeclaringClass());
     }
 
     for (ArtMethod& method : klass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
       AssertMethod(&method);
       EXPECT_FALSE(method.IsDirect());
-      EXPECT_EQ(klass.Get(), method.GetDeclaringClass());
+      EXPECT_OBJ_PTR_EQ(klass.Get(), method.GetDeclaringClass());
     }
 
     for (ArtMethod& method : klass->GetCopiedMethods(kRuntimePointerSize)) {
@@ -386,7 +387,7 @@
     ASSERT_EQ(end_ref_offset.Uint32Value(), current_ref_offset.Uint32Value());
 
     uint32_t total_num_reference_instance_fields = 0;
-    mirror::Class* k = klass.Get();
+    ObjPtr<mirror::Class> k = klass.Get();
     while (k != nullptr) {
       total_num_reference_instance_fields += k->NumReferenceInstanceFields();
       k = k->GetSuperClass();
@@ -400,7 +401,7 @@
     }
   }
 
-  void AssertDexFileClass(mirror::ClassLoader* class_loader, const std::string& descriptor)
+  void AssertDexFileClass(ObjPtr<mirror::ClassLoader> class_loader, const std::string& descriptor)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     ASSERT_TRUE(descriptor != nullptr);
     Thread* self = Thread::Current();
@@ -409,8 +410,8 @@
         hs.NewHandle(class_linker_->FindSystemClass(self, descriptor.c_str())));
     ASSERT_TRUE(klass != nullptr);
     std::string temp;
-    EXPECT_STREQ(descriptor.c_str(), klass.Get()->GetDescriptor(&temp));
-    EXPECT_EQ(class_loader, klass->GetClassLoader());
+    EXPECT_STREQ(descriptor.c_str(), klass->GetDescriptor(&temp));
+    EXPECT_OBJ_PTR_EQ(class_loader, klass->GetClassLoader());
     if (klass->IsPrimitive()) {
       AssertPrimitiveClass(descriptor, klass.Get());
     } else if (klass->IsArrayClass()) {
@@ -420,7 +421,7 @@
     }
   }
 
-  void AssertDexFile(const DexFile& dex, mirror::ClassLoader* class_loader)
+  void AssertDexFile(const DexFile& dex, ObjPtr<mirror::ClassLoader> class_loader)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     // Verify all the classes defined in this file
     for (size_t i = 0; i < dex.NumClassDefs(); i++) {
@@ -469,7 +470,7 @@
 
   bool Check() REQUIRES_SHARED(Locks::mutator_lock_) {
     Thread* self = Thread::Current();
-    mirror::Class* klass =
+    ObjPtr<mirror::Class> klass =
         Runtime::Current()->GetClassLinker()->FindSystemClass(self, class_descriptor.c_str());
     CHECK(klass != nullptr) << class_descriptor;
 
@@ -875,12 +876,13 @@
   Handle<mirror::ClassLoader> class_loader(
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Nested"))));
 
-  mirror::Class* outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader);
+  ObjPtr<mirror::Class> outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader);
   ASSERT_TRUE(outer != nullptr);
   EXPECT_EQ(0U, outer->NumVirtualMethods());
   EXPECT_EQ(1U, outer->NumDirectMethods());
 
-  mirror::Class* inner = class_linker_->FindClass(soa.Self(), "LNested$Inner;", class_loader);
+  ObjPtr<mirror::Class> inner =
+      class_linker_->FindClass(soa.Self(), "LNested$Inner;", class_loader);
   ASSERT_TRUE(inner != nullptr);
   EXPECT_EQ(0U, inner->NumVirtualMethods());
   EXPECT_EQ(1U, inner->NumDirectMethods());
@@ -902,23 +904,24 @@
 
 TEST_F(ClassLinkerTest, FindClass) {
   ScopedObjectAccess soa(Thread::Current());
-  mirror::Class* JavaLangObject = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
-  AssertObjectClass(JavaLangObject);
+  StackHandleScope<2> hs(soa.Self());
+  Handle<mirror::Class> JavaLangObject = hs.NewHandle(
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
+  AssertObjectClass(JavaLangObject.Get());
 
-  StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> class_loader(
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
   AssertNonExistentClass("LMyClass;");
-  mirror::Class* MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
+  ObjPtr<mirror::Class> MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
   ASSERT_TRUE(MyClass != nullptr);
   ASSERT_TRUE(MyClass->GetClass() != nullptr);
   ASSERT_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass());
-  EXPECT_EQ(JavaLangObject, MyClass->GetClass()->GetSuperClass());
+  EXPECT_OBJ_PTR_EQ(JavaLangObject.Get(), MyClass->GetClass()->GetSuperClass());
   std::string temp;
   ASSERT_STREQ(MyClass->GetDescriptor(&temp), "LMyClass;");
-  EXPECT_TRUE(MyClass->GetSuperClass() == JavaLangObject);
+  EXPECT_OBJ_PTR_EQ(MyClass->GetSuperClass(), JavaLangObject.Get());
   EXPECT_TRUE(MyClass->HasSuperClass());
-  EXPECT_EQ(class_loader.Get(), MyClass->GetClassLoader());
+  EXPECT_OBJ_PTR_EQ(class_loader.Get(), MyClass->GetClassLoader());
   EXPECT_EQ(ClassStatus::kResolved, MyClass->GetStatus());
   EXPECT_FALSE(MyClass->IsErroneous());
   EXPECT_TRUE(MyClass->IsLoaded());
@@ -1057,8 +1060,9 @@
 // start of the object
 TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
   ScopedObjectAccess soa(Thread::Current());
-  mirror::Class* array_class = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
-  mirror::ObjectArray<mirror::String>* array =
+  ObjPtr<mirror::Class> array_class =
+      class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
+  ObjPtr<mirror::ObjectArray<mirror::String>> array =
       mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), array_class, 0);
   uintptr_t data_offset =
       reinterpret_cast<uintptr_t>(array->GetRawData(sizeof(mirror::HeapReference<mirror::String>),
@@ -1106,7 +1110,7 @@
   // This lets UnboxPrimitive avoid searching for the field by name at runtime.
   ScopedObjectAccess soa(Thread::Current());
   ScopedNullHandle<mirror::ClassLoader> class_loader;
-  mirror::Class* c;
+  ObjPtr<mirror::Class> c;
   c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
   EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
   c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Byte;", class_loader);
@@ -1127,16 +1131,18 @@
 
 TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
   ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<2> hs(soa.Self());
+  StackHandleScope<3> hs(soa.Self());
   Handle<mirror::ClassLoader> class_loader_1(
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
   Handle<mirror::ClassLoader> class_loader_2(
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
-  mirror::Class* MyClass_1 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1);
-  mirror::Class* MyClass_2 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2);
+  Handle<mirror::Class> MyClass_1 = hs.NewHandle(
+      class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1));
+  ObjPtr<mirror::Class> MyClass_2 =
+      class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2);
   EXPECT_TRUE(MyClass_1 != nullptr);
   EXPECT_TRUE(MyClass_2 != nullptr);
-  EXPECT_NE(MyClass_1, MyClass_2);
+  EXPECT_OBJ_PTR_NE(MyClass_1.Get(), MyClass_2);
 }
 
 TEST_F(ClassLinkerTest, StaticFields) {
@@ -1200,7 +1206,7 @@
       soa.Self(), statics.Get(), "s8", "Ljava/lang/String;");
   EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
   EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
-  mirror::String* str_value = mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot");
+  ObjPtr<mirror::String> str_value = mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot");
   s8->SetObject<false>(s8->GetDeclaringClass(), str_value);
 
   // TODO: Remove EXPECT_FALSE when GCC can handle EXPECT_EQ
@@ -1300,7 +1306,8 @@
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> class_loader(
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
-  mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader);
+  ObjPtr<mirror::Class> klass =
+      class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader);
   ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize);
   ArtMethod* getS0 =
       klass->FindClassMethod("getS0", "()Ljava/lang/Object;", kRuntimePointerSize);
@@ -1345,7 +1352,7 @@
 
 TEST_F(ClassLinkerTest, FinalizableBit) {
   ScopedObjectAccess soa(Thread::Current());
-  mirror::Class* c;
+  ObjPtr<mirror::Class> c;
 
   // Object has a finalize method, but we know it's empty.
   c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
@@ -1381,7 +1388,7 @@
   ScopedObjectAccess soa(Thread::Current());
   std::string temp;
   for (int i = 0; i < ClassLinker::kClassRootsMax; i++) {
-    mirror::Class* klass = class_linker_->GetClassRoot(ClassLinker::ClassRoot(i));
+    ObjPtr<mirror::Class> klass = class_linker_->GetClassRoot(ClassLinker::ClassRoot(i));
     EXPECT_GT(strlen(klass->GetDescriptor(&temp)), 0U);
     EXPECT_STREQ(klass->GetDescriptor(&temp),
                  class_linker_->GetClassRootDescriptor(ClassLinker::ClassRoot(i))) << " i = " << i;
@@ -1391,7 +1398,7 @@
 TEST_F(ClassLinkerTest, ValidatePredefinedClassSizes) {
   ScopedObjectAccess soa(Thread::Current());
   ScopedNullHandle<mirror::ClassLoader> class_loader;
-  mirror::Class* c;
+  ObjPtr<mirror::Class> c;
 
   c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Class;", class_loader);
   ASSERT_TRUE(c != nullptr);
@@ -1418,7 +1425,7 @@
   }
 }
 
-static void CheckVerificationAttempted(mirror::Class* c, bool preverified)
+static void CheckVerificationAttempted(ObjPtr<mirror::Class> c, bool preverified)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   EXPECT_EQ((c->GetAccessFlags() & kAccVerificationAttempted) != 0U, preverified)
       << "Class " << mirror::Class::PrettyClass(c) << " not as expected";
@@ -1430,7 +1437,8 @@
 TEST_F(ClassLinkerTest, Preverified_InitializedBoot) {
   ScopedObjectAccess soa(Thread::Current());
 
-  mirror::Class* JavaLangObject = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
+  ObjPtr<mirror::Class> JavaLangObject =
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
   ASSERT_TRUE(JavaLangObject != nullptr);
   EXPECT_TRUE(JavaLangObject->IsInitialized()) << "Not testing already initialized class from the "
                                                   "core";
@@ -1479,13 +1487,13 @@
   Handle<mirror::Class> jlo_class(
       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
   ASSERT_TRUE(jlo_class != nullptr);
-  EXPECT_TRUE(jlo_class.Get()->IsBootStrapClassLoaded());
+  EXPECT_TRUE(jlo_class->IsBootStrapClassLoaded());
 
   // Statics is not a bootstrap class.
   Handle<mirror::Class> statics(
       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
   ASSERT_TRUE(statics != nullptr);
-  EXPECT_FALSE(statics.Get()->IsBootStrapClassLoaded());
+  EXPECT_FALSE(statics->IsBootStrapClassLoaded());
 }
 
 // Regression test for b/26799552.
@@ -1563,13 +1571,13 @@
   Handle<mirror::Class> string_class(hs.NewHandle(class_linker_->FindClass(soa.Self(),
                                                                            "Ljava/lang/String;",
                                                                            class_loader)));
-  ASSERT_EQ(string_class.Get(), method1_type->GetRType());
-  ASSERT_EQ(string_class.Get(), method1_type->GetPTypes()->Get(0));
+  ASSERT_OBJ_PTR_EQ(string_class.Get(), method1_type->GetRType());
+  ASSERT_OBJ_PTR_EQ(string_class.Get(), method1_type->GetPTypes()->Get(0));
 
   // Resolve the method type again and assert that we get back the same value.
   Handle<mirror::MethodType> method1_type2 = hs.NewHandle(
       class_linker_->ResolveMethodType(soa.Self(), method1_id.proto_idx_, dex_cache, class_loader));
-  ASSERT_EQ(method1_type.Get(), method1_type2.Get());
+  ASSERT_OBJ_PTR_EQ(method1_type.Get(), method1_type2.Get());
 
   // Resolve the MethodType associated with a different method signature
   // and assert it's different.
@@ -1582,7 +1590,7 @@
   const DexFile::MethodId& method2_id = dex_file.GetMethodId(method2->GetDexMethodIndex());
   Handle<mirror::MethodType> method2_type = hs.NewHandle(
       class_linker_->ResolveMethodType(soa.Self(), method2_id.proto_idx_, dex_cache, class_loader));
-  ASSERT_TRUE(method1_type.Get() != method2_type.Get());
+  ASSERT_OBJ_PTR_NE(method1_type.Get(), method2_type.Get());
 }
 
 // Verify that ClassLinker's CreateWellknownClassLoader works as expected
@@ -1599,18 +1607,18 @@
 TEST_F(ClassLinkerTest, PrettyClass) {
   ScopedObjectAccess soa(Thread::Current());
   EXPECT_EQ("null", mirror::Class::PrettyClass(nullptr));
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
+  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
   ASSERT_TRUE(c != nullptr);
-  mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
+  ObjPtr<mirror::Object> o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
   EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Class::PrettyClass(o->GetClass()));
 }
 
 TEST_F(ClassLinkerTest, PrettyClassAndClassLoader) {
   ScopedObjectAccess soa(Thread::Current());
   EXPECT_EQ("null", mirror::Class::PrettyClassAndClassLoader(nullptr));
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
+  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
   ASSERT_TRUE(c != nullptr);
-  mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
+  ObjPtr<mirror::Object> o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
   EXPECT_EQ("java.lang.Class<java.lang.String[],null>",
             mirror::Class::PrettyClassAndClassLoader(o->GetClass()));
 }
@@ -1619,8 +1627,8 @@
   ScopedObjectAccess soa(Thread::Current());
   EXPECT_EQ("null", ArtField::PrettyField(nullptr));
 
-  mirror::Class* java_lang_String = class_linker_->FindSystemClass(soa.Self(),
-                                                                   "Ljava/lang/String;");
+  ObjPtr<mirror::Class> java_lang_String = class_linker_->FindSystemClass(soa.Self(),
+                                                                          "Ljava/lang/String;");
 
   ArtField* f;
   f = java_lang_String->FindDeclaredInstanceField("count", "I");
@@ -1630,7 +1638,7 @@
 
 TEST_F(ClassLinkerTest, JniShortName_JniLongName) {
   ScopedObjectAccess soa(Thread::Current());
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;");
+  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;");
   ASSERT_TRUE(c != nullptr);
   ArtMethod* m;
 
@@ -1682,7 +1690,7 @@
       ASSERT_TRUE(klass != nullptr) << descriptor;
       Handle<mirror::ClassLoader> expected_class_loader(
           hs.NewHandle(soa.Decode<mirror::ClassLoader>(expected_class_loader_obj)));
-      ASSERT_EQ(klass->GetClassLoader(), expected_class_loader.Get());
+      ASSERT_OBJ_PTR_EQ(klass->GetClassLoader(), expected_class_loader.Get());
     }
   }
 };
diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc
index 9278509..141feb4 100644
--- a/runtime/indirect_reference_table_test.cc
+++ b/runtime/indirect_reference_table_test.cc
@@ -60,8 +60,9 @@
                              &error_msg);
   ASSERT_TRUE(irt.IsValid()) << error_msg;
 
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
-  StackHandleScope<4> hs(soa.Self());
+  StackHandleScope<5> hs(soa.Self());
+  Handle<mirror::Class> c =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
   ASSERT_TRUE(c != nullptr);
   Handle<mirror::Object> obj0 = hs.NewHandle(c->AllocObject(soa.Self()));
   ASSERT_TRUE(obj0 != nullptr);
@@ -278,8 +279,9 @@
   ScopedObjectAccess soa(Thread::Current());
   static const size_t kTableMax = 10;
 
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
-  StackHandleScope<5> hs(soa.Self());
+  StackHandleScope<6> hs(soa.Self());
+  Handle<mirror::Class> c = hs.NewHandle(
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
   ASSERT_TRUE(c != nullptr);
   Handle<mirror::Object> obj0 = hs.NewHandle(c->AllocObject(soa.Self()));
   ASSERT_TRUE(obj0 != nullptr);
@@ -487,8 +489,9 @@
   ScopedObjectAccess soa(Thread::Current());
   static const size_t kTableMax = 512;
 
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
-  StackHandleScope<1> hs(soa.Self());
+  StackHandleScope<2> hs(soa.Self());
+  Handle<mirror::Class> c = hs.NewHandle(
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
   ASSERT_TRUE(c != nullptr);
   Handle<mirror::Object> obj0 = hs.NewHandle(c->AllocObject(soa.Self()));
   ASSERT_TRUE(obj0 != nullptr);
diff --git a/runtime/instrumentation_test.cc b/runtime/instrumentation_test.cc
index 3171eeb..8ac26af 100644
--- a/runtime/instrumentation_test.cc
+++ b/runtime/instrumentation_test.cc
@@ -520,7 +520,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtMethod* method =
       klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
@@ -540,7 +540,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtMethod* method =
       klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
@@ -560,7 +560,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
   ASSERT_TRUE(method != nullptr);
@@ -595,7 +595,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
   ASSERT_TRUE(field != nullptr);
@@ -613,7 +613,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
   ASSERT_TRUE(field != nullptr);
@@ -648,7 +648,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtMethod* method_to_deoptimize =
       klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
@@ -697,7 +697,7 @@
   ClassLinker* class_linker = runtime->GetClassLinker();
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
-  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+  ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
   ASSERT_TRUE(klass != nullptr);
   ArtMethod* method_to_deoptimize =
       klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
diff --git a/runtime/jni/jni_internal_test.cc b/runtime/jni/jni_internal_test.cc
index 5d74181..a25049e 100644
--- a/runtime/jni/jni_internal_test.cc
+++ b/runtime/jni/jni_internal_test.cc
@@ -91,7 +91,7 @@
 
   jclass GetPrimitiveClass(char descriptor) {
     ScopedObjectAccess soa(env_);
-    mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor);
+    ObjPtr<mirror::Class> c = class_linker_->FindPrimitiveClass(descriptor);
     CHECK(c != nullptr);
     return soa.AddLocalReference<jclass>(c);
   }
@@ -624,7 +624,7 @@
         StackHandleScope<1> hs(soa.Self());
         Handle<mirror::ClassLoader> loader(
             hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
-        mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
+        ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
         const auto pointer_size = class_linker_->GetImagePointerSize();
         ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size);
         ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 97e0ce6..7a70cae 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -83,7 +83,7 @@
   StackHandleScope<1> hs(soa.Self());
   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
       soa.Decode<mirror::ClassLoader>(jclass_loader)));
-  mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
+  ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
   ASSERT_TRUE(klass != nullptr);
   LinearAlloc* const linear_alloc = klass->GetClassLoader()->GetAllocator();
   EXPECT_NE(linear_alloc, runtime_->GetLinearAlloc());
diff --git a/runtime/mirror/method_type_test.cc b/runtime/mirror/method_type_test.cc
index a361772..16bfc73 100644
--- a/runtime/mirror/method_type_test.cc
+++ b/runtime/mirror/method_type_test.cc
@@ -54,7 +54,7 @@
   CHECK(return_clazz != nullptr);
 
   ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass();
-  mirror::Class* class_array_type = class_linker->FindArrayClass(self, &class_type);
+  ObjPtr<mirror::Class> class_array_type = class_linker->FindArrayClass(self, &class_type);
   Handle<mirror::ObjectArray<mirror::Class>> param_classes = hs.NewHandle(
       mirror::ObjectArray<mirror::Class>::Alloc(self, class_array_type, param_types.size()));
 
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 5306eac..69ba4b9 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -116,7 +116,7 @@
 
 TEST_F(ObjectTest, AllocObjectArray) {
   ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<2> hs(soa.Self());
+  StackHandleScope<3> hs(soa.Self());
   Handle<ObjectArray<Object>> oa(hs.NewHandle(AllocObjectArray<Object>(soa.Self(), 2)));
   EXPECT_EQ(2, oa->GetLength());
   EXPECT_TRUE(oa->Get(0) == nullptr);
@@ -128,17 +128,17 @@
   EXPECT_TRUE(oa->Get(0) == oa.Get());
   EXPECT_TRUE(oa->Get(1) == oa.Get());
 
-  Class* aioobe = class_linker_->FindSystemClass(soa.Self(),
-                                                 "Ljava/lang/ArrayIndexOutOfBoundsException;");
+  Handle<Class> aioobe = hs.NewHandle(
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;"));
 
   EXPECT_TRUE(oa->Get(-1) == nullptr);
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 
   EXPECT_TRUE(oa->Get(2) == nullptr);
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 
   ASSERT_TRUE(oa->GetClass() != nullptr);
@@ -152,53 +152,51 @@
 
 TEST_F(ObjectTest, AllocArray) {
   ScopedObjectAccess soa(Thread::Current());
-  Class* c = class_linker_->FindSystemClass(soa.Self(), "[I");
-  StackHandleScope<1> hs(soa.Self());
-  MutableHandle<Array> a(
-      hs.NewHandle(Array::Alloc<true>(soa.Self(), c, 1, c->GetComponentSizeShift(),
-                                      Runtime::Current()->GetHeap()->GetCurrentAllocator())));
-  EXPECT_TRUE(c == a->GetClass());
+  StackHandleScope<2> hs(soa.Self());
+  MutableHandle<Class> c = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[I"));
+  gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
+  MutableHandle<Array> a = hs.NewHandle(
+      Array::Alloc<true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_EQ(1, a->GetLength());
 
-  c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
-  a.Assign(Array::Alloc<true>(soa.Self(), c, 1, c->GetComponentSizeShift(),
-                              Runtime::Current()->GetHeap()->GetCurrentAllocator()));
-  EXPECT_TRUE(c == a->GetClass());
+  c.Assign(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;"));
+  a.Assign(Array::Alloc<true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_EQ(1, a->GetLength());
 
-  c = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;");
-  a.Assign(Array::Alloc<true>(soa.Self(), c, 1, c->GetComponentSizeShift(),
-                              Runtime::Current()->GetHeap()->GetCurrentAllocator()));
-  EXPECT_TRUE(c == a->GetClass());
+  c.Assign(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;"));
+  a.Assign(Array::Alloc<true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_EQ(1, a->GetLength());
 }
 
 TEST_F(ObjectTest, AllocArray_FillUsable) {
   ScopedObjectAccess soa(Thread::Current());
-  Class* c = class_linker_->FindSystemClass(soa.Self(), "[B");
-  StackHandleScope<1> hs(soa.Self());
-  MutableHandle<Array> a(
-      hs.NewHandle(Array::Alloc<true, true>(soa.Self(), c, 1, c->GetComponentSizeShift(),
-                                            Runtime::Current()->GetHeap()->GetCurrentAllocator())));
-  EXPECT_TRUE(c == a->GetClass());
+  StackHandleScope<2> hs(soa.Self());
+  MutableHandle<Class> c = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[B"));
+  gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
+  MutableHandle<Array> a = hs.NewHandle(
+      Array::Alloc<true, true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_LE(1, a->GetLength());
 
-  c = class_linker_->FindSystemClass(soa.Self(), "[I");
-  a.Assign(Array::Alloc<true, true>(soa.Self(), c, 2, c->GetComponentSizeShift(),
-                                    Runtime::Current()->GetHeap()->GetCurrentAllocator()));
-  EXPECT_TRUE(c == a->GetClass());
+  c.Assign(class_linker_->FindSystemClass(soa.Self(), "[I"));
+  a.Assign(
+      Array::Alloc<true, true>(soa.Self(), c.Get(), 2, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_LE(2, a->GetLength());
 
-  c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
-  a.Assign(Array::Alloc<true, true>(soa.Self(), c, 2, c->GetComponentSizeShift(),
-                                    Runtime::Current()->GetHeap()->GetCurrentAllocator()));
-  EXPECT_TRUE(c == a->GetClass());
+  c.Assign(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;"));
+  a.Assign(
+      Array::Alloc<true, true>(soa.Self(), c.Get(), 2, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_LE(2, a->GetLength());
 
-  c = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;");
-  a.Assign(Array::Alloc<true, true>(soa.Self(), c, 2, c->GetComponentSizeShift(),
-                                    Runtime::Current()->GetHeap()->GetCurrentAllocator()));
-  EXPECT_TRUE(c == a->GetClass());
+  c.Assign(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;"));
+  a.Assign(
+      Array::Alloc<true, true>(soa.Self(), c.Get(), 2, c->GetComponentSizeShift(), allocator_type));
+  EXPECT_TRUE(c.Get() == a->GetClass());
   EXPECT_LE(2, a->GetLength());
 }
 
@@ -218,16 +216,18 @@
   EXPECT_EQ(T(123), a->Get(0));
   EXPECT_EQ(T(321), a->Get(1));
 
-  Class* aioobe = cl->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;");
+  StackHandleScope<1> hs(soa.Self());
+  Handle<Class> aioobe = hs.NewHandle(
+      cl->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;"));
 
   EXPECT_EQ(0, a->Get(-1));
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 
   EXPECT_EQ(0, a->Get(2));
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 }
 
@@ -266,17 +266,18 @@
   EXPECT_DOUBLE_EQ(T(123), a->Get(0));
   EXPECT_DOUBLE_EQ(T(321), a->Get(1));
 
-  Class* aioobe = class_linker_->FindSystemClass(soa.Self(),
-                                                 "Ljava/lang/ArrayIndexOutOfBoundsException;");
+  StackHandleScope<1> hs(soa.Self());
+  Handle<Class> aioobe = hs.NewHandle(
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;"));
 
   EXPECT_DOUBLE_EQ(0, a->Get(-1));
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 
   EXPECT_DOUBLE_EQ(0, a->Get(2));
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 }
 
@@ -296,17 +297,18 @@
   EXPECT_FLOAT_EQ(T(123), a->Get(0));
   EXPECT_FLOAT_EQ(T(321), a->Get(1));
 
-  Class* aioobe = class_linker_->FindSystemClass(soa.Self(),
-                                                 "Ljava/lang/ArrayIndexOutOfBoundsException;");
+  StackHandleScope<1> hs(soa.Self());
+  Handle<Class> aioobe = hs.NewHandle(
+      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;"));
 
   EXPECT_FLOAT_EQ(0, a->Get(-1));
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 
   EXPECT_FLOAT_EQ(0, a->Get(2));
   EXPECT_TRUE(soa.Self()->IsExceptionPending());
-  EXPECT_EQ(aioobe, soa.Self()->GetException()->GetClass());
+  EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass());
   soa.Self()->ClearException();
 }
 
@@ -352,9 +354,10 @@
   jobject class_loader = LoadDex("StaticsFromCode");
   const DexFile* dex_file = GetFirstDexFile(class_loader);
 
-  StackHandleScope<2> hs(soa.Self());
+  StackHandleScope<3> hs(soa.Self());
   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<ClassLoader>(class_loader)));
-  Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", loader);
+  Handle<Class> klass =
+      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", loader));
   ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize);
   const DexFile::TypeId* klass_type_id = dex_file->FindTypeId("LStaticsFromCode;");
   ASSERT_TRUE(klass_type_id != nullptr);
@@ -372,15 +375,15 @@
 
   ArtField* field = FindFieldFromCode<StaticObjectRead, true>(field_idx, clinit, Thread::Current(),
                                                               sizeof(HeapReference<Object>));
-  ObjPtr<Object> s0 = field->GetObj(klass);
+  ObjPtr<Object> s0 = field->GetObj(klass.Get());
   EXPECT_TRUE(s0 != nullptr);
 
   Handle<CharArray> char_array(hs.NewHandle(CharArray::Alloc(soa.Self(), 0)));
   field->SetObj<false>(field->GetDeclaringClass(), char_array.Get());
-  EXPECT_OBJ_PTR_EQ(char_array.Get(), field->GetObj(klass));
+  EXPECT_OBJ_PTR_EQ(char_array.Get(), field->GetObj(klass.Get()));
 
   field->SetObj<false>(field->GetDeclaringClass(), nullptr);
-  EXPECT_EQ(nullptr, field->GetObj(klass));
+  EXPECT_EQ(nullptr, field->GetObj(klass.Get()));
 
   // TODO: more exhaustive tests of all 6 cases of ArtField::*FromCode
 }
@@ -486,9 +489,11 @@
   Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_1)));
   Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_2)));
 
-  Class* klass1 = linker->FindClass(soa.Self(), "LProtoCompare;", class_loader_1);
+  Handle<Class> klass1 =
+      hs.NewHandle(linker->FindClass(soa.Self(), "LProtoCompare;", class_loader_1));
   ASSERT_TRUE(klass1 != nullptr);
-  Class* klass2 = linker->FindClass(soa.Self(), "LProtoCompare2;", class_loader_2);
+  Handle<Class> klass2 =
+      hs.NewHandle(linker->FindClass(soa.Self(), "LProtoCompare2;", class_loader_2));
   ASSERT_TRUE(klass2 != nullptr);
 
   ArtMethod* m1_1 = klass1->GetVirtualMethod(0, kRuntimePointerSize);
@@ -525,11 +530,11 @@
 TEST_F(ObjectTest, InstanceOf) {
   ScopedObjectAccess soa(Thread::Current());
   jobject jclass_loader = LoadDex("XandY");
-  StackHandleScope<3> hs(soa.Self());
+  StackHandleScope<10> hs(soa.Self());
   Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
 
-  Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader);
-  Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader);
+  Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader));
+  Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
   ASSERT_TRUE(X != nullptr);
   ASSERT_TRUE(Y != nullptr);
 
@@ -538,51 +543,56 @@
   ASSERT_TRUE(x != nullptr);
   ASSERT_TRUE(y != nullptr);
 
-  EXPECT_TRUE(x->InstanceOf(X));
-  EXPECT_FALSE(x->InstanceOf(Y));
-  EXPECT_TRUE(y->InstanceOf(X));
-  EXPECT_TRUE(y->InstanceOf(Y));
+  EXPECT_TRUE(x->InstanceOf(X.Get()));
+  EXPECT_FALSE(x->InstanceOf(Y.Get()));
+  EXPECT_TRUE(y->InstanceOf(X.Get()));
+  EXPECT_TRUE(y->InstanceOf(Y.Get()));
 
-  Class* java_lang_Class = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Class;");
-  Class* Object_array_class = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
+  Handle<Class> java_lang_Class =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Class;"));
+  Handle<Class> Object_array_class =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;"));
 
-  EXPECT_FALSE(java_lang_Class->InstanceOf(Object_array_class));
-  EXPECT_TRUE(Object_array_class->InstanceOf(java_lang_Class));
+  EXPECT_FALSE(java_lang_Class->InstanceOf(Object_array_class.Get()));
+  EXPECT_TRUE(Object_array_class->InstanceOf(java_lang_Class.Get()));
 
   // All array classes implement Cloneable and Serializable.
-  Object* array = ObjectArray<Object>::Alloc(soa.Self(), Object_array_class, 1);
-  Class* java_lang_Cloneable =
-      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;");
-  Class* java_io_Serializable =
-      class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;");
-  EXPECT_TRUE(array->InstanceOf(java_lang_Cloneable));
-  EXPECT_TRUE(array->InstanceOf(java_io_Serializable));
+  Handle<Object> array =
+      hs.NewHandle<Object>(ObjectArray<Object>::Alloc(soa.Self(), Object_array_class.Get(), 1));
+  Handle<Class> java_lang_Cloneable =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;"));
+  Handle<Class> java_io_Serializable =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"));
+  EXPECT_TRUE(array->InstanceOf(java_lang_Cloneable.Get()));
+  EXPECT_TRUE(array->InstanceOf(java_io_Serializable.Get()));
 }
 
 TEST_F(ObjectTest, IsAssignableFrom) {
   ScopedObjectAccess soa(Thread::Current());
   jobject jclass_loader = LoadDex("XandY");
-  StackHandleScope<1> hs(soa.Self());
+  StackHandleScope<5> hs(soa.Self());
   Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
-  Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader);
-  Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader);
+  Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader));
+  Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
 
-  EXPECT_TRUE(X->IsAssignableFrom(X));
-  EXPECT_TRUE(X->IsAssignableFrom(Y));
-  EXPECT_FALSE(Y->IsAssignableFrom(X));
-  EXPECT_TRUE(Y->IsAssignableFrom(Y));
+  EXPECT_TRUE(X->IsAssignableFrom(X.Get()));
+  EXPECT_TRUE(X->IsAssignableFrom(Y.Get()));
+  EXPECT_FALSE(Y->IsAssignableFrom(X.Get()));
+  EXPECT_TRUE(Y->IsAssignableFrom(Y.Get()));
 
   // class final String implements CharSequence, ..
-  Class* string = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;");
-  Class* charseq = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/CharSequence;");
+  Handle<Class> string =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;"));
+  Handle<Class> charseq =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/CharSequence;"));
   // Can String be assigned to CharSequence without a cast?
-  EXPECT_TRUE(charseq->IsAssignableFrom(string));
+  EXPECT_TRUE(charseq->IsAssignableFrom(string.Get()));
   // Can CharSequence be assigned to String without a cast?
-  EXPECT_FALSE(string->IsAssignableFrom(charseq));
+  EXPECT_FALSE(string->IsAssignableFrom(charseq.Get()));
 
   // Primitive types are only assignable to themselves
   const char* prims = "ZBCSIJFD";
-  std::vector<Class*> prim_types(strlen(prims));
+  std::vector<ObjPtr<Class>> prim_types(strlen(prims));
   for (size_t i = 0; i < strlen(prims); i++) {
     prim_types[i] = class_linker_->FindPrimitiveClass(prims[i]);
   }
@@ -600,55 +610,61 @@
 TEST_F(ObjectTest, IsAssignableFromArray) {
   ScopedObjectAccess soa(Thread::Current());
   jobject jclass_loader = LoadDex("XandY");
-  StackHandleScope<1> hs(soa.Self());
+  StackHandleScope<14> hs(soa.Self());
   Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
-  Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader);
-  Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader);
+  Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader));
+  Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
   ASSERT_TRUE(X != nullptr);
   ASSERT_TRUE(Y != nullptr);
 
-  Class* YA = class_linker_->FindClass(soa.Self(), "[LY;", class_loader);
-  Class* YAA = class_linker_->FindClass(soa.Self(), "[[LY;", class_loader);
+  Handle<Class> YA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[LY;", class_loader));
+  Handle<Class> YAA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[[LY;", class_loader));
   ASSERT_TRUE(YA != nullptr);
   ASSERT_TRUE(YAA != nullptr);
 
-  Class* XAA = class_linker_->FindClass(soa.Self(), "[[LX;", class_loader);
+  Handle<Class> XAA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[[LX;", class_loader));
   ASSERT_TRUE(XAA != nullptr);
 
-  Class* O = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
-  Class* OA = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;");
-  Class* OAA = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;");
-  Class* OAAA = class_linker_->FindSystemClass(soa.Self(), "[[[Ljava/lang/Object;");
+  Handle<Class> O = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
+  Handle<Class> OA =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;"));
+  Handle<Class> OAA =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;"));
+  Handle<Class> OAAA =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[[Ljava/lang/Object;"));
   ASSERT_TRUE(O != nullptr);
   ASSERT_TRUE(OA != nullptr);
   ASSERT_TRUE(OAA != nullptr);
   ASSERT_TRUE(OAAA != nullptr);
 
-  Class* S = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;");
-  Class* SA = class_linker_->FindSystemClass(soa.Self(), "[Ljava/io/Serializable;");
-  Class* SAA = class_linker_->FindSystemClass(soa.Self(), "[[Ljava/io/Serializable;");
+  Handle<Class> S =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"));
+  Handle<Class> SA =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/io/Serializable;"));
+  Handle<Class> SAA =
+      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/io/Serializable;"));
   ASSERT_TRUE(S != nullptr);
   ASSERT_TRUE(SA != nullptr);
   ASSERT_TRUE(SAA != nullptr);
 
-  Class* IA = class_linker_->FindSystemClass(soa.Self(), "[I");
+  Handle<Class> IA = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[I"));
   ASSERT_TRUE(IA != nullptr);
 
-  EXPECT_TRUE(YAA->IsAssignableFrom(YAA));  // identity
-  EXPECT_TRUE(XAA->IsAssignableFrom(YAA));  // element superclass
-  EXPECT_FALSE(YAA->IsAssignableFrom(XAA));
-  EXPECT_FALSE(Y->IsAssignableFrom(YAA));
-  EXPECT_FALSE(YA->IsAssignableFrom(YAA));
-  EXPECT_TRUE(O->IsAssignableFrom(YAA));  // everything is an Object
-  EXPECT_TRUE(OA->IsAssignableFrom(YAA));
-  EXPECT_TRUE(OAA->IsAssignableFrom(YAA));
-  EXPECT_TRUE(S->IsAssignableFrom(YAA));  // all arrays are Serializable
-  EXPECT_TRUE(SA->IsAssignableFrom(YAA));
-  EXPECT_FALSE(SAA->IsAssignableFrom(YAA));  // unless Y was Serializable
+  EXPECT_TRUE(YAA->IsAssignableFrom(YAA.Get()));  // identity
+  EXPECT_TRUE(XAA->IsAssignableFrom(YAA.Get()));  // element superclass
+  EXPECT_FALSE(YAA->IsAssignableFrom(XAA.Get()));
+  EXPECT_FALSE(Y->IsAssignableFrom(YAA.Get()));
+  EXPECT_FALSE(YA->IsAssignableFrom(YAA.Get()));
+  EXPECT_TRUE(O->IsAssignableFrom(YAA.Get()));  // everything is an Object
+  EXPECT_TRUE(OA->IsAssignableFrom(YAA.Get()));
+  EXPECT_TRUE(OAA->IsAssignableFrom(YAA.Get()));
+  EXPECT_TRUE(S->IsAssignableFrom(YAA.Get()));  // all arrays are Serializable
+  EXPECT_TRUE(SA->IsAssignableFrom(YAA.Get()));
+  EXPECT_FALSE(SAA->IsAssignableFrom(YAA.Get()));  // unless Y was Serializable
 
-  EXPECT_FALSE(IA->IsAssignableFrom(OA));
-  EXPECT_FALSE(OA->IsAssignableFrom(IA));
-  EXPECT_TRUE(O->IsAssignableFrom(IA));
+  EXPECT_FALSE(IA->IsAssignableFrom(OA.Get()));
+  EXPECT_FALSE(OA->IsAssignableFrom(IA.Get()));
+  EXPECT_TRUE(O->IsAssignableFrom(IA.Get()));
 }
 
 TEST_F(ObjectTest, FindInstanceField) {
@@ -656,7 +672,7 @@
   StackHandleScope<1> hs(soa.Self());
   Handle<String> s(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "ABC")));
   ASSERT_TRUE(s != nullptr);
-  Class* c = s->GetClass();
+  ObjPtr<Class> c = s->GetClass();
   ASSERT_TRUE(c != nullptr);
 
   // Wrong type.
@@ -798,7 +814,7 @@
   Handle<mirror::ShortArray> a(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 2)));
   EXPECT_EQ("short[]", mirror::Object::PrettyTypeOf(a.Get()));
 
-  mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
+  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
   ASSERT_TRUE(c != nullptr);
   mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
   EXPECT_EQ("java.lang.String[]", mirror::Object::PrettyTypeOf(o));
diff --git a/runtime/proxy_test.h b/runtime/proxy_test.h
index b559823..9836264 100644
--- a/runtime/proxy_test.h
+++ b/runtime/proxy_test.h
@@ -37,7 +37,9 @@
                                   const char* className,
                                   const std::vector<mirror::Class*>& interfaces)
     REQUIRES_SHARED(Locks::mutator_lock_) {
-  mirror::Class* javaLangObject = class_linker->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
+  StackHandleScope<1> hs(soa.Self());
+  Handle<mirror::Class> javaLangObject = hs.NewHandle(
+      class_linker->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
   CHECK(javaLangObject != nullptr);
 
   jclass javaLangClass = soa.AddLocalReference<jclass>(mirror::Class::GetJavaLangClass());
@@ -67,7 +69,7 @@
       "equals", "(Ljava/lang/Object;)Z", kRuntimePointerSize);
   CHECK(method != nullptr);
   CHECK(!method->IsDirect());
-  CHECK(method->GetDeclaringClass() == javaLangObject);
+  CHECK(method->GetDeclaringClass() == javaLangObject.Get());
   DCHECK(!Runtime::Current()->IsActiveTransaction());
   soa.Env()->SetObjectArrayElement(
       proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
@@ -75,7 +77,7 @@
   method = javaLangObject->FindClassMethod("hashCode", "()I", kRuntimePointerSize);
   CHECK(method != nullptr);
   CHECK(!method->IsDirect());
-  CHECK(method->GetDeclaringClass() == javaLangObject);
+  CHECK(method->GetDeclaringClass() == javaLangObject.Get());
   soa.Env()->SetObjectArrayElement(
       proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
           mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), method)));
@@ -83,7 +85,7 @@
       "toString", "()Ljava/lang/String;", kRuntimePointerSize);
   CHECK(method != nullptr);
   CHECK(!method->IsDirect());
-  CHECK(method->GetDeclaringClass() == javaLangObject);
+  CHECK(method->GetDeclaringClass() == javaLangObject.Get());
   soa.Env()->SetObjectArrayElement(
       proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
           mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), method)));