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

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

Issue 2963623002: Make base::WeakPtr::Get() fast (Closed)
Patch Set: static_assert in the converting copy ctor and update no-compile test 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);
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
15 } 21 }
16 22
17 void WeakReference::Flag::Invalidate() { 23 WeakReference::Flag::Flag(WeakReference::Flag::NullFlagTag) : is_valid_(false) {
18 // The flag being invalidated with a single ref implies that there are no 24 // There is no need for sequence_checker_.DetachFromSequence() because the
19 // weak pointers in existence. Allow deletion on other thread in this case. 25 // null flag doesn't participate in the sequence checks.
Nico 2017/06/28 14:54:09 Maybe add ", see DCHECK in Invalidate()"
hans 2017/06/28 20:37:35 Done.
20 DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) 26
21 << "WeakPtrs must be invalidated on the same sequenced thread."; 27 AddRef(); // Stayin' alive.
Nico 2017/06/28 14:54:09 Remove comment, software is serious business. (Or
hans 2017/06/28 20:37:34 Done.
22 is_valid_ = false;
23 } 28 }
24 29
25 bool WeakReference::Flag::IsValid() const { 30 WeakReference::Flag* WeakReference::Flag::nullFlag() {
26 DCHECK(sequence_checker_.CalledOnValidSequence()) 31 ANNOTATE_SCOPED_MEMORY_LEAK;
Nico 2017/06/28 14:54:09 I don't think this is needed, lsan doesn't report
hans 2017/06/28 20:37:34 Done.
27 << "WeakPtrs must be checked on the same sequenced thread."; 32 static Flag* g_null_flag = new Flag(kNullFlagTag);
Nico 2017/06/28 14:54:09 If you wanted you could use CR_DEFINE_STATIC_LOCAL
hans 2017/06/28 20:37:35 I don't think that would provide much value really
28 return is_valid_; 33 return g_null_flag;
29 } 34 }
30 35
31 WeakReference::Flag::~Flag() { 36 WeakReference::Flag::~Flag() {}
32 }
33 37
34 WeakReference::WeakReference() { 38 WeakReference::WeakReference() : flag_(Flag::nullFlag()) {}
35 }
36
37 WeakReference::WeakReference(const Flag* flag) : flag_(flag) {
38 }
39 39
40 WeakReference::~WeakReference() { 40 WeakReference::~WeakReference() {
41 } 41 }
42 42
43 WeakReference::WeakReference(WeakReference&& other) = default; 43 WeakReference::WeakReference(const Flag* flag) : flag_(flag) {}
44
45 WeakReference::WeakReference(WeakReference&& other)
46 : flag_(std::move(other.flag_)) {
47 other.flag_ = Flag::nullFlag();
48 }
44 49
45 WeakReference::WeakReference(const WeakReference& other) = default; 50 WeakReference::WeakReference(const WeakReference& other) = default;
46 51
47 bool WeakReference::is_valid() const { return flag_.get() && flag_->IsValid(); } 52 WeakReferenceOwner::WeakReferenceOwner()
48 53 : flag_(WeakReference::Flag::nullFlag()) {}
49 WeakReferenceOwner::WeakReferenceOwner() {
50 }
51 54
52 WeakReferenceOwner::~WeakReferenceOwner() { 55 WeakReferenceOwner::~WeakReferenceOwner() {
53 Invalidate(); 56 Invalidate();
54 } 57 }
55 58
56 WeakReference WeakReferenceOwner::GetRef() const { 59 WeakReference WeakReferenceOwner::GetRef() const {
57 // If we hold the last reference to the Flag then create a new one. 60 // If we hold the last reference to the Flag then create a new one.
58 if (!HasRefs()) 61 if (!HasRefs())
59 flag_ = new WeakReference::Flag(); 62 flag_ = new WeakReference::Flag();
60 63
61 return WeakReference(flag_.get()); 64 return WeakReference(flag_.get());
62 } 65 }
63 66
64 void WeakReferenceOwner::Invalidate() { 67 void WeakReferenceOwner::Invalidate() {
65 if (flag_.get()) { 68 flag_->Invalidate();
66 flag_->Invalidate(); 69 flag_ = WeakReference::Flag::nullFlag();
67 flag_ = NULL;
68 }
69 } 70 }
70 71
71 WeakPtrBase::WeakPtrBase() { 72 WeakPtrBase::WeakPtrBase() : ptr_(0) {}
72 }
73 73
74 WeakPtrBase::~WeakPtrBase() { 74 WeakPtrBase::~WeakPtrBase() {}
75 }
76 75
77 WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) { 76 WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) {
78 } 77 }
79 78
79 WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {}
80
81 WeakPtrFactoryBase::~WeakPtrFactoryBase() {
82 ptr_ = 0;
83 }
84
80 } // namespace internal 85 } // namespace internal
81 } // namespace base 86 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698