Merge "ObjPtr<>-ify UnstartedRuntime, fix 2 stale reference uses."
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index ff85f47..0985bf2 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -34,6 +34,7 @@
 #include "index_bss_mapping.h"
 #include "instrumentation.h"
 #include "interpreter/interpreter.h"
+#include "interpreter/shadow_frame-inl.h"
 #include "jit/jit.h"
 #include "linear_alloc.h"
 #include "method_handles.h"
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index f23304c..048c6e4 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -31,6 +31,7 @@
 #include "mterp/mterp.h"
 #include "nativehelper/scoped_local_ref.h"
 #include "scoped_thread_state_change-inl.h"
+#include "shadow_frame-inl.h"
 #include "stack.h"
 #include "thread-inl.h"
 #include "unstarted_runtime.h"
@@ -419,7 +420,7 @@
   size_t cur_reg = num_regs - num_ins;
   if (!method->IsStatic()) {
     CHECK(receiver != nullptr);
-    shadow_frame->SetVRegReference(cur_reg, receiver.Ptr());
+    shadow_frame->SetVRegReference(cur_reg, receiver);
     ++cur_reg;
   }
   uint32_t shorty_len = 0;
@@ -430,7 +431,7 @@
       case 'L': {
         ObjPtr<mirror::Object> o =
             reinterpret_cast<StackReference<mirror::Object>*>(&args[arg_pos])->AsMirrorPtr();
-        shadow_frame->SetVRegReference(cur_reg, o.Ptr());
+        shadow_frame->SetVRegReference(cur_reg, o);
         break;
       }
       case 'J': case 'D': {
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 5a50ec5..708a788 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -34,6 +34,7 @@
 #include "mirror/var_handle.h"
 #include "reflection-inl.h"
 #include "reflection.h"
+#include "shadow_frame-inl.h"
 #include "stack.h"
 #include "thread-inl.h"
 #include "transaction.h"
@@ -1428,6 +1429,24 @@
   }
 }
 
+// Assign register 'src_reg' from shadow_frame to register 'dest_reg' into new_shadow_frame.
+static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFrame& shadow_frame,
+                                  size_t dest_reg, size_t src_reg)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  // Uint required, so that sign extension does not make this wrong on 64b systems
+  uint32_t src_value = shadow_frame.GetVReg(src_reg);
+  ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference<kVerifyNone>(src_reg);
+
+  // If both register locations contains the same value, the register probably holds a reference.
+  // Note: As an optimization, non-moving collectors leave a stale reference value
+  // in the references array even after the original vreg was overwritten to a non-reference.
+  if (src_value == reinterpret_cast<uintptr_t>(o.Ptr())) {
+    new_shadow_frame->SetVRegReference(dest_reg, o);
+  } else {
+    new_shadow_frame->SetVReg(dest_reg, src_value);
+  }
+}
+
 template <bool is_range>
 inline void CopyRegisters(ShadowFrame& caller_frame,
                           ShadowFrame* callee_frame,
@@ -1612,7 +1631,7 @@
               return false;
             }
           }
-          new_shadow_frame->SetVRegReference(dest_reg, o.Ptr());
+          new_shadow_frame->SetVRegReference(dest_reg, o);
           break;
         }
         // Handle doubles and longs. 2 consecutive virtual register slots.
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 67a0349..37234e1 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -543,24 +543,6 @@
   return branch_offset <= 0;
 }
 
-// Assign register 'src_reg' from shadow_frame to register 'dest_reg' into new_shadow_frame.
-static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFrame& shadow_frame,
-                                  size_t dest_reg, size_t src_reg)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  // Uint required, so that sign extension does not make this wrong on 64b systems
-  uint32_t src_value = shadow_frame.GetVReg(src_reg);
-  ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference<kVerifyNone>(src_reg);
-
-  // If both register locations contains the same value, the register probably holds a reference.
-  // Note: As an optimization, non-moving collectors leave a stale reference value
-  // in the references array even after the original vreg was overwritten to a non-reference.
-  if (src_value == reinterpret_cast<uintptr_t>(o.Ptr())) {
-    new_shadow_frame->SetVRegReference(dest_reg, o.Ptr());
-  } else {
-    new_shadow_frame->SetVReg(dest_reg, src_value);
-  }
-}
-
 // The arg_offset is the offset to the first input register in the frame.
 void ArtInterpreterToCompiledCodeBridge(Thread* self,
                                         ArtMethod* caller,
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 5c7838c..2762629 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -24,6 +24,7 @@
 #include "jit/jit.h"
 #include "jvalue-inl.h"
 #include "safe_math.h"
+#include "shadow_frame-inl.h"
 
 namespace art {
 namespace interpreter {
@@ -299,7 +300,7 @@
         PREAMBLE();
         ObjPtr<mirror::Throwable> exception = self->GetException();
         DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
-        shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
+        shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
         self->ClearException();
         inst = inst->Next_1xx();
         break;
@@ -514,7 +515,7 @@
         if (UNLIKELY(s == nullptr)) {
           HANDLE_PENDING_EXCEPTION();
         } else {
-          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
           inst = inst->Next_2xx();
         }
         break;
@@ -527,7 +528,7 @@
         if (UNLIKELY(s == nullptr)) {
           HANDLE_PENDING_EXCEPTION();
         } else {
-          shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
           inst = inst->Next_3xx();
         }
         break;
@@ -542,7 +543,7 @@
         if (UNLIKELY(c == nullptr)) {
           HANDLE_PENDING_EXCEPTION();
         } else {
-          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
           inst = inst->Next_2xx();
         }
         break;
@@ -556,7 +557,7 @@
         if (UNLIKELY(mh == nullptr)) {
           HANDLE_PENDING_EXCEPTION();
         } else {
-          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh);
           inst = inst->Next_2xx();
         }
         break;
@@ -570,7 +571,7 @@
         if (UNLIKELY(mt == nullptr)) {
           HANDLE_PENDING_EXCEPTION();
         } else {
-          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt);
           inst = inst->Next_2xx();
         }
         break;
@@ -681,7 +682,7 @@
             HANDLE_PENDING_EXCEPTION();
             break;
           }
-          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
           inst = inst->Next_2xx();
         }
         break;
@@ -698,7 +699,7 @@
         if (UNLIKELY(obj == nullptr)) {
           HANDLE_PENDING_EXCEPTION();
         } else {
-          shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
+          shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
           inst = inst->Next_2xx();
         }
         break;
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 1b39a74..d62f511 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -24,6 +24,7 @@
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "interpreter/interpreter_common.h"
 #include "interpreter/interpreter_intrinsics.h"
+#include "interpreter/shadow_frame-inl.h"
 
 namespace art {
 namespace interpreter {
@@ -369,7 +370,7 @@
   if (UNLIKELY(s == nullptr)) {
     return true;
   }
-  shadow_frame->SetVRegReference(tgt_vreg, s.Ptr());
+  shadow_frame->SetVRegReference(tgt_vreg, s);
   return false;
 }
 
@@ -386,7 +387,7 @@
   if (UNLIKELY(c == nullptr)) {
     return true;
   }
-  shadow_frame->SetVRegReference(tgt_vreg, c.Ptr());
+  shadow_frame->SetVRegReference(tgt_vreg, c);
   return false;
 }
 
@@ -399,7 +400,7 @@
   if (UNLIKELY(mh == nullptr)) {
     return true;
   }
-  shadow_frame->SetVRegReference(tgt_vreg, mh.Ptr());
+  shadow_frame->SetVRegReference(tgt_vreg, mh);
   return false;
 }
 
@@ -413,7 +414,7 @@
   if (UNLIKELY(mt == nullptr)) {
     return true;
   }
-  shadow_frame->SetVRegReference(tgt_vreg, mt.Ptr());
+  shadow_frame->SetVRegReference(tgt_vreg, mt);
   return false;
 }
 
diff --git a/runtime/interpreter/shadow_frame-inl.h b/runtime/interpreter/shadow_frame-inl.h
new file mode 100644
index 0000000..7eaad59
--- /dev/null
+++ b/runtime/interpreter/shadow_frame-inl.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_INTERPRETER_SHADOW_FRAME_INL_H_
+#define ART_RUNTIME_INTERPRETER_SHADOW_FRAME_INL_H_
+
+#include "shadow_frame.h"
+
+#include "obj_ptr-inl.h"
+
+namespace art {
+
+template<VerifyObjectFlags kVerifyFlags /*= kDefaultVerifyFlags*/>
+inline void ShadowFrame::SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  DCHECK_LT(i, NumberOfVRegs());
+  if (kVerifyFlags & kVerifyWrites) {
+    VerifyObject(val);
+  }
+  ReadBarrier::MaybeAssertToSpaceInvariant(val.Ptr());
+  uint32_t* vreg = &vregs_[i];
+  reinterpret_cast<StackReference<mirror::Object>*>(vreg)->Assign(val);
+  if (HasReferenceArray()) {
+    References()[i].Assign(val);
+  }
+}
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_INTERPRETER_SHADOW_FRAME_INL_H_
diff --git a/runtime/interpreter/shadow_frame.h b/runtime/interpreter/shadow_frame.h
index d5451ff..f76b86c 100644
--- a/runtime/interpreter/shadow_frame.h
+++ b/runtime/interpreter/shadow_frame.h
@@ -37,6 +37,7 @@
 
 class ArtMethod;
 class ShadowFrame;
+template<class MirrorType> class ObjPtr;
 class Thread;
 union JValue;
 
@@ -245,18 +246,8 @@
   }
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  void SetVRegReference(size_t i, mirror::Object* val) REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK_LT(i, NumberOfVRegs());
-    if (kVerifyFlags & kVerifyWrites) {
-      VerifyObject(val);
-    }
-    ReadBarrier::MaybeAssertToSpaceInvariant(val);
-    uint32_t* vreg = &vregs_[i];
-    reinterpret_cast<StackReference<mirror::Object>*>(vreg)->Assign(val);
-    if (HasReferenceArray()) {
-      References()[i].Assign(val);
-    }
-  }
+  void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
+      REQUIRES_SHARED(Locks::mutator_lock_);
 
   void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_) {
     DCHECK(method != nullptr);
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 0e429a6..7abb007 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -131,7 +131,7 @@
   std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 
-  mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
+  ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
   if (found == nullptr && abort_if_not_found) {
     if (!self->IsExceptionPending()) {
       AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
@@ -142,7 +142,7 @@
   }
   if (found != nullptr && initialize_class) {
     StackHandleScope<1> hs(self);
-    Handle<mirror::Class> h_class(hs.NewHandle(found));
+    HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
     if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
       CHECK(self->IsExceptionPending());
       return;
@@ -269,8 +269,7 @@
     AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
     return;
   }
-  mirror::Class* klass = param->AsClass();
-  Handle<mirror::Class> h_klass(hs.NewHandle(klass));
+  Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
 
   // Check that it's not null.
   if (h_klass == nullptr) {
@@ -280,7 +279,7 @@
 
   // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
   if (Runtime::Current()->IsActiveTransaction()) {
-    if (h_klass.Get()->IsFinalizable()) {
+    if (h_klass->IsFinalizable()) {
       AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
                         h_klass->PrettyClass().c_str());
       return;
@@ -299,7 +298,7 @@
       cons = nullptr;
     }
     if (cons != nullptr) {
-      Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
+      Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
       CHECK(h_obj != nullptr);  // We don't expect OOM at compile-time.
       EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
       if (!self->IsExceptionPending()) {
@@ -323,8 +322,8 @@
     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
   // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
   // going the reflective Dex way.
-  mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
-  mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
+  ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
+  ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
   ArtField* found = nullptr;
   for (ArtField& field : klass->GetIFields()) {
     if (name2->Equals(field.GetName())) {
@@ -376,13 +375,13 @@
 void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
   // Special managed code cut-out to allow method lookup in a un-started runtime.
-  mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
+  ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
   if (klass == nullptr) {
     ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
     return;
   }
-  mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
-  mirror::ObjectArray<mirror::Class>* args =
+  ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
+  ObjPtr<mirror::ObjectArray<mirror::Class>> args =
       shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
   Runtime* runtime = Runtime::Current();
   bool transaction = runtime->IsActiveTransaction();
@@ -414,7 +413,7 @@
 // Special managed code cut-out to allow constructor lookup in a un-started runtime.
 void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
-  mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
+  ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
   if (klass == nullptr) {
     ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
     return;
@@ -830,12 +829,12 @@
   }
 
   // Type checking.
-  mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
+  ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
       GetComponentType();
 
   if (!src_type->IsPrimitive()) {
     // Check that the second type is not primitive.
-    mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
+    ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
         GetComponentType();
     if (trg_type->IsPrimitiveInt()) {
       AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
@@ -1894,7 +1893,7 @@
 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
-  mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
+  ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
   Primitive::Type primitive_type = component->GetPrimitiveType();
   result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
 }
@@ -1902,7 +1901,7 @@
 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
-  mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
+  ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
   Primitive::Type primitive_type = component->GetPrimitiveType();
   result->SetI(Primitive::ComponentSize(primitive_type));
 }
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index fd43562..860de2c 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -35,6 +35,7 @@
 #include "mirror/string-inl.h"
 #include "runtime.h"
 #include "scoped_thread_state_change-inl.h"
+#include "shadow_frame-inl.h"
 #include "thread.h"
 #include "transaction.h"
 
@@ -82,7 +83,7 @@
   // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
   //       of three everywhere. That is enough to test all cases.
 
-  static mirror::ObjectArray<mirror::Object>* CreateObjectArray(
+  static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
       Thread* self,
       ObjPtr<mirror::Class> component_type,
       const StackHandleScope<3>& data)
@@ -98,10 +99,10 @@
       result->Set(static_cast<int32_t>(i), data.GetReference(i));
       CHECK(!self->IsExceptionPending());
     }
-    return result.Ptr();
+    return result;
   }
 
-  static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array,
+  static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
                                const StackHandleScope<3>& data)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     CHECK_EQ(array->GetLength(), 3);
@@ -114,9 +115,9 @@
   void RunArrayCopy(Thread* self,
                     ShadowFrame* tmp,
                     bool expect_exception,
-                    mirror::ObjectArray<mirror::Object>* src,
+                    ObjPtr<mirror::ObjectArray<mirror::Object>> src,
                     int32_t src_pos,
-                    mirror::ObjectArray<mirror::Object>* dst,
+                    ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
                     int32_t dst_pos,
                     int32_t length)
       REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -137,8 +138,8 @@
   void RunArrayCopy(Thread* self,
                     ShadowFrame* tmp,
                     bool expect_exception,
-                    mirror::Class* src_component_class,
-                    mirror::Class* dst_component_class,
+                    ObjPtr<mirror::Class> src_component_class,
+                    ObjPtr<mirror::Class> dst_component_class,
                     const StackHandleScope<3>& src_data,
                     int32_t src_pos,
                     const StackHandleScope<3>& dst_data,
@@ -366,7 +367,7 @@
   // TODO: Actual UTF.
   constexpr const char* base_string = "abcdefghijklmnop";
   int32_t base_len = static_cast<int32_t>(strlen(base_string));
-  mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
+  ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
 
   JValue result;
   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
@@ -386,7 +387,7 @@
 TEST_F(UnstartedRuntimeTest, StringInit) {
   Thread* self = Thread::Current();
   ScopedObjectAccess soa(self);
-  mirror::Class* klass = mirror::String::GetJavaLangString();
+  ObjPtr<mirror::Class> klass = mirror::String::GetJavaLangString();
   ArtMethod* method =
       klass->FindConstructor("(Ljava/lang/String;)V",
                              Runtime::Current()->GetClassLinker()->GetImagePointerSize());
@@ -398,10 +399,13 @@
   JValue result;
   ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
   const char* base_string = "hello_world";
-  mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string);
-  mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, "");
-  shadow_frame->SetVRegReference(0, reference_empty_string);
-  shadow_frame->SetVRegReference(1, string_arg);
+  StackHandleScope<2> hs(self);
+  Handle<mirror::String> string_arg =
+      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
+  Handle<mirror::String> reference_empty_string =
+      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
+  shadow_frame->SetVRegReference(0, reference_empty_string.Get());
+  shadow_frame->SetVRegReference(1, string_arg.Get());
 
   interpreter::DoCall<false, false>(method,
                                     self,
@@ -409,7 +413,7 @@
                                     Instruction::At(inst_data),
                                     inst_data[0],
                                     &result);
-  mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL());
+  ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
   EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
 
   if (string_arg->IsCompressed() && string_result->IsCompressed()) {
@@ -442,7 +446,7 @@
 
   // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
   //       allocate.
-  StackHandleScope<2> hs_misc(self);
+  StackHandleScope<3> hs_misc(self);
   Handle<mirror::Class> object_class(
       hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
 
@@ -461,10 +465,10 @@
   RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
   RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
 
-  mirror::ObjectArray<mirror::Object>* class_as_array =
-      reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get());
-  RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0);
-  RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0);
+  Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
+      hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
+  RunArrayCopy(self, tmp, true, class_as_array.Get(), 0, array.Get(), 0, 0);
+  RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array.Get(), 0, 0);
 
   ShadowFrame::DeleteDeoptimizedFrame(tmp);
 }
@@ -897,7 +901,7 @@
   JValue result;
   ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
 
-  mirror::Class* class_klass = mirror::Class::GetJavaLangClass();
+  ObjPtr<mirror::Class> class_klass = mirror::Class::GetJavaLangClass();
   shadow_frame->SetVRegReference(0, class_klass);
   UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
   EXPECT_EQ(result.GetZ(), 0);
@@ -906,7 +910,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(), "LNested$1;", loader);
+  ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
   ASSERT_TRUE(c != nullptr);
   shadow_frame->SetVRegReference(0, c);
   UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
@@ -1042,7 +1046,7 @@
                                     Instruction::At(inst_data),
                                     inst_data[0],
                                     &result);
-  ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL());
+  ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
   ASSERT_TRUE(string_result != nullptr);
 
   std::string mod_utf = string_result->ToModifiedUtf8();
@@ -1138,7 +1142,7 @@
     ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
 
     for (const char* name : kTestCases) {
-      mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name);
+      ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
       CHECK(name_string != nullptr);
 
       if (in_transaction) {
@@ -1213,8 +1217,10 @@
 };
 
 TEST_F(UnstartedClassForNameTest, ClassForName) {
-  auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
+  auto runner = [](Thread* self,
+                   ShadowFrame* shadow_frame,
+                   ObjPtr<mirror::String> name,
+                   JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
     shadow_frame->SetVRegReference(0, name);
     UnstartedClassForName(self, shadow_frame, result, 0);
   };
@@ -1222,8 +1228,10 @@
 }
 
 TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
-  auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
-            REQUIRES_SHARED(Locks::mutator_lock_) {
+  auto runner = [](Thread* self,
+                   ShadowFrame* shadow_frame,
+                   ObjPtr<mirror::String> name,
+                   JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
     shadow_frame->SetVRegReference(0, name);
     shadow_frame->SetVReg(1, 0);
     shadow_frame->SetVRegReference(2, nullptr);
@@ -1239,8 +1247,10 @@
   StackHandleScope<1> hs(self);
   Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
 
-  auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
+  auto runner = [&](Thread* th,
+                    ShadowFrame* shadow_frame,
+                    ObjPtr<mirror::String> name,
+                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
     shadow_frame->SetVRegReference(0, name);
     shadow_frame->SetVReg(1, 0);
     shadow_frame->SetVRegReference(2, boot_cp.Get());
@@ -1256,7 +1266,10 @@
   StackHandleScope<1> hs(self);
   Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
 
-  auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
+  auto runner = [&](Thread* th,
+                    ShadowFrame* shadow_frame,
+                    ObjPtr<mirror::String> name,
+                    JValue* result)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     shadow_frame->SetVRegReference(0, name);
     shadow_frame->SetVReg(1, 0);
@@ -1277,8 +1290,10 @@
   Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
       self->DecodeJObject(path_jobj)->AsClassLoader());
 
-  auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
+  auto runner = [&](Thread* th,
+                    ShadowFrame* shadow_frame,
+                    ObjPtr<mirror::String> name,
+                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
     shadow_frame->SetVRegReference(0, name);
     shadow_frame->SetVReg(1, 0);
     shadow_frame->SetVRegReference(2, path_cp.Get());
@@ -1376,7 +1391,7 @@
   // Should have the right string.
   ObjPtr<mirror::String> result_msg =
       reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
-  EXPECT_EQ(input.Get(), result_msg.Ptr());
+  EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
 
   ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
 }
@@ -1393,7 +1408,7 @@
   ASSERT_FALSE(self->IsExceptionPending());
 
   ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
-  tmp->SetVRegReference(0, str.Ptr());
+  tmp->SetVRegReference(0, str);
   UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
   EXPECT_NE(0, result.GetI());
   EXPECT_EQ(str->IdentityHashCode(), result.GetI());
diff --git a/runtime/method_handles-inl.h b/runtime/method_handles-inl.h
index 00a8c00..c4ac982 100644
--- a/runtime/method_handles-inl.h
+++ b/runtime/method_handles-inl.h
@@ -22,6 +22,7 @@
 #include "common_throws.h"
 #include "dex/dex_instruction.h"
 #include "interpreter/interpreter_common.h"
+#include "interpreter/shadow_frame-inl.h"
 #include "jvalue-inl.h"
 #include "mirror/class.h"
 #include "mirror/method_type.h"
@@ -31,6 +32,79 @@
 
 namespace art {
 
+// A convenience class that allows for iteration through a list of
+// input argument registers. This is used to iterate over input
+// arguments while performing standard argument conversions.
+class ShadowFrameGetter {
+ public:
+  ShadowFrameGetter(const ShadowFrame& shadow_frame,
+                    const InstructionOperands* const operands,
+                    size_t operand_index = 0u)
+      : shadow_frame_(shadow_frame), operands_(operands), operand_index_(operand_index)  {}
+
+  ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return shadow_frame_.GetVReg(Next());
+  }
+
+  ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return shadow_frame_.GetVRegLong(NextLong());
+  }
+
+  ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return shadow_frame_.GetVRegReference(Next());
+  }
+
+ private:
+  uint32_t Next() {
+    const uint32_t next = operands_->GetOperand(operand_index_);
+    operand_index_ += 1;
+    return next;
+  }
+
+  uint32_t NextLong() {
+    const uint32_t next = operands_->GetOperand(operand_index_);
+    operand_index_ += 2;
+    return next;
+  }
+
+  const ShadowFrame& shadow_frame_;
+  const InstructionOperands* const operands_;  // the set of register operands to read
+  size_t operand_index_;  // the next register operand to read from frame
+};
+
+// A convenience class that allows values to be written to a given shadow frame,
+// starting at location |first_dst_reg|.
+class ShadowFrameSetter {
+ public:
+  ShadowFrameSetter(ShadowFrame* shadow_frame, size_t first_dst_reg)
+      : shadow_frame_(shadow_frame), arg_index_(first_dst_reg) {}
+
+  ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
+    DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs());
+    shadow_frame_->SetVReg(arg_index_++, value);
+  }
+
+  ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value)
+      REQUIRES_SHARED(Locks::mutator_lock_) {
+    DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs());
+    shadow_frame_->SetVRegReference(arg_index_++, value);
+  }
+
+  ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
+    DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs());
+    shadow_frame_->SetVRegLong(arg_index_, value);
+    arg_index_ += 2;
+  }
+
+  ALWAYS_INLINE bool Done() const {
+    return arg_index_ == shadow_frame_->NumberOfVRegs();
+  }
+
+ private:
+  ShadowFrame* shadow_frame_;
+  size_t arg_index_;
+};
+
 inline bool ConvertArgumentValue(Handle<mirror::MethodType> callsite_type,
                                  Handle<mirror::MethodType> callee_type,
                                  ObjPtr<mirror::Class> from_class,
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index 1d45aae..27de725 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -19,6 +19,7 @@
 #include "android-base/stringprintf.h"
 
 #include "common_dex_operations.h"
+#include "interpreter/shadow_frame-inl.h"
 #include "jvalue-inl.h"
 #include "mirror/emulated_stack_frame.h"
 #include "mirror/method_handle_impl-inl.h"
diff --git a/runtime/method_handles.h b/runtime/method_handles.h
index fce3d06..b6e3134 100644
--- a/runtime/method_handles.h
+++ b/runtime/method_handles.h
@@ -21,12 +21,13 @@
 
 #include "dex/dex_instruction.h"
 #include "handle.h"
-#include "interpreter/shadow_frame.h"
 #include "jvalue.h"
 #include "mirror/class.h"
 
 namespace art {
 
+class ShadowFrame;
+
 namespace mirror {
 class MethodHandle;
 class MethodType;
@@ -126,79 +127,6 @@
                         int32_t start_index,
                         int32_t end_index) REQUIRES_SHARED(Locks::mutator_lock_);
 
-// A convenience class that allows for iteration through a list of
-// input argument registers. This is used to iterate over input
-// arguments while performing standard argument conversions.
-class ShadowFrameGetter {
- public:
-  ShadowFrameGetter(const ShadowFrame& shadow_frame,
-                    const InstructionOperands* const operands,
-                    size_t operand_index = 0u)
-      : shadow_frame_(shadow_frame), operands_(operands), operand_index_(operand_index)  {}
-
-  ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return shadow_frame_.GetVReg(Next());
-  }
-
-  ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return shadow_frame_.GetVRegLong(NextLong());
-  }
-
-  ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return shadow_frame_.GetVRegReference(Next());
-  }
-
- private:
-  uint32_t Next() {
-    const uint32_t next = operands_->GetOperand(operand_index_);
-    operand_index_ += 1;
-    return next;
-  }
-
-  uint32_t NextLong() {
-    const uint32_t next = operands_->GetOperand(operand_index_);
-    operand_index_ += 2;
-    return next;
-  }
-
-  const ShadowFrame& shadow_frame_;
-  const InstructionOperands* const operands_;  // the set of register operands to read
-  size_t operand_index_;  // the next register operand to read from frame
-};
-
-// A convenience class that allows values to be written to a given shadow frame,
-// starting at location |first_dst_reg|.
-class ShadowFrameSetter {
- public:
-  ShadowFrameSetter(ShadowFrame* shadow_frame, size_t first_dst_reg)
-      : shadow_frame_(shadow_frame), arg_index_(first_dst_reg) {}
-
-  ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs());
-    shadow_frame_->SetVReg(arg_index_++, value);
-  }
-
-  ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs());
-    shadow_frame_->SetVRegReference(arg_index_++, value.Ptr());
-  }
-
-  ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs());
-    shadow_frame_->SetVRegLong(arg_index_, value);
-    arg_index_ += 2;
-  }
-
-  ALWAYS_INLINE bool Done() const {
-    return arg_index_ == shadow_frame_->NumberOfVRegs();
-  }
-
- private:
-  ShadowFrame* shadow_frame_;
-  size_t arg_index_;
-};
-
 bool MethodHandleInvoke(Thread* self,
                         ShadowFrame& shadow_frame,
                         Handle<mirror::MethodHandle> method_handle,
diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc
index 44c819a..c755299 100644
--- a/runtime/mirror/var_handle.cc
+++ b/runtime/mirror/var_handle.cc
@@ -24,7 +24,7 @@
 #include "intrinsics_enum.h"
 #include "jni/jni_internal.h"
 #include "jvalue-inl.h"
-#include "method_handles.h"
+#include "method_handles-inl.h"
 #include "method_type.h"
 #include "well_known_classes.h"
 
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index c555fca..de613d3 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -26,6 +26,7 @@
 #include "entrypoints/quick/quick_entrypoints_enum.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "handle_scope-inl.h"
+#include "interpreter/shadow_frame-inl.h"
 #include "jit/jit.h"
 #include "jit/jit_code_cache.h"
 #include "mirror/class-inl.h"
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 7d1cb5c..8cb0700 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -29,7 +29,7 @@
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc/space/image_space.h"
 #include "gc/space/space-inl.h"
-#include "interpreter/shadow_frame.h"
+#include "interpreter/shadow_frame-inl.h"
 #include "jit/jit.h"
 #include "jit/jit_code_cache.h"
 #include "linear_alloc.h"
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 81ed722..5a80929 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -63,7 +63,7 @@
 #include "handle_scope-inl.h"
 #include "indirect_reference_table-inl.h"
 #include "interpreter/interpreter.h"
-#include "interpreter/shadow_frame.h"
+#include "interpreter/shadow_frame-inl.h"
 #include "java_frame_root_info.h"
 #include "jni/java_vm_ext.h"
 #include "jni/jni_internal.h"