ObjPtr<>-ify String allocations, fix stale refs.

ObjPtr<>-ify String allocation functions and related code
and remove some unnecessary calls to ObjPtr<>::Ptr(). Fix
stale reference uses in reference_table_test and stub_test.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 31113334
Change-Id: I42927fb8b7240e5132188f73318b2ccb218748fd
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index c9774a7..8eaa00a 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -939,7 +939,7 @@
 
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
-    mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
+    ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
     EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
   }
@@ -951,7 +951,7 @@
 
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
-    mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
+    ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
     EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
   }
@@ -963,7 +963,7 @@
 
     EXPECT_FALSE(self->IsExceptionPending());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
-    mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
+    ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
     EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
   }
@@ -1059,12 +1059,12 @@
                             self);
     EXPECT_FALSE(self->IsExceptionPending()) << mirror::Object::PrettyTypeOf(self->GetException());
     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
-    mirror::Object* obj = reinterpret_cast<mirror::Object*>(result);
+    ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
     EXPECT_TRUE(obj->IsArrayInstance());
     EXPECT_TRUE(obj->IsObjectArray());
     EXPECT_EQ(c.Get(), obj->GetClass());
     VerifyObject(obj);
-    mirror::Array* array = reinterpret_cast<mirror::Array*>(result);
+    ObjPtr<mirror::Array> array = reinterpret_cast<mirror::Array*>(result);
     EXPECT_EQ(array->GetLength(), 10);
   }
 
@@ -1514,23 +1514,29 @@
 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
     (defined(__x86_64__) && !defined(__APPLE__))
 
-static void set_and_check_static(uint32_t f_idx, mirror::Object* val, Thread* self,
-                                 ArtMethod* referrer, StubTest* test)
+static void set_and_check_static(uint32_t f_idx,
+                                 ObjPtr<mirror::Object> val,
+                                 Thread* self,
+                                 ArtMethod* referrer,
+                                 StubTest* test)
     REQUIRES_SHARED(Locks::mutator_lock_) {
+  StackHandleScope<1u> hs(self);
+  Handle<mirror::Object> h_val = hs.NewHandle(val);
   test->Invoke3WithReferrer(static_cast<size_t>(f_idx),
-                            reinterpret_cast<size_t>(val),
+                            reinterpret_cast<size_t>(h_val.Get()),
                             0U,
                             StubTest::GetEntrypoint(self, kQuickSetObjStatic),
                             self,
                             referrer);
 
   size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f_idx),
-                                         0U, 0U,
+                                         0U,
+                                         0U,
                                          StubTest::GetEntrypoint(self, kQuickGetObjStatic),
                                          self,
                                          referrer);
 
-  EXPECT_EQ(res, reinterpret_cast<size_t>(val)) << "Value " << val;
+  EXPECT_EQ(res, reinterpret_cast<size_t>(h_val.Get())) << "Value " << h_val.Get();
 }
 #endif
 
@@ -1542,7 +1548,7 @@
   set_and_check_static(f->GetDexFieldIndex(), nullptr, self, referrer, test);
 
   // Allocate a string object for simplicity.
-  mirror::String* str = mirror::String::AllocFromModifiedUtf8(self, "Test");
+  ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "Test");
   set_and_check_static(f->GetDexFieldIndex(), str, self, referrer, test);
 
   set_and_check_static(f->GetDexFieldIndex(), nullptr, self, referrer, test);
@@ -1557,27 +1563,33 @@
 
 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
     (defined(__x86_64__) && !defined(__APPLE__))
-static void set_and_check_instance(ArtField* f, mirror::Object* trg,
-                                   mirror::Object* val, Thread* self, ArtMethod* referrer,
+static void set_and_check_instance(ArtField* f,
+                                   ObjPtr<mirror::Object> trg,
+                                   ObjPtr<mirror::Object> val,
+                                   Thread* self,
+                                   ArtMethod* referrer,
                                    StubTest* test)
     REQUIRES_SHARED(Locks::mutator_lock_) {
+  StackHandleScope<2u> hs(self);
+  Handle<mirror::Object> h_trg = hs.NewHandle(trg);
+  Handle<mirror::Object> h_val = hs.NewHandle(val);
   test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
-                            reinterpret_cast<size_t>(trg),
-                            reinterpret_cast<size_t>(val),
+                            reinterpret_cast<size_t>(h_trg.Get()),
+                            reinterpret_cast<size_t>(h_val.Get()),
                             StubTest::GetEntrypoint(self, kQuickSetObjInstance),
                             self,
                             referrer);
 
   size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
-                                         reinterpret_cast<size_t>(trg),
+                                         reinterpret_cast<size_t>(h_trg.Get()),
                                          0U,
                                          StubTest::GetEntrypoint(self, kQuickGetObjInstance),
                                          self,
                                          referrer);
 
-  EXPECT_EQ(res, reinterpret_cast<size_t>(val)) << "Value " << val;
+  EXPECT_EQ(res, reinterpret_cast<size_t>(h_val.Get())) << "Value " << h_val.Get();
 
-  EXPECT_OBJ_PTR_EQ(val, f->GetObj(trg));
+  EXPECT_OBJ_PTR_EQ(h_val.Get(), f->GetObj(h_trg.Get()));
 }
 #endif
 
@@ -1589,7 +1601,7 @@
   set_and_check_instance(f, obj->Get(), nullptr, self, referrer, test);
 
   // Allocate a string object for simplicity.
-  mirror::String* str = mirror::String::AllocFromModifiedUtf8(self, "Test");
+  ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "Test");
   set_and_check_instance(f, obj->Get(), str, self, referrer, test);
 
   set_and_check_instance(f, obj->Get(), nullptr, self, referrer, test);
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 663af81..5443ace 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1346,7 +1346,7 @@
 
 JDWP::JdwpError Dbg::CreateString(const std::string& str, JDWP::ObjectId* new_string_id) {
   Thread* self = Thread::Current();
-  mirror::String* new_string = mirror::String::AllocFromModifiedUtf8(self, str.c_str());
+  ObjPtr<mirror::String> new_string = mirror::String::AllocFromModifiedUtf8(self, str.c_str());
   if (new_string == nullptr) {
     DCHECK(self->IsExceptionPending());
     self->ClearException();
diff --git a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
index 1b3bb6a..ecf6f67 100644
--- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
@@ -89,7 +89,7 @@
     REQUIRES_SHARED(Locks::mutator_lock_) { \
   /* The klass arg is so it matches the ABI of the other object alloc callbacks. */ \
   DCHECK(klass->IsStringClass()) << klass->PrettyClass(); \
-  return mirror::String::AllocEmptyString<instrumented_bool>(self, allocator_type); \
+  return mirror::String::AllocEmptyString<instrumented_bool>(self, allocator_type).Ptr(); \
 } \
 extern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \
     mirror::Class* klass, int32_t component_count, Thread* self) \
@@ -105,24 +105,24 @@
   ScopedQuickEntrypointChecks sqec(self); \
   StackHandleScope<1> hs(self); \
   Handle<mirror::ByteArray> handle_array(hs.NewHandle(byte_array)); \
-  return mirror::String::AllocFromByteArray<instrumented_bool>(self, byte_count, handle_array, \
-                                                               offset, high, allocator_type); \
+  return mirror::String::AllocFromByteArray<instrumented_bool>( \
+      self, byte_count, handle_array, offset, high, allocator_type).Ptr(); \
 } \
 extern "C" mirror::String* artAllocStringFromCharsFromCode##suffix##suffix2( \
     int32_t offset, int32_t char_count, mirror::CharArray* char_array, Thread* self) \
     REQUIRES_SHARED(Locks::mutator_lock_) { \
   StackHandleScope<1> hs(self); \
   Handle<mirror::CharArray> handle_array(hs.NewHandle(char_array)); \
-  return mirror::String::AllocFromCharArray<instrumented_bool>(self, char_count, handle_array, \
-                                                               offset, allocator_type); \
+  return mirror::String::AllocFromCharArray<instrumented_bool>( \
+      self, char_count, handle_array, offset, allocator_type).Ptr(); \
 } \
 extern "C" mirror::String* artAllocStringFromStringFromCode##suffix##suffix2( /* NOLINT */ \
     mirror::String* string, Thread* self) \
     REQUIRES_SHARED(Locks::mutator_lock_) { \
   StackHandleScope<1> hs(self); \
   Handle<mirror::String> handle_string(hs.NewHandle(string)); \
-  return mirror::String::AllocFromString<instrumented_bool>(self, handle_string->GetLength(), \
-                                                            handle_string, 0, allocator_type); \
+  return mirror::String::AllocFromString<instrumented_bool>( \
+    self, handle_string->GetLength(), handle_string, 0, allocator_type).Ptr(); \
 }
 
 #define GENERATE_ENTRYPOINTS_FOR_ALLOCATOR(suffix, allocator_type) \
diff --git a/runtime/gc/heap_test.cc b/runtime/gc/heap_test.cc
index fa10150..5f4621e 100644
--- a/runtime/gc/heap_test.cc
+++ b/runtime/gc/heap_test.cc
@@ -74,7 +74,8 @@
       Handle<mirror::ObjectArray<mirror::Object>> array(hs2.NewHandle(
           mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.Get(), 2048)));
       for (size_t j = 0; j < 2048; ++j) {
-        mirror::String* string = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!");
+        ObjPtr<mirror::String> string =
+            mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!");
         // handle scope operator -> deferences the handle scope before running the method.
         array->Set<false>(j, string);
       }
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 7a40ab4..db3032a 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -805,7 +805,7 @@
 
   const uint32_t vRegC = is_var_args ? inst->VRegC_45cc() : inst->VRegC_4rcc();
   ObjPtr<mirror::Object> receiver(shadow_frame.GetVRegReference(vRegC));
-  Handle<mirror::VarHandle> var_handle(hs.NewHandle(down_cast<mirror::VarHandle*>(receiver.Ptr())));
+  Handle<mirror::VarHandle> var_handle(hs.NewHandle(ObjPtr<mirror::VarHandle>::DownCast(receiver)));
   if (is_var_args) {
     uint32_t args[Instruction::kMaxVarArgRegs];
     inst->GetVarArgs(args, inst_data);
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index 7c0db30..f8d0ef1 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -1779,7 +1779,7 @@
       return nullptr;
     }
     ScopedObjectAccess soa(env);
-    mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
+    ObjPtr<mirror::String> result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
     return soa.AddLocalReference<jstring>(result);
   }
 
@@ -1788,7 +1788,7 @@
       return nullptr;
     }
     ScopedObjectAccess soa(env);
-    mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
+    ObjPtr<mirror::String> result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
     return soa.AddLocalReference<jstring>(result);
   }
 
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 22597dd..220d66b 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -731,7 +731,7 @@
 
 template<VerifyObjectFlags kVerifyFlags,
          ReadBarrierOption kReadBarrierOption>
-inline String* Class::GetName() {
+inline ObjPtr<String> Class::GetName() {
   return GetFieldObject<String, kVerifyFlags, kReadBarrierOption>(
       OFFSET_OF_OBJECT_MEMBER(Class, name_));
 }
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 239105f..74b22c4 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -252,8 +252,8 @@
 // Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
 // but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
 // slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
-String* Class::ComputeName(Handle<Class> h_this) {
-  String* name = h_this->GetName();
+ObjPtr<String> Class::ComputeName(Handle<Class> h_this) {
+  ObjPtr<String> name = h_this->GetName();
   if (name != nullptr) {
     return name;
   }
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index e8a7c1e..6ae3c79 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -340,10 +340,10 @@
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  String* GetName() REQUIRES_SHARED(Locks::mutator_lock_);  // Returns the cached name.
+  ObjPtr<String> GetName() REQUIRES_SHARED(Locks::mutator_lock_);  // Returns the cached name.
   void SetName(ObjPtr<String> name) REQUIRES_SHARED(Locks::mutator_lock_);  // Sets the cached name.
   // Computes the name, then sets the cached value.
-  static String* ComputeName(Handle<Class> h_this) REQUIRES_SHARED(Locks::mutator_lock_)
+  static ObjPtr<String> ComputeName(Handle<Class> h_this) REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
diff --git a/runtime/mirror/string-alloc-inl.h b/runtime/mirror/string-alloc-inl.h
index 4c4e2af..4330235 100644
--- a/runtime/mirror/string-alloc-inl.h
+++ b/runtime/mirror/string-alloc-inl.h
@@ -25,6 +25,7 @@
 #include "class.h"
 #include "class_root.h"
 #include "gc/heap-inl.h"
+#include "obj_ptr.h"
 #include "runtime.h"
 #include "runtime_globals.h"
 #include "thread.h"
@@ -154,10 +155,10 @@
 };
 
 template <bool kIsInstrumented, typename PreFenceVisitor>
-inline String* String::Alloc(Thread* self,
-                             int32_t utf16_length_with_flag,
-                             gc::AllocatorType allocator_type,
-                             const PreFenceVisitor& pre_fence_visitor) {
+inline ObjPtr<String> String::Alloc(Thread* self,
+                                    int32_t utf16_length_with_flag,
+                                    gc::AllocatorType allocator_type,
+                                    const PreFenceVisitor& pre_fence_visitor) {
   constexpr size_t header_size = sizeof(String);
   const bool compressible = kUseStringCompression && String::IsCompressed(utf16_length_with_flag);
   const size_t block_size = (compressible) ? sizeof(uint8_t) : sizeof(uint16_t);
@@ -189,67 +190,64 @@
   }
 
   gc::Heap* heap = runtime->GetHeap();
-  return down_cast<String*>(
+  return ObjPtr<String>::DownCast(MakeObjPtr(
       heap->AllocObjectWithAllocator<kIsInstrumented, true>(self,
                                                             string_class,
                                                             alloc_size,
                                                             allocator_type,
-                                                            pre_fence_visitor));
+                                                            pre_fence_visitor)));
 }
 
 template <bool kIsInstrumented>
-inline String* String::AllocEmptyString(Thread* self, gc::AllocatorType allocator_type) {
+inline ObjPtr<String> String::AllocEmptyString(Thread* self, gc::AllocatorType allocator_type) {
   const int32_t length_with_flag = String::GetFlaggedCount(0, /* compressible= */ true);
   SetStringCountVisitor visitor(length_with_flag);
   return Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
 }
 
 template <bool kIsInstrumented>
-inline String* String::AllocFromByteArray(Thread* self,
-                                          int32_t byte_length,
-                                          Handle<ByteArray> array,
-                                          int32_t offset,
-                                          int32_t high_byte,
-                                          gc::AllocatorType allocator_type) {
+inline ObjPtr<String> String::AllocFromByteArray(Thread* self,
+                                                 int32_t byte_length,
+                                                 Handle<ByteArray> array,
+                                                 int32_t offset,
+                                                 int32_t high_byte,
+                                                 gc::AllocatorType allocator_type) {
   const uint8_t* const src = reinterpret_cast<uint8_t*>(array->GetData()) + offset;
   high_byte &= 0xff;  // Extract the relevant bits before determining `compressible`.
   const bool compressible =
       kUseStringCompression && String::AllASCII<uint8_t>(src, byte_length) && (high_byte == 0);
   const int32_t length_with_flag = String::GetFlaggedCount(byte_length, compressible);
   SetStringCountAndBytesVisitor visitor(length_with_flag, array, offset, high_byte << 8);
-  String* string = Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
-  return string;
+  return Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
 }
 
 template <bool kIsInstrumented>
-inline String* String::AllocFromCharArray(Thread* self,
-                                          int32_t count,
-                                          Handle<CharArray> array,
-                                          int32_t offset,
-                                          gc::AllocatorType allocator_type) {
+inline ObjPtr<String> String::AllocFromCharArray(Thread* self,
+                                                 int32_t count,
+                                                 Handle<CharArray> array,
+                                                 int32_t offset,
+                                                 gc::AllocatorType allocator_type) {
   // It is a caller error to have a count less than the actual array's size.
   DCHECK_GE(array->GetLength(), count);
   const bool compressible = kUseStringCompression &&
                             String::AllASCII<uint16_t>(array->GetData() + offset, count);
   const int32_t length_with_flag = String::GetFlaggedCount(count, compressible);
   SetStringCountAndValueVisitorFromCharArray visitor(length_with_flag, array, offset);
-  String* new_string = Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
-  return new_string;
+  return Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
 }
 
 template <bool kIsInstrumented>
-inline String* String::AllocFromString(Thread* self,
-                                       int32_t string_length,
-                                       Handle<String> string,
-                                       int32_t offset,
-                                       gc::AllocatorType allocator_type) {
+inline ObjPtr<String> String::AllocFromString(Thread* self,
+                                              int32_t string_length,
+                                              Handle<String> string,
+                                              int32_t offset,
+                                              gc::AllocatorType allocator_type) {
   const bool compressible = kUseStringCompression &&
       ((string->IsCompressed()) ? true : String::AllASCII<uint16_t>(string->GetValue() + offset,
                                                                     string_length));
   const int32_t length_with_flag = String::GetFlaggedCount(string_length, compressible);
   SetStringCountAndValueVisitorFromString visitor(length_with_flag, string, offset);
-  String* new_string = Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
-  return new_string;
+  return Alloc<kIsInstrumented>(self, length_with_flag, allocator_type, visitor);
 }
 
 }  // namespace mirror
diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc
index bf99c37..1881c57 100644
--- a/runtime/mirror/string.cc
+++ b/runtime/mirror/string.cc
@@ -119,7 +119,9 @@
   return string;
 }
 
-String* String::AllocFromStrings(Thread* self, Handle<String> string, Handle<String> string2) {
+ObjPtr<String> String::AllocFromStrings(Thread* self,
+                                        Handle<String> string,
+                                        Handle<String> string2) {
   int32_t length = string->GetLength();
   int32_t length2 = string2->GetLength();
   gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
@@ -153,10 +155,12 @@
       memcpy(new_value + length, string2->GetValue(), length2 * sizeof(uint16_t));
     }
   }
-  return new_string.Ptr();
+  return new_string;
 }
 
-String* String::AllocFromUtf16(Thread* self, int32_t utf16_length, const uint16_t* utf16_data_in) {
+ObjPtr<String> String::AllocFromUtf16(Thread* self,
+                                      int32_t utf16_length,
+                                      const uint16_t* utf16_data_in) {
   CHECK(utf16_data_in != nullptr || utf16_length == 0);
   gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
   const bool compressible = kUseStringCompression &&
@@ -175,26 +179,26 @@
     uint16_t* array = string->GetValue();
     memcpy(array, utf16_data_in, utf16_length * sizeof(uint16_t));
   }
-  return string.Ptr();
+  return string;
 }
 
-String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
+ObjPtr<String> String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
   DCHECK(utf != nullptr);
   size_t byte_count = strlen(utf);
   size_t char_count = CountModifiedUtf8Chars(utf, byte_count);
   return AllocFromModifiedUtf8(self, char_count, utf, byte_count);
 }
 
-String* String::AllocFromModifiedUtf8(Thread* self,
-                                      int32_t utf16_length,
-                                      const char* utf8_data_in) {
+ObjPtr<String> String::AllocFromModifiedUtf8(Thread* self,
+                                             int32_t utf16_length,
+                                             const char* utf8_data_in) {
   return AllocFromModifiedUtf8(self, utf16_length, utf8_data_in, strlen(utf8_data_in));
 }
 
-String* String::AllocFromModifiedUtf8(Thread* self,
-                                      int32_t utf16_length,
-                                      const char* utf8_data_in,
-                                      int32_t utf8_length) {
+ObjPtr<String> String::AllocFromModifiedUtf8(Thread* self,
+                                             int32_t utf16_length,
+                                             const char* utf8_data_in,
+                                             int32_t utf8_length) {
   gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
   const bool compressible = kUseStringCompression && (utf16_length == utf8_length);
   const int32_t utf16_length_with_flag = String::GetFlaggedCount(utf16_length, compressible);
@@ -209,7 +213,7 @@
     uint16_t* utf16_data_out = string->GetValue();
     ConvertModifiedUtf8ToUtf16(utf16_data_out, utf16_length, utf8_data_in, utf8_length);
   }
-  return string.Ptr();
+  return string;
 }
 
 bool String::Equals(ObjPtr<String> that) {
@@ -319,7 +323,7 @@
   return count_diff;
 }
 
-CharArray* String::ToCharArray(Thread* self) {
+ObjPtr<CharArray> String::ToCharArray(Thread* self) {
   StackHandleScope<1> hs(self);
   Handle<String> string(hs.NewHandle(this));
   ObjPtr<CharArray> result = CharArray::Alloc(self, GetLength());
@@ -335,7 +339,7 @@
   } else {
     self->AssertPendingOOMException();
   }
-  return result.Ptr();
+  return result;
 }
 
 void String::GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index) {
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 4a7f4ae..c98aa6b 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -26,6 +26,7 @@
 namespace art {
 
 template<class T> class Handle;
+template<class MirrorType> class ObjPtr;
 struct StringOffsets;
 class StubTest_ReadBarrierForRoot_Test;
 
@@ -114,43 +115,57 @@
   ObjPtr<String> Intern() REQUIRES_SHARED(Locks::mutator_lock_);
 
   template <bool kIsInstrumented>
-  ALWAYS_INLINE static String* AllocFromByteArray(Thread* self, int32_t byte_length,
-                                                  Handle<ByteArray> array, int32_t offset,
-                                                  int32_t high_byte,
-                                                  gc::AllocatorType allocator_type)
+  ALWAYS_INLINE static ObjPtr<String> AllocFromByteArray(Thread* self,
+                                                         int32_t byte_length,
+                                                         Handle<ByteArray> array,
+                                                         int32_t offset,
+                                                         int32_t high_byte,
+                                                         gc::AllocatorType allocator_type)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
   template <bool kIsInstrumented>
-  ALWAYS_INLINE static String* AllocFromCharArray(Thread* self, int32_t count,
-                                                  Handle<CharArray> array, int32_t offset,
-                                                  gc::AllocatorType allocator_type)
+  ALWAYS_INLINE static ObjPtr<String> AllocFromCharArray(Thread* self,
+                                                         int32_t count,
+                                                         Handle<CharArray> array,
+                                                         int32_t offset,
+                                                         gc::AllocatorType allocator_type)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
   template <bool kIsInstrumented>
-  ALWAYS_INLINE static String* AllocFromString(Thread* self, int32_t string_length,
-                                               Handle<String> string, int32_t offset,
-                                               gc::AllocatorType allocator_type)
+  ALWAYS_INLINE static ObjPtr<String> AllocFromString(Thread* self,
+                                                      int32_t string_length,
+                                                      Handle<String> string,
+                                                      int32_t offset,
+                                                      gc::AllocatorType allocator_type)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
   template <bool kIsInstrumented>
-  ALWAYS_INLINE static String* AllocEmptyString(Thread* self,
-                                                gc::AllocatorType allocator_type)
+  ALWAYS_INLINE static ObjPtr<String> AllocEmptyString(Thread* self,
+                                                       gc::AllocatorType allocator_type)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static String* AllocFromStrings(Thread* self, Handle<String> string, Handle<String> string2)
+  static ObjPtr<String> AllocFromStrings(Thread* self,
+                                         Handle<String> string,
+                                         Handle<String> string2)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static String* AllocFromUtf16(Thread* self, int32_t utf16_length, const uint16_t* utf16_data_in)
+  static ObjPtr<String> AllocFromUtf16(Thread* self,
+                                       int32_t utf16_length,
+                                       const uint16_t* utf16_data_in)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static String* AllocFromModifiedUtf8(Thread* self, const char* utf)
+  static ObjPtr<String> AllocFromModifiedUtf8(Thread* self, const char* utf)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
-                                       const char* utf8_data_in, int32_t utf8_length)
+  static ObjPtr<String> AllocFromModifiedUtf8(Thread* self,
+                                              int32_t utf16_length,
+                                              const char* utf8_data_in,
+                                              int32_t utf8_length)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length, const char* utf8_data_in)
+  static ObjPtr<String> AllocFromModifiedUtf8(Thread* self,
+                                              int32_t utf16_length,
+                                              const char* utf8_data_in)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
   bool Equals(const char* modified_utf8) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -168,7 +183,7 @@
 
   int32_t CompareTo(ObjPtr<String> other) REQUIRES_SHARED(Locks::mutator_lock_);
 
-  CharArray* ToCharArray(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_)
+  ObjPtr<CharArray> ToCharArray(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Roles::uninterruptible_);
 
   void GetChars(int32_t start, int32_t end, Handle<CharArray> array, int32_t index)
@@ -234,9 +249,10 @@
   }
 
   template <bool kIsInstrumented, typename PreFenceVisitor>
-  ALWAYS_INLINE static String* Alloc(Thread* self, int32_t utf16_length_with_flag,
-                                     gc::AllocatorType allocator_type,
-                                     const PreFenceVisitor& pre_fence_visitor)
+  ALWAYS_INLINE static ObjPtr<String> Alloc(Thread* self,
+                                            int32_t utf16_length_with_flag,
+                                            gc::AllocatorType allocator_type,
+                                            const PreFenceVisitor& pre_fence_visitor)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
diff --git a/runtime/mirror/var_handle_test.cc b/runtime/mirror/var_handle_test.cc
index a349e34..3382066 100644
--- a/runtime/mirror/var_handle_test.cc
+++ b/runtime/mirror/var_handle_test.cc
@@ -52,7 +52,7 @@
     if (art_field->IsStatic()) {
       InitializeVarHandle(fvh.Get(), var_type, access_modes_bit_mask);
     } else {
-      Handle<Class> declaring_type = hs.NewHandle(art_field->GetDeclaringClass().Ptr());
+      Handle<Class> declaring_type = hs.NewHandle(art_field->GetDeclaringClass());
       InitializeVarHandle(fvh.Get(),
                           var_type,
                           declaring_type,
diff --git a/runtime/native/java_lang_String.cc b/runtime/native/java_lang_String.cc
index 4be2086..83498f6 100644
--- a/runtime/native/java_lang_String.cc
+++ b/runtime/native/java_lang_String.cc
@@ -44,8 +44,7 @@
     ThrowNullPointerException("rhs == null");
     return -1;
   } else {
-    return soa.Decode<mirror::String>(java_this)->CompareTo(
-        soa.Decode<mirror::String>(java_rhs).Ptr());
+    return soa.Decode<mirror::String>(java_this)->CompareTo(soa.Decode<mirror::String>(java_rhs));
   }
 }
 
diff --git a/runtime/non_debuggable_classes.cc b/runtime/non_debuggable_classes.cc
index 8b6c2ed..412ab0a 100644
--- a/runtime/non_debuggable_classes.cc
+++ b/runtime/non_debuggable_classes.cc
@@ -32,7 +32,7 @@
   JNIEnvExt* env = self->GetJniEnv();
   ObjPtr<mirror::Class> mirror_klass(self->DecodeJObject(klass)->AsClass());
   for (jclass c : non_debuggable_classes) {
-    if (self->DecodeJObject(c)->AsClass() == mirror_klass.Ptr()) {
+    if (self->DecodeJObject(c)->AsClass() == mirror_klass) {
       return;
     }
   }
diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc
index 2acb2c7..e5c1e6a 100644
--- a/runtime/reference_table_test.cc
+++ b/runtime/reference_table_test.cc
@@ -42,7 +42,7 @@
 
 class ReferenceTableTest : public CommonRuntimeTest {};
 
-static mirror::Object* CreateWeakReference(mirror::Object* referent)
+static ObjPtr<mirror::Object> CreateWeakReference(ObjPtr<mirror::Object> referent)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   Thread* self = Thread::Current();
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
@@ -77,7 +77,9 @@
 
 TEST_F(ReferenceTableTest, Basics) {
   ScopedObjectAccess soa(Thread::Current());
-  mirror::Object* o1 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello");
+  StackHandleScope<5u> hs(soa.Self());
+  Handle<mirror::String> o1 =
+      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello"));
 
   ReferenceTable rt("test", 0, 11);
 
@@ -89,17 +91,17 @@
     EXPECT_EQ(0U, rt.Size());
   }
 
-  // Check removal of all nullss in a empty table is a no-op.
+  // Check removal of all nulls in a empty table is a no-op.
   rt.Remove(nullptr);
   EXPECT_EQ(0U, rt.Size());
 
   // Check removal of all o1 in a empty table is a no-op.
-  rt.Remove(o1);
+  rt.Remove(o1.Get());
   EXPECT_EQ(0U, rt.Size());
 
   // Add o1 and check we have 1 element and can dump.
   {
-    rt.Add(o1);
+    rt.Add(o1.Get());
     EXPECT_EQ(1U, rt.Size());
     std::ostringstream oss;
     rt.Dump(oss);
@@ -108,9 +110,9 @@
   }
 
   // Add a second object 10 times and check dumping is sane.
-  ObjPtr<mirror::Object> o2 = mirror::ShortArray::Alloc(soa.Self(), 0);
+  Handle<mirror::ShortArray> o2 = hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 0));
   for (size_t i = 0; i < 10; ++i) {
-    rt.Add(o2);
+    rt.Add(o2.Get());
     EXPECT_EQ(i + 2, rt.Size());
     std::ostringstream oss;
     rt.Dump(oss);
@@ -129,7 +131,7 @@
 
   // Remove o1 (first element).
   {
-    rt.Remove(o1);
+    rt.Remove(o1.Get());
     EXPECT_EQ(10U, rt.Size());
     std::ostringstream oss;
     rt.Dump(oss);
@@ -138,7 +140,7 @@
 
   // Remove o2 ten times.
   for (size_t i = 0; i < 10; ++i) {
-    rt.Remove(o2);
+    rt.Remove(o2.Get());
     EXPECT_EQ(9 - i, rt.Size());
     std::ostringstream oss;
     rt.Dump(oss);
@@ -154,7 +156,7 @@
 
   // Add a reference and check that the type of the referent is dumped.
   {
-    mirror::Object* empty_reference = CreateWeakReference(nullptr);
+    ObjPtr<mirror::Object> empty_reference = CreateWeakReference(nullptr);
     ASSERT_TRUE(empty_reference->IsReferenceInstance());
     rt.Add(empty_reference);
     std::ostringstream oss;
@@ -165,8 +167,9 @@
   }
 
   {
-    mirror::Object* string_referent = mirror::String::AllocFromModifiedUtf8(Thread::Current(), "A");
-    mirror::Object* non_empty_reference = CreateWeakReference(string_referent);
+    ObjPtr<mirror::Object> string_referent =
+        mirror::String::AllocFromModifiedUtf8(Thread::Current(), "A");
+    ObjPtr<mirror::Object> non_empty_reference = CreateWeakReference(string_referent);
     ASSERT_TRUE(non_empty_reference->IsReferenceInstance());
     rt.Add(non_empty_reference);
     std::ostringstream oss;
@@ -179,7 +182,6 @@
 
   // Add two objects. Enable allocation tracking for the latter.
   {
-    StackHandleScope<3> hs(soa.Self());
     Handle<mirror::String> h_without_trace(hs.NewHandle(
         mirror::String::AllocFromModifiedUtf8(soa.Self(), "Without")));
 
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index f32dd73..34b0f48 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2724,7 +2724,7 @@
             : called_method->LookupResolvedReturnType();
         if (return_type_class != nullptr) {
           return_type = &FromClass(called_method->GetReturnTypeDescriptor(),
-                                   return_type_class.Ptr(),
+                                   return_type_class,
                                    return_type_class->CannotBeAssignedFromOtherTypes());
         } else {
           DCHECK(!can_load_classes_ || self_->IsExceptionPending());