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,