v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
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
14#include "cppgc/type-traits.h"
15#include "v8config.h" // NOLINT(build/include_directory)
16
17namespace cppgc {
18
19class Visitor;
20
21namespace internal {
22
23// MemberBase always refers to the object as const object and defers to
24// BasicMember on casting to the right type as needed.
26 protected:
28
29 MemberBase() : raw_(nullptr) {}
30 explicit MemberBase(const void* value) : raw_(value) {}
31 MemberBase(const void* value, AtomicInitializerTag) { SetRawAtomic(value); }
32
33 const void** GetRawSlot() const { return &raw_; }
34 const void* GetRaw() const { return raw_; }
35 void SetRaw(void* value) { raw_ = value; }
36
37 const void* GetRawAtomic() const {
38 return reinterpret_cast<const std::atomic<const void*>*>(&raw_)->load(
39 std::memory_order_relaxed);
40 }
41 void SetRawAtomic(const void* value) {
42 reinterpret_cast<std::atomic<const void*>*>(&raw_)->store(
43 value, std::memory_order_relaxed);
44 }
45
46 void ClearFromGC() const { raw_ = nullptr; }
47
48 private:
49 // All constructors initialize `raw_`. Do not add a default value here as it
50 // results in a non-atomic write on some builds, even when the atomic version
51 // of the constructor is used.
52 mutable const void* raw_;
53};
54
55// The basic class from which all Member classes are 'generated'.
56template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
57 typename CheckingPolicy>
58class BasicMember final : private MemberBase, private CheckingPolicy {
59 public:
60 using PointeeType = T;
61
62 constexpr BasicMember() = default;
63 constexpr BasicMember(std::nullptr_t) {} // NOLINT
65 BasicMember(T* raw) : MemberBase(raw) { // NOLINT
66 InitializingWriteBarrier();
67 this->CheckPointer(Get());
68 }
69 BasicMember(T& raw) : BasicMember(&raw) {} // NOLINT
70 // Atomic ctor. Using the AtomicInitializerTag forces BasicMember to
71 // initialize using atomic assignments. This is required for preventing
72 // data races with concurrent marking.
74 BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
75 : MemberBase(nullptr, atomic) {}
77 : MemberBase(s, atomic) {}
78 BasicMember(T* raw, AtomicInitializerTag atomic) : MemberBase(raw, atomic) {
79 InitializingWriteBarrier();
80 this->CheckPointer(Get());
81 }
83 : BasicMember(&raw, atomic) {}
84 // Copy ctor.
85 BasicMember(const BasicMember& other) : BasicMember(other.Get()) {}
86 // Allow heterogeneous construction.
87 template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
88 typename OtherCheckingPolicy,
89 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
90 BasicMember( // NOLINT
91 const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
92 OtherCheckingPolicy>& other)
93 : BasicMember(other.Get()) {}
94 // Move ctor.
95 BasicMember(BasicMember&& other) noexcept : BasicMember(other.Get()) {
96 other.Clear();
97 }
98 // Allow heterogeneous move construction.
99 template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
100 typename OtherCheckingPolicy,
101 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
102 BasicMember(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
103 OtherCheckingPolicy>&& other) noexcept
104 : BasicMember(other.Get()) {
105 other.Clear();
106 }
107 // Construction from Persistent.
108 template <typename U, typename PersistentWeaknessPolicy,
109 typename PersistentLocationPolicy,
110 typename PersistentCheckingPolicy,
111 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
112 BasicMember(const BasicPersistent<U, PersistentWeaknessPolicy,
113 PersistentLocationPolicy,
114 PersistentCheckingPolicy>& p)
115 : BasicMember(p.Get()) {}
116
117 // Copy assignment.
119 return operator=(other.Get());
120 }
121 // Allow heterogeneous copy assignment.
122 template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
123 typename OtherCheckingPolicy,
124 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
126 const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
127 OtherCheckingPolicy>& other) {
128 return operator=(other.Get());
129 }
130 // Move assignment.
131 BasicMember& operator=(BasicMember&& other) noexcept {
132 operator=(other.Get());
133 other.Clear();
134 return *this;
135 }
136 // Heterogeneous move assignment.
137 template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
138 typename OtherCheckingPolicy,
139 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
140 BasicMember& operator=(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
141 OtherCheckingPolicy>&& other) noexcept {
142 operator=(other.Get());
143 other.Clear();
144 return *this;
145 }
146 // Assignment from Persistent.
147 template <typename U, typename PersistentWeaknessPolicy,
148 typename PersistentLocationPolicy,
149 typename PersistentCheckingPolicy,
150 typename = std::enable_if_t<std::is_base_of<T, U>::value>>
152 const BasicPersistent<U, PersistentWeaknessPolicy,
153 PersistentLocationPolicy, PersistentCheckingPolicy>&
154 other) {
155 return operator=(other.Get());
156 }
158 SetRawAtomic(other);
159 AssigningWriteBarrier();
160 this->CheckPointer(Get());
161 return *this;
162 }
163 BasicMember& operator=(std::nullptr_t) {
164 Clear();
165 return *this;
166 }
168 SetRawAtomic(s);
169 return *this;
170 }
171
172 template <typename OtherWeaknessTag, typename OtherBarrierPolicy,
173 typename OtherCheckingPolicy>
174 void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
175 OtherCheckingPolicy>& other) {
176 T* tmp = Get();
177 *this = other;
178 other = tmp;
179 }
180
181 explicit operator bool() const { return Get(); }
182 operator T*() const { return Get(); }
183 T* operator->() const { return Get(); }
184 T& operator*() const { return *Get(); }
185
186 // CFI cast exemption to allow passing SentinelPointer through T* and support
187 // heterogeneous assignments between different Member and Persistent handles
188 // based on their actual types.
189 V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
190 // Executed by the mutator, hence non atomic load.
191 //
192 // The const_cast below removes the constness from MemberBase storage. The
193 // following static_cast re-adds any constness if specified through the
194 // user-visible template parameter T.
195 return static_cast<T*>(const_cast<void*>(MemberBase::GetRaw()));
196 }
197
198 void Clear() { SetRawAtomic(nullptr); }
199
200 T* Release() {
201 T* result = Get();
202 Clear();
203 return result;
204 }
205
206 const T** GetSlotForTesting() const {
207 return reinterpret_cast<const T**>(GetRawSlot());
208 }
209
210 private:
211 const T* GetRawAtomic() const {
212 return static_cast<const T*>(MemberBase::GetRawAtomic());
213 }
214
215 void InitializingWriteBarrier() const {
216 WriteBarrierPolicy::InitializingBarrier(GetRawSlot(), GetRaw());
217 }
218 void AssigningWriteBarrier() const {
219 WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), GetRaw());
220 }
221
222 void ClearFromGC() const { MemberBase::ClearFromGC(); }
223
224 T* GetFromGC() const { return Get(); }
225
226 friend class cppgc::Visitor;
227 template <typename U>
228 friend struct cppgc::TraceTrait;
229};
230
231template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
232 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
233 typename WriteBarrierPolicy2, typename CheckingPolicy2>
234bool operator==(const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1,
235 CheckingPolicy1>& member1,
236 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2,
237 CheckingPolicy2>& member2) {
238 return member1.Get() == member2.Get();
239}
240
241template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
242 typename CheckingPolicy1, typename T2, typename WeaknessTag2,
243 typename WriteBarrierPolicy2, typename CheckingPolicy2>
244bool operator!=(const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1,
245 CheckingPolicy1>& member1,
246 const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2,
247 CheckingPolicy2>& member2) {
248 return !(member1 == member2);
249}
250
251template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy>
252struct IsWeak<
253 internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy>>
254 : std::true_type {};
255
256} // namespace internal
257
263template <typename T>
264using Member = internal::BasicMember<T, internal::StrongMemberTag,
266
275template <typename T>
276using WeakMember = internal::BasicMember<T, internal::WeakMemberTag,
278
285template <typename T>
286using UntracedMember = internal::BasicMember<T, internal::UntracedMemberTag,
288
289} // namespace cppgc
290
291#endif // INCLUDE_CPPGC_MEMBER_H_
BasicMember & operator=(std::nullptr_t)
Definition member.h:163
BasicMember & operator=(BasicMember &&other) noexcept
Definition member.h:131
BasicMember(const BasicMember &other)
Definition member.h:85
BasicMember(BasicMember &&other) noexcept
Definition member.h:95
BasicMember(const BasicPersistent< U, PersistentWeaknessPolicy, PersistentLocationPolicy, PersistentCheckingPolicy > &p)
Definition member.h:112
BasicMember(const BasicMember< U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy > &other)
Definition member.h:90
V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T *Get() const
Definition member.h:189
BasicMember(T *raw, AtomicInitializerTag atomic)
Definition member.h:78
BasicMember & operator=(const BasicPersistent< U, PersistentWeaknessPolicy, PersistentLocationPolicy, PersistentCheckingPolicy > &other)
Definition member.h:151
BasicMember & operator=(T *other)
Definition member.h:157
BasicMember & operator=(const BasicMember &other)
Definition member.h:118
BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
Definition member.h:74
void Swap(BasicMember< T, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy > &other)
Definition member.h:174
const T ** GetSlotForTesting() const
Definition member.h:206
BasicMember(BasicMember< U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy > &&other) noexcept
Definition member.h:102
BasicMember(SentinelPointer s)
Definition member.h:64
BasicMember(SentinelPointer s, AtomicInitializerTag atomic)
Definition member.h:76
constexpr BasicMember()=default
BasicMember & operator=(BasicMember< U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy > &&other) noexcept
Definition member.h:140
BasicMember & operator=(SentinelPointer s)
Definition member.h:167
constexpr BasicMember(std::nullptr_t)
Definition member.h:63
BasicMember(T &raw, AtomicInitializerTag atomic)
Definition member.h:82
BasicMember & operator=(const BasicMember< U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy > &other)
Definition member.h:125
void SetRawAtomic(const void *value)
Definition member.h:41
const void * GetRaw() const
Definition member.h:34
void ClearFromGC() const
Definition member.h:46
const void ** GetRawSlot() const
Definition member.h:33
void SetRaw(void *value)
Definition member.h:35
MemberBase(const void *value, AtomicInitializerTag)
Definition member.h:31
MemberBase(const void *value)
Definition member.h:30
const void * GetRawAtomic() const
Definition member.h:37
bool operator!=(const BasicMember< T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1 > &member1, const BasicMember< T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2 > &member2)
Definition member.h:244
bool operator==(const BasicMember< T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1 > &member1, const BasicMember< T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2 > &member2)
Definition member.h:234