ART: Change ObjPtr validation

Do not validate for copy constructor and assignment. This is the
majority of overhead in practice. Invalid ObjPtrs will still be
detected when they are used.

Bug: 35644369
Test: m test-art-host
Change-Id: I74378afdf69164046d854a0804465b83592f0873
diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h
index 4162873..9a66983 100644
--- a/runtime/obj_ptr.h
+++ b/runtime/obj_ptr.h
@@ -28,6 +28,10 @@
 
 constexpr bool kObjPtrPoisoning = kIsDebugBuild;
 
+// It turns out that most of the performance overhead comes from copying. Don't validate for now.
+// This defers finding stale ObjPtr objects until they are used.
+constexpr bool kObjPtrPoisoningValidateOnCopy = false;
+
 // Value type representing a pointer to a mirror::Object of type MirrorType
 // Since the cookie is thread based, it is not safe to share an ObjPtr between threads.
 template<class MirrorType>
@@ -63,14 +67,18 @@
             typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
   ALWAYS_INLINE ObjPtr(const ObjPtr<Type>& other)  // NOLINT
       REQUIRES_SHARED(Locks::mutator_lock_)
-      : reference_(Encode(static_cast<MirrorType*>(other.Ptr()))) {
+      : reference_(kObjPtrPoisoningValidateOnCopy
+                       ? Encode(static_cast<MirrorType*>(other.Ptr()))
+                       : other.reference_) {
   }
 
   template <typename Type,
             typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
   ALWAYS_INLINE ObjPtr& operator=(const ObjPtr<Type>& other)
       REQUIRES_SHARED(Locks::mutator_lock_) {
-    reference_ = Encode(static_cast<MirrorType*>(other.Ptr()));
+    reference_ = kObjPtrPoisoningValidateOnCopy
+                     ? Encode(static_cast<MirrorType*>(other.Ptr()))
+                     : other.reference_;
     return *this;
   }
 
@@ -160,6 +168,8 @@
   ALWAYS_INLINE static uintptr_t Encode(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_);
   // The encoded reference and cookie.
   uintptr_t reference_;
+
+  template <class T> friend class ObjPtr;  // Required for reference_ access in copy cons/operator.
 };
 
 static_assert(std::is_trivially_copyable<ObjPtr<void>>::value,