V8  latest master commit
V8 is Google's open source JavaScript engine
persistent.h
Go to the documentation of this file.
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef INCLUDE_CPPGC_PERSISTENT_H_
6 #define INCLUDE_CPPGC_PERSISTENT_H_
7 
8 #include <type_traits>
9 
12 #include "cppgc/source-location.h"
13 #include "cppgc/type-traits.h"
14 #include "cppgc/visitor.h"
15 #include "v8config.h" // NOLINT(build/include_directory)
16 
17 namespace cppgc {
18 namespace internal {
19 
20 // The basic class from which all Persistent classes are generated.
21 template <typename T, typename WeaknessPolicy, typename LocationPolicy,
22  typename CheckingPolicy>
23 class BasicPersistent : public LocationPolicy,
24  private WeaknessPolicy,
25  private CheckingPolicy {
26  public:
27  using typename WeaknessPolicy::IsStrongPersistent;
28  using PointeeType = T;
29 
30  // Null-state/sentinel constructors.
31  BasicPersistent( // NOLINT
33  : LocationPolicy(loc) {}
34 
35  BasicPersistent(std::nullptr_t, // NOLINT
37  : LocationPolicy(loc) {}
38 
39  BasicPersistent( // NOLINT
41  : LocationPolicy(loc), raw_(s) {}
42 
43  // Raw value contstructors.
44  BasicPersistent(T* raw, // NOLINT
46  : LocationPolicy(loc), raw_(raw) {
47  if (!IsValid()) return;
48  node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode(
49  this, &BasicPersistent::Trace);
50  this->CheckPointer(Get());
51  }
52 
53  BasicPersistent(T& raw, // NOLINT
55  : BasicPersistent(&raw, loc) {}
56 
57  // Copy ctor.
60  : BasicPersistent(other.Get(), loc) {}
61 
62  // Heterogeneous ctor.
63  template <typename U, typename OtherWeaknessPolicy,
64  typename OtherLocationPolicy, typename OtherCheckingPolicy,
65  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
66  BasicPersistent( // NOLINT
67  const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
68  OtherCheckingPolicy>& other,
70  : BasicPersistent(other.Get(), loc) {}
71 
72  // Move ctor. The heterogeneous move ctor is not supported since e.g.
73  // persistent can't reuse persistent node from weak persistent.
75  BasicPersistent&& other,
76  const SourceLocation& loc = SourceLocation::Current()) noexcept
77  : LocationPolicy(std::move(other)),
78  raw_(std::move(other.raw_)),
79  node_(std::move(other.node_)) {
80  if (!IsValid()) return;
81  node_->UpdateOwner(this);
82  other.raw_ = nullptr;
83  other.node_ = nullptr;
84  this->CheckPointer(Get());
85  }
86 
87  // Constructor from member.
88  template <typename U, typename MemberBarrierPolicy,
89  typename MemberWeaknessTag, typename MemberCheckingPolicy,
90  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
91  BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy, // NOLINT
92  MemberWeaknessTag, MemberCheckingPolicy>
93  member,
95  : BasicPersistent(member.Get(), loc) {}
96 
98 
99  // Copy assignment.
101  return operator=(other.Get());
102  }
103 
104  template <typename U, typename OtherWeaknessPolicy,
105  typename OtherLocationPolicy, typename OtherCheckingPolicy,
106  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
108  const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
109  OtherCheckingPolicy>& other) {
110  return operator=(other.Get());
111  }
112 
113  // Move assignment.
115  if (this == &other) return *this;
116  Clear();
117  LocationPolicy::operator=(std::move(other));
118  raw_ = std::move(other.raw_);
119  node_ = std::move(other.node_);
120  if (!IsValid()) return *this;
121  node_->UpdateOwner(this);
122  other.raw_ = nullptr;
123  other.node_ = nullptr;
124  this->CheckPointer(Get());
125  return *this;
126  }
127 
128  // Assignment from member.
129  template <typename U, typename MemberBarrierPolicy,
130  typename MemberWeaknessTag, typename MemberCheckingPolicy,
131  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
133  internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
134  MemberCheckingPolicy>
135  member) {
136  return operator=(member.Get());
137  }
138 
140  Assign(other);
141  return *this;
142  }
143 
144  BasicPersistent& operator=(std::nullptr_t) {
145  Clear();
146  return *this;
147  }
148 
150  Assign(s);
151  return *this;
152  }
153 
154  explicit operator bool() const { return Get(); }
155  operator T*() const { return Get(); }
156  T* operator->() const { return Get(); }
157  T& operator*() const { return *Get(); }
158 
159  T* Get() const { return raw_; }
160 
161  void Clear() { Assign(nullptr); }
162 
163  T* Release() {
164  T* result = Get();
165  Clear();
166  return result;
167  }
168 
169  private:
170  static void Trace(Visitor* v, const void* ptr) {
171  const auto* persistent = static_cast<const BasicPersistent*>(ptr);
172  v->TraceRoot(*persistent, persistent->Location());
173  }
174 
175  bool IsValid() const {
176  // Ideally, handling kSentinelPointer would be done by the embedder. On the
177  // other hand, having Persistent aware of it is beneficial since no node
178  // gets wasted.
179  return raw_ != nullptr && raw_ != kSentinelPointer;
180  }
181 
182  void Assign(T* ptr) {
183  if (IsValid()) {
184  if (ptr && ptr != kSentinelPointer) {
185  // Simply assign the pointer reusing the existing node.
186  raw_ = ptr;
187  this->CheckPointer(ptr);
188  return;
189  }
190  WeaknessPolicy::GetPersistentRegion(raw_).FreeNode(node_);
191  node_ = nullptr;
192  }
193  raw_ = ptr;
194  if (!IsValid()) return;
195  node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode(
196  this, &BasicPersistent::Trace);
197  this->CheckPointer(Get());
198  }
199 
200  T* raw_ = nullptr;
201  PersistentNode* node_ = nullptr;
202 };
203 
204 template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
205  typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
206  typename LocationPolicy2, typename CheckingPolicy2>
207 bool operator==(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
208  CheckingPolicy1>& p1,
209  const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
210  CheckingPolicy2>& p2) {
211  return p1.Get() == p2.Get();
212 }
213 
214 template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
215  typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
216  typename LocationPolicy2, typename CheckingPolicy2>
217 bool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
218  CheckingPolicy1>& p1,
219  const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
220  CheckingPolicy2>& p2) {
221  return !(p1 == p2);
222 }
223 
224 template <typename T1, typename PersistentWeaknessPolicy,
225  typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
226  typename T2, typename MemberWriteBarrierPolicy,
227  typename MemberWeaknessTag, typename MemberCheckingPolicy>
228 bool operator==(const BasicPersistent<T1, PersistentWeaknessPolicy,
229  PersistentLocationPolicy,
230  PersistentCheckingPolicy>& p,
231  BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
232  MemberCheckingPolicy>
233  m) {
234  return p.Get() == m.Get();
235 }
236 
237 template <typename T1, typename PersistentWeaknessPolicy,
238  typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
239  typename T2, typename MemberWriteBarrierPolicy,
240  typename MemberWeaknessTag, typename MemberCheckingPolicy>
241 bool operator!=(const BasicPersistent<T1, PersistentWeaknessPolicy,
242  PersistentLocationPolicy,
243  PersistentCheckingPolicy>& p,
244  BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
245  MemberCheckingPolicy>
246  m) {
247  return !(p == m);
248 }
249 
250 template <typename T1, typename MemberWriteBarrierPolicy,
251  typename MemberWeaknessTag, typename MemberCheckingPolicy,
252  typename T2, typename PersistentWeaknessPolicy,
253  typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
254 bool operator==(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
255  MemberCheckingPolicy>
256  m,
257  const BasicPersistent<T1, PersistentWeaknessPolicy,
258  PersistentLocationPolicy,
259  PersistentCheckingPolicy>& p) {
260  return m.Get() == p.Get();
261 }
262 
263 template <typename T1, typename MemberWriteBarrierPolicy,
264  typename MemberWeaknessTag, typename MemberCheckingPolicy,
265  typename T2, typename PersistentWeaknessPolicy,
266  typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
267 bool operator!=(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
268  MemberCheckingPolicy>
269  m,
270  const BasicPersistent<T1, PersistentWeaknessPolicy,
271  PersistentLocationPolicy,
272  PersistentCheckingPolicy>& p) {
273  return !(m == p);
274 }
275 
276 template <typename T, typename LocationPolicy, typename CheckingPolicy>
277 struct IsWeak<BasicPersistent<T, internal::WeakPersistentPolicy, LocationPolicy,
278  CheckingPolicy>> : std::true_type {};
279 } // namespace internal
280 
288 template <typename T>
289 using Persistent =
291 
298 template <typename T>
299 using WeakPersistent =
301 
302 } // namespace cppgc
303 
304 #endif // INCLUDE_CPPGC_PERSISTENT_H_
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(const BasicPersistent< U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy > &other, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:66
cppgc::internal::operator!=
bool operator!=(BasicMember< T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1 > member1, BasicMember< T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2 > member2)
Definition: member.h:159
visitor.h
cppgc::internal::BasicPersistent::Clear
void Clear()
Definition: persistent.h:161
cppgc::internal::IsWeak
Definition: type-traits.h:26
cppgc::internal::BasicPersistent::~BasicPersistent
~BasicPersistent()
Definition: persistent.h:97
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(std::nullptr_t, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:35
cppgc::SourceLocation
Definition: source-location.h:28
cppgc::internal::WeakPersistentPolicy
Definition: pointer-policies.h:99
cppgc::internal::SentinelPointer
Definition: pointer-policies.h:116
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(const BasicPersistent< U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy > &other)
Definition: persistent.h:107
cppgc::Visitor::TraceRoot
void TraceRoot(const Persistent &p, const SourceLocation &loc)
Definition: visitor.h:57
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(T &raw, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:53
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:31
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(T *raw, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:44
persistent-node.h
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(const BasicPersistent &other)
Definition: persistent.h:100
cppgc::internal::PersistentNode::UpdateOwner
void UpdateOwner(void *owner)
Definition: persistent-node.h:42
cppgc::internal::BasicPersistent
Definition: pointer-policies.h:109
cppgc
Definition: allocation.h:18
v8config.h
cppgc::internal::BasicMember
Definition: pointer-policies.h:112
cppgc::internal::BasicPersistent::operator->
T * operator->() const
Definition: persistent.h:156
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(internal::BasicMember< U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy > member, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:91
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(BasicPersistent &&other, const SourceLocation &loc=SourceLocation::Current()) noexcept
Definition: persistent.h:74
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(BasicPersistent &&other)
Definition: persistent.h:114
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(std::nullptr_t)
Definition: persistent.h:144
pointer-policies.h
cppgc::internal::BasicPersistent::operator*
T & operator*() const
Definition: persistent.h:157
cppgc::internal::operator==
bool operator==(BasicMember< T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1 > member1, BasicMember< T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2 > member2)
Definition: member.h:149
cppgc::Visitor
Definition: visitor.h:27
cppgc::internal::BasicPersistent::Release
T * Release()
Definition: persistent.h:163
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(SentinelPointer s, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:39
cppgc::kSentinelPointer
constexpr internal::SentinelPointer kSentinelPointer
Definition: pointer-policies.h:129
cppgc::internal::BasicPersistent::PointeeType
T PointeeType
Definition: persistent.h:28
type-traits.h
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(T *other)
Definition: persistent.h:139
cppgc::SourceLocation::Current
static constexpr SourceLocation Current()
Definition: source-location.h:37
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(internal::BasicMember< U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy > member)
Definition: persistent.h:132
cppgc::internal::BasicPersistent::BasicPersistent
BasicPersistent(const BasicPersistent &other, const SourceLocation &loc=SourceLocation::Current())
Definition: persistent.h:58
cppgc::internal::BasicPersistent::operator=
BasicPersistent & operator=(SentinelPointer s)
Definition: persistent.h:149
cppgc::internal::BasicPersistent::Get
T * Get() const
Definition: persistent.h:159
source-location.h