ObjPtr<>-ify Monitor/-Pool.

Test: m test-art-host-gtest
Test: testrunner.py --host
Bug: 31113334
Change-Id: I2d2ebc5ef56e73e5678e0cfcd84c479611dfcca8
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index b41edc5..2c5ebfe 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -50,7 +50,7 @@
 #include "jni/jni_internal.h"
 #include "mirror/class.h"
 #include "mirror/object-inl.h"
-#include "monitor.h"
+#include "monitor-inl.h"
 #include "nativehelper/scoped_local_ref.h"
 #include "runtime.h"
 #include "scoped_thread_state_change-inl.h"
@@ -236,7 +236,7 @@
 }
 
 template<typename Type>
-static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
+static Type AddLocalRef(art::JNIEnvExt* e, art::ObjPtr<art::mirror::Object> obj)
     REQUIRES_SHARED(art::Locks::mutator_lock_) {
   return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
 }
diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc
index 5e934df..b96c92a 100644
--- a/openjdkjvmti/ti_stack.cc
+++ b/openjdkjvmti/ti_stack.cc
@@ -844,18 +844,17 @@
     return true;
   }
 
-  static void AppendOwnedMonitors(art::mirror::Object* owned_monitor, void* arg)
+  static void AppendOwnedMonitors(art::ObjPtr<art::mirror::Object> owned_monitor, void* arg)
       REQUIRES_SHARED(art::Locks::mutator_lock_) {
     art::Locks::mutator_lock_->AssertSharedHeld(art::Thread::Current());
     MonitorVisitor* visitor = reinterpret_cast<MonitorVisitor*>(arg);
-    art::ObjPtr<art::mirror::Object> mon(owned_monitor);
     // Filter out duplicates.
     for (const art::Handle<art::mirror::Object>& monitor : visitor->monitors) {
-      if (monitor.Get() == mon.Ptr()) {
+      if (monitor.Get() == owned_monitor) {
         return;
       }
     }
-    visitor->monitors.push_back(visitor->hs.NewHandle(mon));
+    visitor->monitors.push_back(visitor->hs.NewHandle(owned_monitor));
     visitor->stack_depths.push_back(visitor->current_stack_depth);
   }
 
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 5ed3acc..0cc7d29 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -141,6 +141,7 @@
         "mirror/throwable.cc",
         "mirror/var_handle.cc",
         "monitor.cc",
+        "monitor_objects_stack_visitor.cc",
         "native_bridge_art_interface.cc",
         "native_stack_dump.cc",
         "native/dalvik_system_DexFile.cc",
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index a38c9ab..c5b111f 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -900,7 +900,7 @@
       return true;
     }
 
-    static void AppendOwnedMonitors(mirror::Object* owned_monitor, void* arg)
+    static void AppendOwnedMonitors(ObjPtr<mirror::Object> owned_monitor, void* arg)
         REQUIRES_SHARED(Locks::mutator_lock_) {
       OwnedMonitorVisitor* visitor = reinterpret_cast<OwnedMonitorVisitor*>(arg);
       visitor->monitors->push_back(gRegistry->Add(owned_monitor));
@@ -939,7 +939,7 @@
   if (!IsSuspendedForDebugger(soa, thread)) {
     return JDWP::ERR_THREAD_NOT_SUSPENDED;
   }
-  mirror::Object* contended_monitor_obj = Monitor::GetContendedMonitor(thread);
+  ObjPtr<mirror::Object> contended_monitor_obj = Monitor::GetContendedMonitor(thread);
   // Add() requires the thread_list_lock_ not held to avoid the lock
   // level violation.
   *contended_monitor = gRegistry->Add(contended_monitor_obj);
diff --git a/runtime/entrypoints/quick/quick_lock_entrypoints.cc b/runtime/entrypoints/quick/quick_lock_entrypoints.cc
index 4bcce21..87286cf 100644
--- a/runtime/entrypoints/quick/quick_lock_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_lock_entrypoints.cc
@@ -29,8 +29,8 @@
     ThrowNullPointerException("Null reference used for synchronization (monitor-enter)");
     return -1;  // Failure.
   } else {
-    obj = obj->MonitorEnter(self);  // May block
-    DCHECK(self->HoldsLock(obj));
+    ObjPtr<mirror::Object> object = obj->MonitorEnter(self);  // May block
+    DCHECK(self->HoldsLock(object));
     // Exceptions can be thrown by monitor event listeners. This is expected to be rare however.
     if (UNLIKELY(self->IsExceptionPending())) {
       // TODO Remove this DCHECK if we expand the use of monitor callbacks.
@@ -38,11 +38,11 @@
           << "Exceptions are only expected to be thrown by plugin code which doesn't seem to be "
           << "loaded.";
       // We need to get rid of the lock
-      bool unlocked = obj->MonitorExit(self);
+      bool unlocked = object->MonitorExit(self);
       DCHECK(unlocked);
       return -1;  // Failure.
     } else {
-      DCHECK(self->HoldsLock(obj));
+      DCHECK(self->HoldsLock(object));
       return 0;  // Success.
     }
   }
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index e203658..56e1807 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -79,11 +79,11 @@
   return Monitor::GetLockOwnerThreadId(this);
 }
 
-inline mirror::Object* Object::MonitorEnter(Thread* self) {
+inline ObjPtr<mirror::Object> Object::MonitorEnter(Thread* self) {
   return Monitor::MonitorEnter(self, this, /*trylock=*/false);
 }
 
-inline mirror::Object* Object::MonitorTryEnter(Thread* self) {
+inline ObjPtr<mirror::Object> Object::MonitorTryEnter(Thread* self) {
   return Monitor::MonitorEnter(self, this, /*trylock=*/true);
 }
 
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 2d69206..fea6eb5 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -153,11 +153,11 @@
   uint32_t GetLockOwnerThreadId();
 
   // Try to enter the monitor, returns non null if we succeeded.
-  mirror::Object* MonitorTryEnter(Thread* self)
+  ObjPtr<mirror::Object> MonitorTryEnter(Thread* self)
       EXCLUSIVE_LOCK_FUNCTION()
       REQUIRES(!Roles::uninterruptible_)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  mirror::Object* MonitorEnter(Thread* self)
+  ObjPtr<mirror::Object> MonitorEnter(Thread* self)
       EXCLUSIVE_LOCK_FUNCTION()
       REQUIRES(!Roles::uninterruptible_)
       REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/monitor-inl.h b/runtime/monitor-inl.h
new file mode 100644
index 0000000..e8ffafa
--- /dev/null
+++ b/runtime/monitor-inl.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 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_MONITOR_INL_H_
+#define ART_RUNTIME_MONITOR_INL_H_
+
+#include "monitor.h"
+
+#include "gc_root-inl.h"
+#include "obj_ptr-inl.h"
+
+namespace art {
+
+template<ReadBarrierOption kReadBarrierOption>
+inline ObjPtr<mirror::Object> Monitor::GetObject() REQUIRES_SHARED(Locks::mutator_lock_) {
+  return obj_.Read<kReadBarrierOption>();
+}
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_MONITOR_INL_H_
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 6abc8d7..676bceb 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "monitor.h"
+#include "monitor-inl.h"
 
 #include <vector>
 
@@ -89,7 +89,7 @@
       stack_dump_lock_profiling_threshold * kDebugThresholdFudgeFactor;
 }
 
-Monitor::Monitor(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code)
+Monitor::Monitor(Thread* self, Thread* owner, ObjPtr<mirror::Object> obj, int32_t hash_code)
     : monitor_lock_("a monitor lock", kMonitorLock),
       monitor_contenders_("monitor contenders", monitor_lock_),
       num_waiters_(0),
@@ -112,7 +112,10 @@
   // The identity hash code is set for the life time of the monitor.
 }
 
-Monitor::Monitor(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code,
+Monitor::Monitor(Thread* self,
+                 Thread* owner,
+                 ObjPtr<mirror::Object> obj,
+                 int32_t hash_code,
                  MonitorId id)
     : monitor_lock_("a monitor lock", kMonitorLock),
       monitor_contenders_("monitor contenders", monitor_lock_),
@@ -273,19 +276,19 @@
   remove(wake_set_);
 }
 
-void Monitor::SetObject(mirror::Object* object) {
+void Monitor::SetObject(ObjPtr<mirror::Object> object) {
   obj_ = GcRoot<mirror::Object>(object);
 }
 
 // This function is inlined and just helps to not have the VLOG and ATRACE check at all the
 // potential tracing points.
-void Monitor::AtraceMonitorLock(Thread* self, mirror::Object* obj, bool is_wait) {
+void Monitor::AtraceMonitorLock(Thread* self, ObjPtr<mirror::Object> obj, bool is_wait) {
   if (UNLIKELY(VLOG_IS_ON(systrace_lock_logging) && ATraceEnabled())) {
     AtraceMonitorLockImpl(self, obj, is_wait);
   }
 }
 
-void Monitor::AtraceMonitorLockImpl(Thread* self, mirror::Object* obj, bool is_wait) {
+void Monitor::AtraceMonitorLockImpl(Thread* self, ObjPtr<mirror::Object> obj, bool is_wait) {
   // Wait() requires a deeper call stack to be useful. Otherwise you'll see "Waiting at
   // Object.java". Assume that we'll wait a nontrivial amount, so it's OK to do a longer
   // stack walk than if !is_wait.
@@ -335,7 +338,7 @@
   // also do not have to be stable, as the monitor may be deflated.
   std::string tmp = StringPrintf("%s %d at %s:%d",
       prefix,
-      (obj == nullptr ? -1 : static_cast<int32_t>(reinterpret_cast<uintptr_t>(obj))),
+      (obj == nullptr ? -1 : static_cast<int32_t>(reinterpret_cast<uintptr_t>(obj.Ptr()))),
       (filename != nullptr ? filename : "null"),
       line_number);
   ATraceBegin(tmp.c_str());
@@ -462,7 +465,7 @@
       called_monitors_callback = true;
       Runtime::Current()->GetRuntimeCallbacks()->MonitorContendedLocking(this);
     }
-    self->SetMonitorEnterObject(GetObject());
+    self->SetMonitorEnterObject(GetObject().Ptr());
     {
       ScopedThreadSuspension tsc(self, kBlocked);  // Change to blocked and give up mutator_lock_.
       uint32_t original_owner_thread_id = 0u;
@@ -627,7 +630,7 @@
   return oss.str();
 }
 
-void Monitor::FailedUnlock(mirror::Object* o,
+void Monitor::FailedUnlock(ObjPtr<mirror::Object> o,
                            uint32_t expected_owner_thread_id,
                            uint32_t found_owner_thread_id,
                            Monitor* monitor) {
@@ -957,7 +960,7 @@
   }
 }
 
-bool Monitor::Deflate(Thread* self, mirror::Object* obj) {
+bool Monitor::Deflate(Thread* self, ObjPtr<mirror::Object> obj) {
   DCHECK(obj != nullptr);
   // Don't need volatile since we only deflate with mutators suspended.
   LockWord lw(obj->GetLockWord(false));
@@ -1007,7 +1010,7 @@
   return true;
 }
 
-void Monitor::Inflate(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code) {
+void Monitor::Inflate(Thread* self, Thread* owner, ObjPtr<mirror::Object> obj, int32_t hash_code) {
   DCHECK(self != nullptr);
   DCHECK(obj != nullptr);
   // Allocate and acquire a new monitor.
@@ -1063,18 +1066,20 @@
 }
 
 // Fool annotalysis into thinking that the lock on obj is acquired.
-static mirror::Object* FakeLock(mirror::Object* obj)
-    EXCLUSIVE_LOCK_FUNCTION(obj) NO_THREAD_SAFETY_ANALYSIS {
+static ObjPtr<mirror::Object> FakeLock(ObjPtr<mirror::Object> obj)
+    EXCLUSIVE_LOCK_FUNCTION(obj.Ptr()) NO_THREAD_SAFETY_ANALYSIS {
   return obj;
 }
 
 // Fool annotalysis into thinking that the lock on obj is release.
-static mirror::Object* FakeUnlock(mirror::Object* obj)
-    UNLOCK_FUNCTION(obj) NO_THREAD_SAFETY_ANALYSIS {
+static ObjPtr<mirror::Object> FakeUnlock(ObjPtr<mirror::Object> obj)
+    UNLOCK_FUNCTION(obj.Ptr()) NO_THREAD_SAFETY_ANALYSIS {
   return obj;
 }
 
-mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj, bool trylock) {
+ObjPtr<mirror::Object> Monitor::MonitorEnter(Thread* self,
+                                             ObjPtr<mirror::Object> obj,
+                                             bool trylock) {
   DCHECK(self != nullptr);
   DCHECK(obj != nullptr);
   self->AssertThreadSuspensionIsAllowable();
@@ -1180,7 +1185,7 @@
   }
 }
 
-bool Monitor::MonitorExit(Thread* self, mirror::Object* obj) {
+bool Monitor::MonitorExit(Thread* self, ObjPtr<mirror::Object> obj) {
   DCHECK(self != nullptr);
   DCHECK(obj != nullptr);
   self->AssertThreadSuspensionIsAllowable();
@@ -1242,8 +1247,12 @@
   }
 }
 
-void Monitor::Wait(Thread* self, mirror::Object *obj, int64_t ms, int32_t ns,
-                   bool interruptShouldThrow, ThreadState why) {
+void Monitor::Wait(Thread* self,
+                   ObjPtr<mirror::Object> obj,
+                   int64_t ms,
+                   int32_t ns,
+                   bool interruptShouldThrow,
+                   ThreadState why) {
   DCHECK(self != nullptr);
   DCHECK(obj != nullptr);
   StackHandleScope<1> hs(self);
@@ -1288,7 +1297,7 @@
   mon->Wait(self, ms, ns, interruptShouldThrow, why);
 }
 
-void Monitor::DoNotify(Thread* self, mirror::Object* obj, bool notify_all) {
+void Monitor::DoNotify(Thread* self, ObjPtr<mirror::Object> obj, bool notify_all) {
   DCHECK(self != nullptr);
   DCHECK(obj != nullptr);
   LockWord lock_word = obj->GetLockWord(true);
@@ -1325,7 +1334,7 @@
   }
 }
 
-uint32_t Monitor::GetLockOwnerThreadId(mirror::Object* obj) {
+uint32_t Monitor::GetLockOwnerThreadId(ObjPtr<mirror::Object> obj) {
   DCHECK(obj != nullptr);
   LockWord lock_word = obj->GetLockWord(true);
   switch (lock_word.GetState()) {
@@ -1347,7 +1356,7 @@
 }
 
 ThreadState Monitor::FetchState(const Thread* thread,
-                                /* out */ mirror::Object** monitor_object,
+                                /* out */ ObjPtr<mirror::Object>* monitor_object,
                                 /* out */ uint32_t* lock_owner_tid) {
   DCHECK(monitor_object != nullptr);
   DCHECK(lock_owner_tid != nullptr);
@@ -1374,14 +1383,14 @@
     case kBlocked:
     case kWaitingForLockInflation:
     {
-      mirror::Object* lock_object = thread->GetMonitorEnterObject();
+      ObjPtr<mirror::Object> lock_object = thread->GetMonitorEnterObject();
       if (lock_object != nullptr) {
         if (kUseReadBarrier && Thread::Current()->GetIsGcMarking()) {
           // We may call Thread::Dump() in the middle of the CC thread flip and this thread's stack
           // may have not been flipped yet and "pretty_object" may be a from-space (stale) ref, in
           // which case the GetLockOwnerThreadId() call below will crash. So explicitly mark/forward
           // it here.
-          lock_object = ReadBarrier::Mark(lock_object);
+          lock_object = ReadBarrier::Mark(lock_object.Ptr());
         }
         *monitor_object = lock_object;
         *lock_owner_tid = lock_object->GetLockOwnerThreadId();
@@ -1396,10 +1405,10 @@
   return state;
 }
 
-mirror::Object* Monitor::GetContendedMonitor(Thread* thread) {
+ObjPtr<mirror::Object> Monitor::GetContendedMonitor(Thread* thread) {
   // This is used to implement JDWP's ThreadReference.CurrentContendedMonitor, and has a bizarre
   // definition of contended that includes a monitor a thread is trying to enter...
-  mirror::Object* result = thread->GetMonitorEnterObject();
+  ObjPtr<mirror::Object> result = thread->GetMonitorEnterObject();
   if (result == nullptr) {
     // ...but also a monitor that the thread is waiting on.
     MutexLock mu(Thread::Current(), *thread->GetWaitMutex());
@@ -1411,8 +1420,10 @@
   return result;
 }
 
-void Monitor::VisitLocks(StackVisitor* stack_visitor, void (*callback)(mirror::Object*, void*),
-                         void* callback_context, bool abort_on_failure) {
+void Monitor::VisitLocks(StackVisitor* stack_visitor,
+                         void (*callback)(ObjPtr<mirror::Object>, void*),
+                         void* callback_context,
+                         bool abort_on_failure) {
   ArtMethod* m = stack_visitor->GetMethod();
   CHECK(m != nullptr);
 
@@ -1420,7 +1431,7 @@
   // TODO: use the JNI implementation's table of explicit MonitorEnter calls and dump those too.
   if (m->IsNative()) {
     if (m->IsSynchronized()) {
-      mirror::Object* jni_this =
+      ObjPtr<mirror::Object> jni_this =
           stack_visitor->GetCurrentHandleScope(sizeof(void*))->GetReference(0);
       callback(jni_this, callback_context);
     }
@@ -1472,7 +1483,7 @@
       uint32_t value;
       success = stack_visitor->GetVReg(m, dex_reg, kReferenceVReg, &value);
       if (success) {
-        mirror::Object* o = reinterpret_cast<mirror::Object*>(value);
+        ObjPtr<mirror::Object> o = reinterpret_cast<mirror::Object*>(value);
         callback(o, callback_context);
         break;
       }
@@ -1603,9 +1614,9 @@
   for (auto it = list_.begin(); it != list_.end(); ) {
     Monitor* m = *it;
     // Disable the read barrier in GetObject() as this is called by GC.
-    mirror::Object* obj = m->GetObject<kWithoutReadBarrier>();
+    ObjPtr<mirror::Object> obj = m->GetObject<kWithoutReadBarrier>();
     // The object of a monitor can be null if we have deflated it.
-    mirror::Object* new_obj = obj != nullptr ? visitor->IsMarked(obj) : nullptr;
+    ObjPtr<mirror::Object> new_obj = obj != nullptr ? visitor->IsMarked(obj.Ptr()) : nullptr;
     if (new_obj == nullptr) {
       VLOG(monitor) << "freeing monitor " << m << " belonging to unmarked object "
                     << obj;
@@ -1650,7 +1661,7 @@
   return visitor.deflate_count_;
 }
 
-MonitorInfo::MonitorInfo(mirror::Object* obj) : owner_(nullptr), entry_count_(0) {
+MonitorInfo::MonitorInfo(ObjPtr<mirror::Object> obj) : owner_(nullptr), entry_count_(0) {
   DCHECK(obj != nullptr);
   LockWord lock_word = obj->GetLockWord(true);
   switch (lock_word.GetState()) {
diff --git a/runtime/monitor.h b/runtime/monitor.h
index c1f84e9..4187f27 100644
--- a/runtime/monitor.h
+++ b/runtime/monitor.h
@@ -30,6 +30,7 @@
 #include "base/mutex.h"
 #include "gc_root.h"
 #include "lock_word.h"
+#include "obj_ptr.h"
 #include "read_barrier_option.h"
 #include "runtime_callbacks.h"
 #include "thread_state.h"
@@ -64,62 +65,69 @@
   static void Init(uint32_t lock_profiling_threshold, uint32_t stack_dump_lock_profiling_threshold);
 
   // Return the thread id of the lock owner or 0 when there is no owner.
-  static uint32_t GetLockOwnerThreadId(mirror::Object* obj)
+  static uint32_t GetLockOwnerThreadId(ObjPtr<mirror::Object> obj)
       NO_THREAD_SAFETY_ANALYSIS;  // TODO: Reading lock owner without holding lock is racy.
 
   // NO_THREAD_SAFETY_ANALYSIS for mon->Lock.
-  static mirror::Object* MonitorEnter(Thread* thread, mirror::Object* obj, bool trylock)
-      EXCLUSIVE_LOCK_FUNCTION(obj)
+  static ObjPtr<mirror::Object> MonitorEnter(Thread* thread,
+                                             ObjPtr<mirror::Object> obj,
+                                             bool trylock)
+      EXCLUSIVE_LOCK_FUNCTION(obj.Ptr())
       NO_THREAD_SAFETY_ANALYSIS
       REQUIRES(!Roles::uninterruptible_)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // NO_THREAD_SAFETY_ANALYSIS for mon->Unlock.
-  static bool MonitorExit(Thread* thread, mirror::Object* obj)
+  static bool MonitorExit(Thread* thread, ObjPtr<mirror::Object> obj)
       NO_THREAD_SAFETY_ANALYSIS
       REQUIRES(!Roles::uninterruptible_)
       REQUIRES_SHARED(Locks::mutator_lock_)
-      UNLOCK_FUNCTION(obj);
+      UNLOCK_FUNCTION(obj.Ptr());
 
-  static void Notify(Thread* self, mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
+  static void Notify(Thread* self, ObjPtr<mirror::Object> obj)
+      REQUIRES_SHARED(Locks::mutator_lock_) {
     DoNotify(self, obj, false);
   }
-  static void NotifyAll(Thread* self, mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
+  static void NotifyAll(Thread* self, ObjPtr<mirror::Object> obj)
+      REQUIRES_SHARED(Locks::mutator_lock_) {
     DoNotify(self, obj, true);
   }
 
   // Object.wait().  Also called for class init.
   // NO_THREAD_SAFETY_ANALYSIS for mon->Wait.
-  static void Wait(Thread* self, mirror::Object* obj, int64_t ms, int32_t ns,
+  static void Wait(Thread* self,
+                   ObjPtr<mirror::Object> obj,
+                   int64_t ms,
+                   int32_t ns,
                    bool interruptShouldThrow, ThreadState why)
       REQUIRES_SHARED(Locks::mutator_lock_) NO_THREAD_SAFETY_ANALYSIS;
 
   static ThreadState FetchState(const Thread* thread,
-                                /* out */ mirror::Object** monitor_object,
+                                /* out */ ObjPtr<mirror::Object>* monitor_object,
                                 /* out */ uint32_t* lock_owner_tid)
       REQUIRES(!Locks::thread_suspend_count_lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Used to implement JDWP's ThreadReference.CurrentContendedMonitor.
-  static mirror::Object* GetContendedMonitor(Thread* thread)
+  static ObjPtr<mirror::Object> GetContendedMonitor(Thread* thread)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Calls 'callback' once for each lock held in the single stack frame represented by
   // the current state of 'stack_visitor'.
   // The abort_on_failure flag allows to not die when the state of the runtime is unorderly. This
   // is necessary when we have already aborted but want to dump the stack as much as we can.
-  static void VisitLocks(StackVisitor* stack_visitor, void (*callback)(mirror::Object*, void*),
-                         void* callback_context, bool abort_on_failure = true)
+  static void VisitLocks(StackVisitor* stack_visitor,
+                         void (*callback)(ObjPtr<mirror::Object>, void*),
+                         void* callback_context,
+                         bool abort_on_failure = true)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   static bool IsValidLockWord(LockWord lock_word);
 
   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  mirror::Object* GetObject() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return obj_.Read<kReadBarrierOption>();
-  }
+  ObjPtr<mirror::Object> GetObject() REQUIRES_SHARED(Locks::mutator_lock_);
 
-  void SetObject(mirror::Object* object);
+  void SetObject(ObjPtr<mirror::Object> object);
 
   Thread* GetOwner() const NO_THREAD_SAFETY_ANALYSIS {
     return owner_;
@@ -144,7 +152,7 @@
   // Not exclusive because ImageWriter calls this during a Heap::VisitObjects() that
   // does not allow a thread suspension in the middle. TODO: maybe make this exclusive.
   // NO_THREAD_SAFETY_ANALYSIS for monitor->monitor_lock_.
-  static bool Deflate(Thread* self, mirror::Object* obj)
+  static bool Deflate(Thread* self, ObjPtr<mirror::Object> obj)
       REQUIRES_SHARED(Locks::mutator_lock_) NO_THREAD_SAFETY_ANALYSIS;
 
 #ifndef __LP64__
@@ -162,9 +170,9 @@
 #endif
 
  private:
-  Monitor(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code)
+  Monitor(Thread* self, Thread* owner, ObjPtr<mirror::Object> obj, int32_t hash_code)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  Monitor(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code, MonitorId id)
+  Monitor(Thread* self, Thread* owner, ObjPtr<mirror::Object> obj, int32_t hash_code, MonitorId id)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Install the monitor into its object, may fail if another thread installs a different monitor
@@ -187,7 +195,7 @@
   // calling thread must own the lock or the owner must be suspended. There's a race with other
   // threads inflating the lock, installing hash codes and spurious failures. The caller should
   // re-read the lock word following the call.
-  static void Inflate(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code)
+  static void Inflate(Thread* self, Thread* owner, ObjPtr<mirror::Object> obj, int32_t hash_code)
       REQUIRES_SHARED(Locks::mutator_lock_)
       NO_THREAD_SAFETY_ANALYSIS;  // For m->Install(self)
 
@@ -198,7 +206,7 @@
                           uint32_t owner_dex_pc)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static void FailedUnlock(mirror::Object* obj,
+  static void FailedUnlock(ObjPtr<mirror::Object> obj,
                            uint32_t expected_owner_thread_id,
                            uint32_t found_owner_thread_id,
                            Monitor* mon)
@@ -224,7 +232,7 @@
       REQUIRES(!monitor_lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static void DoNotify(Thread* self, mirror::Object* obj, bool notify_all)
+  static void DoNotify(Thread* self, ObjPtr<mirror::Object> obj, bool notify_all)
       REQUIRES_SHARED(Locks::mutator_lock_) NO_THREAD_SAFETY_ANALYSIS;  // For mon->Notify.
 
   void Notify(Thread* self)
@@ -275,11 +283,11 @@
 
   // Support for systrace output of monitor operations.
   ALWAYS_INLINE static void AtraceMonitorLock(Thread* self,
-                                              mirror::Object* obj,
+                                              ObjPtr<mirror::Object> obj,
                                               bool is_wait)
       REQUIRES_SHARED(Locks::mutator_lock_);
   static void AtraceMonitorLockImpl(Thread* self,
-                                    mirror::Object* obj,
+                                    ObjPtr<mirror::Object> obj,
                                     bool is_wait)
       REQUIRES_SHARED(Locks::mutator_lock_);
   ALWAYS_INLINE static void AtraceMonitorUnlock();
@@ -375,7 +383,7 @@
   MonitorInfo() : owner_(nullptr), entry_count_(0) {}
   MonitorInfo(const MonitorInfo&) = default;
   MonitorInfo& operator=(const MonitorInfo&) = default;
-  explicit MonitorInfo(mirror::Object* o) REQUIRES(Locks::mutator_lock_);
+  explicit MonitorInfo(ObjPtr<mirror::Object> o) REQUIRES(Locks::mutator_lock_);
 
   Thread* owner_;
   size_t entry_count_;
diff --git a/runtime/monitor_objects_stack_visitor.cc b/runtime/monitor_objects_stack_visitor.cc
new file mode 100644
index 0000000..61f4159
--- /dev/null
+++ b/runtime/monitor_objects_stack_visitor.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "monitor_objects_stack_visitor.h"
+
+#include "obj_ptr-inl.h"
+#include "read_barrier-inl.h"
+#include "thread-current-inl.h"
+
+namespace art {
+
+bool MonitorObjectsStackVisitor::VisitFrame() {
+  ArtMethod* m = GetMethod();
+  if (m->IsRuntimeMethod()) {
+    return true;
+  }
+
+  VisitMethodResult vmrEntry = StartMethod(m, frame_count);
+  switch (vmrEntry) {
+    case VisitMethodResult::kContinueMethod:
+      break;
+    case VisitMethodResult::kSkipMethod:
+      return true;
+    case VisitMethodResult::kEndStackWalk:
+      return false;
+  }
+
+  if (frame_count == 0) {
+    // Top frame, check for blocked state.
+
+    ObjPtr<mirror::Object> monitor_object;
+    uint32_t lock_owner_tid;
+    ThreadState state = Monitor::FetchState(GetThread(),
+                                            &monitor_object,
+                                            &lock_owner_tid);
+    switch (state) {
+      case kWaiting:
+      case kTimedWaiting:
+        VisitWaitingObject(monitor_object, state);
+        break;
+      case kSleeping:
+        VisitSleepingObject(monitor_object);
+        break;
+
+      case kBlocked:
+      case kWaitingForLockInflation:
+        VisitBlockedOnObject(monitor_object, state, lock_owner_tid);
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  if (dump_locks) {
+    // Visit locks, but do not abort on errors. This could trigger a nested abort.
+    // Skip visiting locks if dump_locks is false as it would cause a bad_mutexes_held in
+    // RegTypeCache::RegTypeCache due to thread_list_lock.
+    Monitor::VisitLocks(this, VisitLockedObject, this, false);
+  }
+
+  ++frame_count;
+
+  VisitMethodResult vmrExit = EndMethod(m);
+  switch (vmrExit) {
+    case VisitMethodResult::kContinueMethod:
+    case VisitMethodResult::kSkipMethod:
+      return true;
+
+    case VisitMethodResult::kEndStackWalk:
+      return false;
+  }
+  LOG(FATAL) << "Unreachable";
+  UNREACHABLE();
+}
+
+void MonitorObjectsStackVisitor::VisitLockedObject(ObjPtr<mirror::Object> o, void* context) {
+  MonitorObjectsStackVisitor* self = reinterpret_cast<MonitorObjectsStackVisitor*>(context);
+  if (o != nullptr) {
+    if (kUseReadBarrier && Thread::Current()->GetIsGcMarking()) {
+      // We may call Thread::Dump() in the middle of the CC thread flip and this thread's stack
+      // may have not been flipped yet and "o" may be a from-space (stale) ref, in which case the
+      // IdentityHashCode call below will crash. So explicitly mark/forward it here.
+      o = ReadBarrier::Mark(o.Ptr());
+    }
+  }
+  self->VisitLockedObject(o);
+}
+
+}  // namespace art
diff --git a/runtime/monitor_objects_stack_visitor.h b/runtime/monitor_objects_stack_visitor.h
index 3968239..8e148aa 100644
--- a/runtime/monitor_objects_stack_visitor.h
+++ b/runtime/monitor_objects_stack_visitor.h
@@ -54,70 +54,7 @@
     kEndStackWalk,
   };
 
-  bool VisitFrame() final REQUIRES_SHARED(Locks::mutator_lock_) {
-    ArtMethod* m = GetMethod();
-    if (m->IsRuntimeMethod()) {
-      return true;
-    }
-
-    VisitMethodResult vmrEntry = StartMethod(m, frame_count);
-    switch (vmrEntry) {
-      case VisitMethodResult::kContinueMethod:
-        break;
-      case VisitMethodResult::kSkipMethod:
-        return true;
-      case VisitMethodResult::kEndStackWalk:
-        return false;
-    }
-
-    if (frame_count == 0) {
-      // Top frame, check for blocked state.
-
-      mirror::Object* monitor_object;
-      uint32_t lock_owner_tid;
-      ThreadState state = Monitor::FetchState(GetThread(),
-                                              &monitor_object,
-                                              &lock_owner_tid);
-      switch (state) {
-        case kWaiting:
-        case kTimedWaiting:
-          VisitWaitingObject(monitor_object, state);
-          break;
-        case kSleeping:
-          VisitSleepingObject(monitor_object);
-          break;
-
-        case kBlocked:
-        case kWaitingForLockInflation:
-          VisitBlockedOnObject(monitor_object, state, lock_owner_tid);
-          break;
-
-        default:
-          break;
-      }
-    }
-
-    if (dump_locks) {
-      // Visit locks, but do not abort on errors. This could trigger a nested abort.
-      // Skip visiting locks if dump_locks is false as it would cause a bad_mutexes_held in
-      // RegTypeCache::RegTypeCache due to thread_list_lock.
-      Monitor::VisitLocks(this, VisitLockedObject, this, false);
-    }
-
-    ++frame_count;
-
-    VisitMethodResult vmrExit = EndMethod(m);
-    switch (vmrExit) {
-      case VisitMethodResult::kContinueMethod:
-      case VisitMethodResult::kSkipMethod:
-        return true;
-
-      case VisitMethodResult::kEndStackWalk:
-        return false;
-    }
-    LOG(FATAL) << "Unreachable";
-    UNREACHABLE();
-  }
+  bool VisitFrame() final REQUIRES_SHARED(Locks::mutator_lock_);
 
  protected:
   virtual VisitMethodResult StartMethod(ArtMethod* m, size_t frame_nr)
@@ -125,31 +62,22 @@
   virtual VisitMethodResult EndMethod(ArtMethod* m)
       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
 
-  virtual void VisitWaitingObject(mirror::Object* obj, ThreadState state)
+  virtual void VisitWaitingObject(ObjPtr<mirror::Object> obj, ThreadState state)
       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
-  virtual void VisitSleepingObject(mirror::Object* obj)
+  virtual void VisitSleepingObject(ObjPtr<mirror::Object> obj)
       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
-  virtual void VisitBlockedOnObject(mirror::Object* obj, ThreadState state, uint32_t owner_tid)
+  virtual void VisitBlockedOnObject(ObjPtr<mirror::Object> obj,
+                                    ThreadState state,
+                                    uint32_t owner_tid)
       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
-  virtual void VisitLockedObject(mirror::Object* obj)
+  virtual void VisitLockedObject(ObjPtr<mirror::Object> obj)
       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
 
   size_t frame_count;
 
  private:
-  static void VisitLockedObject(mirror::Object* o, void* context)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    MonitorObjectsStackVisitor* self = reinterpret_cast<MonitorObjectsStackVisitor*>(context);
-    if (o != nullptr) {
-      if (kUseReadBarrier && Thread::Current()->GetIsGcMarking()) {
-        // We may call Thread::Dump() in the middle of the CC thread flip and this thread's stack
-        // may have not been flipped yet and "o" may be a from-space (stale) ref, in which case the
-        // IdentityHashCode call below will crash. So explicitly mark/forward it here.
-        o = ReadBarrier::Mark(o);
-      }
-    }
-    self->VisitLockedObject(o);
-  }
+  static void VisitLockedObject(ObjPtr<mirror::Object> o, void* context)
+      REQUIRES_SHARED(Locks::mutator_lock_);
 
   const bool dump_locks;
 };
diff --git a/runtime/monitor_pool.cc b/runtime/monitor_pool.cc
index cf5934b..b2b0024 100644
--- a/runtime/monitor_pool.cc
+++ b/runtime/monitor_pool.cc
@@ -105,7 +105,9 @@
   }
 }
 
-Monitor* MonitorPool::CreateMonitorInPool(Thread* self, Thread* owner, mirror::Object* obj,
+Monitor* MonitorPool::CreateMonitorInPool(Thread* self,
+                                          Thread* owner,
+                                          ObjPtr<mirror::Object> obj,
                                           int32_t hash_code)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   // We are gonna allocate, so acquire the writer lock.
diff --git a/runtime/monitor_pool.h b/runtime/monitor_pool.h
index c6b0b0b..4521a22 100644
--- a/runtime/monitor_pool.h
+++ b/runtime/monitor_pool.h
@@ -42,7 +42,10 @@
 #endif
   }
 
-  static Monitor* CreateMonitor(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code)
+  static Monitor* CreateMonitor(Thread* self,
+                                Thread* owner,
+                                ObjPtr<mirror::Object> obj,
+                                int32_t hash_code)
       REQUIRES_SHARED(Locks::mutator_lock_) {
 #ifndef __LP64__
     Monitor* mon = new Monitor(self, owner, obj, hash_code);
@@ -122,7 +125,10 @@
   // so ignore thead-safety analysis.
   void FreeInternal() NO_THREAD_SAFETY_ANALYSIS;
 
-  Monitor* CreateMonitorInPool(Thread* self, Thread* owner, mirror::Object* obj, int32_t hash_code)
+  Monitor* CreateMonitorInPool(Thread* self,
+                               Thread* owner,
+                               ObjPtr<mirror::Object> obj,
+                               int32_t hash_code)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   void ReleaseMonitorToPool(Thread* self, Monitor* monitor);
diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc
index a4f3df2..4a60c04 100644
--- a/runtime/runtime_callbacks_test.cc
+++ b/runtime/runtime_callbacks_test.cc
@@ -37,9 +37,9 @@
 #include "handle_scope-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
-#include "monitor.h"
+#include "monitor-inl.h"
 #include "nativehelper/scoped_local_ref.h"
-#include "obj_ptr.h"
+#include "obj_ptr-inl.h"
 #include "runtime.h"
 #include "scoped_thread_state_change-inl.h"
 #include "thread-inl.h"
@@ -443,7 +443,8 @@
   }
 
   struct Callback : public MonitorCallback {
-    bool IsInterestingObject(mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+    bool IsInterestingObject(ObjPtr<mirror::Object> obj)
+        REQUIRES_SHARED(art::Locks::mutator_lock_) {
       if (!obj->IsClass()) {
         return false;
       }
@@ -453,7 +454,8 @@
       return ref_ == test;
     }
 
-    void SetInterestingObject(mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+    void SetInterestingObject(ObjPtr<mirror::Object> obj)
+        REQUIRES_SHARED(art::Locks::mutator_lock_) {
       std::lock_guard<std::mutex> lock(ref_guard_);
       ObjPtr<mirror::Class> k = obj->AsClass();
       ref_ = { &k->GetDexFile(), k->GetDexClassDefIndex() };
@@ -501,11 +503,11 @@
     {
       ScopedObjectAccess soa(self);
       cb_.SetInterestingObject(
-          soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections).Ptr());
+          soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections));
       Monitor::Wait(
           self,
           // Just a random class
-          soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections).Ptr(),
+          soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections),
           /*ms=*/0,
           /*ns=*/0,
           /*interruptShouldThrow=*/false,
diff --git a/runtime/thread.cc b/runtime/thread.cc
index bdbb697..ffdea8a 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2014,17 +2014,17 @@
     return VisitMethodResult::kContinueMethod;
   }
 
-  void VisitWaitingObject(mirror::Object* obj, ThreadState state ATTRIBUTE_UNUSED)
+  void VisitWaitingObject(ObjPtr<mirror::Object> obj, ThreadState state ATTRIBUTE_UNUSED)
       override
       REQUIRES_SHARED(Locks::mutator_lock_) {
     PrintObject(obj, "  - waiting on ", ThreadList::kInvalidThreadId);
   }
-  void VisitSleepingObject(mirror::Object* obj)
+  void VisitSleepingObject(ObjPtr<mirror::Object> obj)
       override
       REQUIRES_SHARED(Locks::mutator_lock_) {
     PrintObject(obj, "  - sleeping on ", ThreadList::kInvalidThreadId);
   }
-  void VisitBlockedOnObject(mirror::Object* obj,
+  void VisitBlockedOnObject(ObjPtr<mirror::Object> obj,
                             ThreadState state,
                             uint32_t owner_tid)
       override
@@ -2045,13 +2045,13 @@
     }
     PrintObject(obj, msg, owner_tid);
   }
-  void VisitLockedObject(mirror::Object* obj)
+  void VisitLockedObject(ObjPtr<mirror::Object> obj)
       override
       REQUIRES_SHARED(Locks::mutator_lock_) {
     PrintObject(obj, "  - locked ", ThreadList::kInvalidThreadId);
   }
 
-  void PrintObject(mirror::Object* obj,
+  void PrintObject(ObjPtr<mirror::Object> obj,
                    const char* msg,
                    uint32_t owner_tid) REQUIRES_SHARED(Locks::mutator_lock_) {
     if (obj == nullptr) {
@@ -2062,7 +2062,7 @@
         // Getting the identity hashcode here would result in lock inflation and suspension of the
         // current thread, which isn't safe if this is the only runnable thread.
         os << msg << StringPrintf("<@addr=0x%" PRIxPTR "> (a %s)",
-                                  reinterpret_cast<intptr_t>(obj),
+                                  reinterpret_cast<intptr_t>(obj.Ptr()),
                                   obj->PrettyTypeOf().c_str());
       } else {
         // - waiting on <0x6008c468> (a java.lang.Class<java.lang.ref.ReferenceQueue>)
@@ -3006,24 +3006,24 @@
       return VisitMethodResult::kContinueMethod;
     }
 
-    void VisitWaitingObject(mirror::Object* obj, ThreadState state ATTRIBUTE_UNUSED)
+    void VisitWaitingObject(ObjPtr<mirror::Object> obj, ThreadState state ATTRIBUTE_UNUSED)
         override
         REQUIRES_SHARED(Locks::mutator_lock_) {
       wait_jobject_.reset(soaa_.AddLocalReference<jobject>(obj));
     }
-    void VisitSleepingObject(mirror::Object* obj)
+    void VisitSleepingObject(ObjPtr<mirror::Object> obj)
         override
         REQUIRES_SHARED(Locks::mutator_lock_) {
       wait_jobject_.reset(soaa_.AddLocalReference<jobject>(obj));
     }
-    void VisitBlockedOnObject(mirror::Object* obj,
+    void VisitBlockedOnObject(ObjPtr<mirror::Object> obj,
                               ThreadState state ATTRIBUTE_UNUSED,
                               uint32_t owner_tid ATTRIBUTE_UNUSED)
         override
         REQUIRES_SHARED(Locks::mutator_lock_) {
       block_jobject_.reset(soaa_.AddLocalReference<jobject>(obj));
     }
-    void VisitLockedObject(mirror::Object* obj)
+    void VisitLockedObject(ObjPtr<mirror::Object> obj)
         override
         REQUIRES_SHARED(Locks::mutator_lock_) {
       frame_lock_objects_.emplace_back(soaa_.Env(), soaa_.AddLocalReference<jobject>(obj));
diff --git a/test/167-visit-locks/visit_locks.cc b/test/167-visit-locks/visit_locks.cc
index 8955f5a..f72b577 100644
--- a/test/167-visit-locks/visit_locks.cc
+++ b/test/167-visit-locks/visit_locks.cc
@@ -27,6 +27,7 @@
 #include "mirror/object-inl.h"
 #include "mirror/string.h"
 #include "monitor.h"
+#include "obj_ptr-inl.h"
 #include "scoped_thread_state_change-inl.h"
 #include "stack.h"
 #include "thread-current-inl.h"
@@ -59,7 +60,7 @@
       return true;
     }
 
-    static void Callback(mirror::Object* obj, void*) REQUIRES_SHARED(Locks::mutator_lock_) {
+    static void Callback(ObjPtr<mirror::Object> obj, void*) REQUIRES_SHARED(Locks::mutator_lock_) {
       CHECK(obj != nullptr);
       CHECK(obj->IsString());
       std::cerr << obj->AsString()->ToModifiedUtf8() << std::endl;