Index: base/memory/weak_ptr.h |
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h |
index f80e4f26123f7048b4f6bf1310104f5955a6b9c8..5c9ed545d726a1b8d7f5c16b7ff2721f64a9dfcc 100644 |
--- a/base/memory/weak_ptr.h |
+++ b/base/memory/weak_ptr.h |
@@ -96,59 +96,16 @@ class BASE_EXPORT WeakReference { |
public: |
Flag(); |
- // Get a pointer to the "Null Flag", a sentinel object used by WeakReference |
- // objects that don't point to a valid Flag, either because they're default |
- // constructed or because they have been invalidated. This can be used like |
- // any other Flag object, but it is invalidated already from the start, and |
- // its refcount will never reach zero. |
- static Flag* NullFlag(); |
- |
- void Invalidate() { |
-#if DCHECK_IS_ON() |
- if (this == NullFlag()) { |
- // The Null Flag does not participate in the sequence checks below. |
- // Since its state never changes, it can be accessed from any thread. |
- DCHECK(!is_valid_); |
- return; |
- } |
- // The flag being invalidated with a single ref implies that there are no |
- // weak pointers in existence. Allow deletion on other thread in this |
- // case. |
- DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) |
- << "WeakPtrs must be invalidated on the same sequenced thread."; |
-#endif |
- is_valid_ = 0; |
- } |
- |
- // Returns a pointer-sized bitmask of all 1s if valid or all 0s otherwise. |
- uintptr_t IsValid() const { |
-#if DCHECK_IS_ON() |
- if (this == NullFlag()) { |
- // The Null Flag does not participate in the sequence checks below. |
- // Since its state never changes, it can be accessed from any thread. |
- DCHECK(!is_valid_); |
- return 0; |
- } |
- DCHECK(sequence_checker_.CalledOnValidSequence()) |
- << "WeakPtrs must be checked on the same sequenced thread."; |
-#endif |
- return is_valid_; |
- } |
+ void Invalidate(); |
+ bool IsValid() const; |
private: |
friend class base::RefCountedThreadSafe<Flag>; |
- enum NullFlagTag { kNullFlagTag }; |
- Flag(NullFlagTag); |
- |
~Flag(); |
- uintptr_t is_valid_; |
-#if DCHECK_IS_ON() |
- // Even if SequenceChecker is an empty class in non-dcheck builds, it still |
- // takes up space in the class. |
SequenceChecker sequence_checker_; |
-#endif |
+ bool is_valid_; |
}; |
WeakReference(); |
@@ -160,11 +117,9 @@ class BASE_EXPORT WeakReference { |
WeakReference& operator=(WeakReference&& other) = default; |
WeakReference& operator=(const WeakReference& other) = default; |
- uintptr_t is_valid() const { return flag_->IsValid(); } |
+ bool is_valid() const; |
private: |
- // Note: To avoid null-checks, flag_ always points to either Flag::NullFlag() |
- // or some other object. |
scoped_refptr<const Flag> flag_; |
}; |
@@ -176,7 +131,7 @@ class BASE_EXPORT WeakReferenceOwner { |
WeakReference GetRef() const; |
bool HasRefs() const { |
- return flag_ != WeakReference::Flag::NullFlag() && !flag_->HasOneRef(); |
+ return flag_.get() && !flag_->HasOneRef(); |
} |
void Invalidate(); |
@@ -281,10 +236,7 @@ class WeakPtr : public internal::WeakPtrBase { |
} |
T* get() const { |
- // Intentionally bitwise and; see command on Flag::IsValid(). This provides |
- // a fast way of conditionally retrieving the pointer, and conveniently sets |
- // EFLAGS for any null-check performed by the caller. |
- return reinterpret_cast<T*>(ref_.is_valid() & ptr_); |
+ return ref_.is_valid() ? reinterpret_cast<T*>(ptr_) : nullptr; |
} |
T& operator*() const { |