Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: base/memory/weak_ptr.cc

Issue 2963623002: Make base::WeakPtr::Get() fast (Closed)
Patch Set: Move WeakReference::Flag::Invalidate out-of-line; it's only called from WeakReferenceOwner::Invalid… Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/weak_ptr.h" 5 #include "base/memory/weak_ptr.h"
6 6
7 #include "base/debug/leak_annotations.h"
8
7 namespace base { 9 namespace base {
8 namespace internal { 10 namespace internal {
9 11
10 WeakReference::Flag::Flag() : is_valid_(true) { 12 static constexpr uintptr_t kTrueMask = ~static_cast<uintptr_t>(0);
gab 2017/07/18 20:31:08 rm "static": it's redundant at file-scope level
hans 2017/07/19 08:08:23 Done.
13
14 WeakReference::Flag::Flag() : is_valid_(kTrueMask) {
15 #if DCHECK_IS_ON()
11 // Flags only become bound when checked for validity, or invalidated, 16 // Flags only become bound when checked for validity, or invalidated,
12 // so that we can check that later validity/invalidation operations on 17 // so that we can check that later validity/invalidation operations on
13 // the same Flag take place on the same sequenced thread. 18 // the same Flag take place on the same sequenced thread.
14 sequence_checker_.DetachFromSequence(); 19 sequence_checker_.DetachFromSequence();
20 #endif
21 }
22
23 WeakReference::Flag::Flag(WeakReference::Flag::NullFlagTag) : is_valid_(false) {
24 // There is no need for sequence_checker_.DetachFromSequence() because the
25 // null flag doesn't participate in the sequence checks. See DCHECK in
26 // Invalidate() and IsValid().
27
28 // Keep the object alive perpetually, even when there are no references to it.
29 AddRef();
30 }
31
32 WeakReference::Flag* WeakReference::Flag::NullFlag() {
33 ANNOTATE_SCOPED_MEMORY_LEAK;
34 static Flag* g_null_flag = new Flag(kNullFlagTag);
35 return g_null_flag;
15 } 36 }
16 37
17 void WeakReference::Flag::Invalidate() { 38 void WeakReference::Flag::Invalidate() {
39 #if DCHECK_IS_ON()
40 if (this == NullFlag()) {
41 // The Null Flag does not participate in the sequence checks below.
42 // Since its state never changes, it can be accessed from any thread.
43 DCHECK(!is_valid_);
44 return;
45 }
18 // The flag being invalidated with a single ref implies that there are no 46 // The flag being invalidated with a single ref implies that there are no
19 // weak pointers in existence. Allow deletion on other thread in this case. 47 // weak pointers in existence. Allow deletion on other thread in this
48 // case.
20 DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) 49 DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef())
21 << "WeakPtrs must be invalidated on the same sequenced thread."; 50 << "WeakPtrs must be invalidated on the same sequenced thread.";
22 is_valid_ = false; 51 #endif
52 is_valid_ = 0;
23 } 53 }
24 54
25 bool WeakReference::Flag::IsValid() const { 55 WeakReference::Flag::~Flag() {}
26 DCHECK(sequence_checker_.CalledOnValidSequence()) 56
27 << "WeakPtrs must be checked on the same sequenced thread."; 57 WeakReference::WeakReference() : flag_(Flag::NullFlag()) {}
28 return is_valid_; 58
59 WeakReference::~WeakReference() {}
60
61 WeakReference::WeakReference(const Flag* flag) : flag_(flag) {}
62
63 WeakReference::WeakReference(WeakReference&& other)
64 : flag_(std::move(other.flag_)) {
65 other.flag_ = Flag::NullFlag();
29 } 66 }
30 67
31 WeakReference::Flag::~Flag() {
32 }
33
34 WeakReference::WeakReference() {
35 }
36
37 WeakReference::WeakReference(const Flag* flag) : flag_(flag) {
38 }
39
40 WeakReference::~WeakReference() {
41 }
42
43 WeakReference::WeakReference(WeakReference&& other) = default;
44
45 WeakReference::WeakReference(const WeakReference& other) = default; 68 WeakReference::WeakReference(const WeakReference& other) = default;
46 69
47 bool WeakReference::is_valid() const { return flag_.get() && flag_->IsValid(); } 70 WeakReferenceOwner::WeakReferenceOwner()
48 71 : flag_(WeakReference::Flag::NullFlag()) {}
49 WeakReferenceOwner::WeakReferenceOwner() {
50 }
51 72
52 WeakReferenceOwner::~WeakReferenceOwner() { 73 WeakReferenceOwner::~WeakReferenceOwner() {
53 Invalidate(); 74 Invalidate();
54 } 75 }
55 76
56 WeakReference WeakReferenceOwner::GetRef() const { 77 WeakReference WeakReferenceOwner::GetRef() const {
57 // If we hold the last reference to the Flag then create a new one. 78 // If we hold the last reference to the Flag then create a new one.
58 if (!HasRefs()) 79 if (!HasRefs())
59 flag_ = new WeakReference::Flag(); 80 flag_ = new WeakReference::Flag();
60 81
61 return WeakReference(flag_.get()); 82 return WeakReference(flag_.get());
62 } 83 }
63 84
64 void WeakReferenceOwner::Invalidate() { 85 void WeakReferenceOwner::Invalidate() {
65 if (flag_.get()) { 86 if (flag_ != WeakReference::Flag::NullFlag()) {
66 flag_->Invalidate(); 87 flag_->Invalidate();
67 flag_ = NULL; 88 flag_ = WeakReference::Flag::NullFlag();
68 } 89 }
69 } 90 }
70 91
71 WeakPtrBase::WeakPtrBase() : ptr_(0) {} 92 WeakPtrBase::WeakPtrBase() : ptr_(0) {}
72 93
73 WeakPtrBase::~WeakPtrBase() {} 94 WeakPtrBase::~WeakPtrBase() {}
74 95
75 WeakPtrBase::WeakPtrBase(const WeakReference& ref, uintptr_t ptr) 96 WeakPtrBase::WeakPtrBase(const WeakReference& ref, uintptr_t ptr)
76 : ref_(ref), ptr_(ptr) {} 97 : ref_(ref), ptr_(ptr) {}
77 98
78 WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {} 99 WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {}
79 100
80 WeakPtrFactoryBase::~WeakPtrFactoryBase() { 101 WeakPtrFactoryBase::~WeakPtrFactoryBase() {
81 ptr_ = 0; 102 ptr_ = 0;
82 } 103 }
83 104
84 } // namespace internal 105 } // namespace internal
85 } // namespace base 106 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698