v8  8.4.371 (node 14.15.5)
V8 is Google's open source JavaScript engine
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
member.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_MEMBER_H_
6 #define INCLUDE_CPPGC_MEMBER_H_
7 
8 #include <atomic>
9 #include <cstddef>
10 #include <type_traits>
11 
12 #include "cppgc/internal/pointer-policies.h"
13 #include "cppgc/type-traits.h"
14 #include "v8config.h" // NOLINT(build/include_directory)
15 
16 namespace cppgc {
17 
18 class Visitor;
19 
20 namespace internal {
21 
22 // The basic class from which all Member classes are 'generated'.
23 template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
24  typename CheckingPolicy>
25 class BasicMember : private CheckingPolicy {
26  public:
27  using PointeeType = T;
28 
29  constexpr BasicMember() = default;
30  constexpr BasicMember(std::nullptr_t) {} // NOLINT
31  BasicMember(SentinelPointer s) : raw_(s) {} // NOLINT
32  BasicMember(T* raw) : raw_(raw) { // NOLINT
33  InitializingWriteBarrier();
34  this->CheckPointer(raw_);
35  }
36  BasicMember(T& raw) : BasicMember(&raw) {} // NOLINT
37  BasicMember(const BasicMember& other) : BasicMember(other.Get()) {}
38  // Allow heterogeneous construction.
39  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
40  typename OtherCheckingPolicy,
41  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
42  BasicMember( // NOLINT
43  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
44  OtherCheckingPolicy>& other)
45  : BasicMember(other.Get()) {}
46  // Construction from Persistent.
47  template <typename U, typename PersistentWeaknessPolicy,
48  typename PersistentLocationPolicy,
49  typename PersistentCheckingPolicy,
50  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
51  BasicMember( // NOLINT
52  const BasicPersistent<U, PersistentWeaknessPolicy,
53  PersistentLocationPolicy, PersistentCheckingPolicy>&
54  p)
55  : BasicMember(p.Get()) {}
56 
57  BasicMember& operator=(const BasicMember& other) {
58  return operator=(other.Get());
59  }
60  // Allow heterogeneous assignment.
61  template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
62  typename OtherCheckingPolicy,
63  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
64  BasicMember& operator=(
65  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
66  OtherCheckingPolicy>& other) {
67  return operator=(other.Get());
68  }
69  // Assignment from Persistent.
70  template <typename U, typename PersistentWeaknessPolicy,
71  typename PersistentLocationPolicy,
72  typename PersistentCheckingPolicy,
73  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
74  BasicMember& operator=(
75  const BasicPersistent<U, PersistentWeaknessPolicy,
76  PersistentLocationPolicy, PersistentCheckingPolicy>&
77  other) {
78  return operator=(other.Get());
79  }
80  BasicMember& operator=(T* other) {
81  SetRawAtomic(other);
82  AssigningWriteBarrier();
83  this->CheckPointer(Get());
84  return *this;
85  }
86  BasicMember& operator=(std::nullptr_t) {
87  Clear();
88  return *this;
89  }
90  BasicMember& operator=(SentinelPointer s) {
91  SetRawAtomic(s);
92  return *this;
93  }
94 
95  template <typename OtherWeaknessTag, typename OtherBarrierPolicy,
96  typename OtherCheckingPolicy>
97  void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
98  OtherCheckingPolicy>& other) {
99  T* tmp = Get();
100  *this = other;
101  other = tmp;
102  }
103 
104  explicit operator bool() const { return Get(); }
105  operator T*() const { return Get(); } // NOLINT
106  T* operator->() const { return Get(); }
107  T& operator*() const { return *Get(); }
108 
109  T* Get() const {
110  // Executed by the mutator, hence non atomic load.
111  return raw_;
112  }
113 
114  void Clear() { SetRawAtomic(nullptr); }
115 
116  T* Release() {
117  T* result = Get();
118  Clear();
119  return result;
120  }
121 
122  private:
123  void SetRawAtomic(T* raw) {
124  reinterpret_cast<std::atomic<T*>*>(&raw_)->store(raw,
125  std::memory_order_relaxed);
126  }
127  T* GetRawAtomic() const {
128  return reinterpret_cast<const std::atomic<T*>*>(&raw_)->load(
129  std::memory_order_relaxed);
130  }
131 
132  void InitializingWriteBarrier() const {
133  WriteBarrierPolicy::InitializingBarrier(
134  reinterpret_cast<const void*>(&raw_), static_cast<const void*>(raw_));
135  }
136  void AssigningWriteBarrier() const {
137  WriteBarrierPolicy::AssigningBarrier(reinterpret_cast<const void*>(&raw_),
138  static_cast<const void*>(raw_));
139  }
140 
141  T* raw_ = nullptr;
142 
143  friend class cppgc::Visitor;
144 };
145 
146 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
147  typename CheckingPolicy1, typename T2, typename WeaknessTag2,
148  typename WriteBarrierPolicy2, typename CheckingPolicy2>
149 bool operator==(
150  BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1> member1,
151  BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>
152  member2) {
153  return member1.Get() == member2.Get();
154 }
155 
156 template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
157  typename CheckingPolicy1, typename T2, typename WeaknessTag2,
158  typename WriteBarrierPolicy2, typename CheckingPolicy2>
159 bool operator!=(
160  BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1> member1,
161  BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>
162  member2) {
163  return !(member1 == member2);
164 }
165 
166 template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy>
167 struct IsWeak<
168  internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy>>
169  : std::true_type {};
170 
171 } // namespace internal
172 
173 /**
174  * Members are used in classes to contain strong pointers to other garbage
175  * collected objects. All Member fields of a class must be traced in the class'
176  * trace method.
177  */
178 template <typename T>
179 using Member = internal::BasicMember<T, internal::StrongMemberTag,
181 
182 /**
183  * WeakMember is similar to Member in that it is used to point to other garbage
184  * collected objects. However instead of creating a strong pointer to the
185  * object, the WeakMember creates a weak pointer, which does not keep the
186  * pointee alive. Hence if all pointers to to a heap allocated object are weak
187  * the object will be garbage collected. At the time of GC the weak pointers
188  * will automatically be set to null.
189  */
190 template <typename T>
191 using WeakMember = internal::BasicMember<T, internal::WeakMemberTag,
193 
194 /**
195  * UntracedMember is a pointer to an on-heap object that is not traced for some
196  * reason. Do not use this unless you know what you are doing. Keeping raw
197  * pointers to on-heap objects is prohibited unless used from stack. Pointee
198  * must be kept alive through other means.
199  */
200 template <typename T>
201 using UntracedMember = internal::BasicMember<T, internal::UntracedMemberTag,
203 
204 } // namespace cppgc
205 
206 #endif // INCLUDE_CPPGC_MEMBER_H_