5#ifndef INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
6#define INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
10#include "cppgc/internal/persistent-node.h"
11#include "cppgc/internal/pointer-policies.h"
12#include "cppgc/persistent.h"
13#include "cppgc/visitor.h"
43 return reinterpret_cast<std::atomic<PersistentNode*>*>(&
node_)->load(
44 std::memory_order_acquire);
50#if defined(__has_feature
)
51#if __has_feature
(address_sanitizer)
57 __atomic_store(&node_, &value, __ATOMIC_RELEASE);
61 reinterpret_cast<std::atomic<PersistentNode*>*>(&
node_)->store(
62 value, std::memory_order_release);
69template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
70 typename CheckingPolicy>
72 public LocationPolicy,
73 private WeaknessPolicy,
74 private CheckingPolicy {
76 using typename WeaknessPolicy::IsStrongPersistent;
77 using PointeeType = T;
86 PersistentRegionLock guard;
91 if (IsValid(old_value)) {
92 CrossThreadPersistentRegion& region =
93 this->GetPersistentRegion(old_value);
106 : LocationPolicy(loc) {}
109 SourceLocation loc = SourceLocation::Current())
110 : LocationPolicy(loc) {}
113 SourceLocation loc = SourceLocation::Current())
117 SourceLocation loc = SourceLocation::Current())
119 if (!IsValid(raw))
return;
120 PersistentRegionLock guard;
121 CrossThreadPersistentRegion& region =
this->GetPersistentRegion(raw);
123 this->CheckPointer(raw);
128 UnsafeCtorTag() =
default;
129 template <
typename U,
typename OtherWeaknessPolicy,
130 typename OtherLocationPolicy,
typename OtherCheckingPolicy>
135 SourceLocation loc = SourceLocation::Current())
137 if (!IsValid(raw))
return;
138 CrossThreadPersistentRegion& region =
this->GetPersistentRegion(raw);
140 this->CheckPointer(raw);
144 SourceLocation loc = SourceLocation::Current())
147 template <
typename U,
typename MemberBarrierPolicy,
148 typename MemberWeaknessTag,
typename MemberCheckingPolicy,
149 typename MemberStorageType,
153 MemberCheckingPolicy, MemberStorageType>
155 SourceLocation loc = SourceLocation::Current())
159 SourceLocation loc = SourceLocation::Current())
166 template <
typename U,
typename OtherWeaknessPolicy,
167 typename OtherLocationPolicy,
typename OtherCheckingPolicy,
170 U, OtherWeaknessPolicy, OtherLocationPolicy,
171 OtherCheckingPolicy>& other,
172 SourceLocation loc = SourceLocation::Current())
179 SourceLocation loc = SourceLocation::Current())
noexcept {
181 *
this = std::move(other);
186 PersistentRegionLock guard;
187 AssignSafe(guard, other.Get());
191 template <
typename U,
typename OtherWeaknessPolicy,
192 typename OtherLocationPolicy,
typename OtherCheckingPolicy,
197 OtherCheckingPolicy>& other) {
198 PersistentRegionLock guard;
199 AssignSafe(guard, other.Get());
204 if (
this == &other)
return *
this;
206 PersistentRegionLock guard;
208 LocationPolicy::operator=(std::move(other));
211 other.SetValue(
nullptr);
212 other.SetNode(
nullptr);
213 this->CheckPointer(Get());
218
219
220
221
228 template <
typename U,
typename MemberBarrierPolicy,
229 typename MemberWeaknessTag,
typename MemberCheckingPolicy,
230 typename MemberStorageType,
234 MemberCheckingPolicy, MemberStorageType>
236 return operator=(member.Get());
240
241
242
243
250
251
252
253
255 PersistentRegionLock guard;
256 AssignSafe(guard, s);
261
262
263
264
265
266
271 return static_cast<T*>(
const_cast<
void*>(
GetValue()));
275
276
278 PersistentRegionLock guard;
279 AssignSafe(guard,
nullptr);
283
284
285
286
287
288
296
297
298
299
300
301
305
306
307
308
309
310
314
315
316
317
321 template <
typename U,
typename OtherWeaknessPolicy = WeaknessPolicy,
322 typename OtherLocationPolicy = LocationPolicy,
323 typename OtherCheckingPolicy = CheckingPolicy>
327 using OtherBasicCrossThreadPersistent =
329 OtherCheckingPolicy>;
330 PersistentRegionLock guard;
331 return OtherBasicCrossThreadPersistent(
332 typename OtherBasicCrossThreadPersistent::UnsafeCtorTag(),
333 static_cast<U*>(Get()));
336 template <
typename U = T,
341 return BasicCrossThreadPersistent<
342 U, internal::StrongCrossThreadPersistentPolicy>(*
this);
346 static bool IsValid(
const void* ptr) {
350 static void TraceAsRoot(RootVisitor& root_visitor,
const void* ptr) {
354 void AssignUnsafe(T* ptr) {
356 if (IsValid(old_value)) {
357 PersistentRegionLock guard;
361 if (IsValid(old_value)) {
362 CrossThreadPersistentRegion& region =
363 this->GetPersistentRegion(old_value);
364 if (IsValid(ptr) && (®ion == &
this->GetPersistentRegion(ptr))) {
366 this->CheckPointer(ptr);
376 if (!IsValid(ptr))
return;
377 PersistentRegionLock guard;
378 SetNode(this->GetPersistentRegion(ptr).AllocateNode(
this, &TraceAsRoot)
);
379 this->CheckPointer(ptr);
382 void AssignSafe(PersistentRegionLock&, T* ptr) {
385 if (IsValid(old_value)) {
386 CrossThreadPersistentRegion& region =
387 this->GetPersistentRegion(old_value);
388 if (IsValid(ptr) && (®ion == &
this->GetPersistentRegion(ptr))) {
390 this->CheckPointer(ptr);
397 if (!IsValid(ptr))
return;
398 SetNode(this->GetPersistentRegion(ptr).AllocateNode(
this, &TraceAsRoot)
);
399 this->CheckPointer(ptr);
402 void ClearFromGC()
const {
403 if (IsValid(GetValueFromGC())) {
404 WeaknessPolicy::GetPersistentRegion(GetValueFromGC())
412 T* GetFromGC()
const {
413 return static_cast<T*>(
const_cast<
void*>(GetValueFromGC()));
419template <
typename T,
typename LocationPolicy,
typename CheckingPolicy>
422 LocationPolicy, CheckingPolicy>>
430
431
432
433
434
435
436
437
438
439
445
446
447
448
449
450
451
452
453
454
friend class BasicCrossThreadPersistent
BasicCrossThreadPersistent & operator=(const BasicCrossThreadPersistent< U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy > &other)
BasicCrossThreadPersistent(UnsafeCtorTag, T *raw, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent(SentinelPointer s, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent & operator=(T *other)
BasicCrossThreadPersistent & operator=(std::nullptr_t)
BasicCrossThreadPersistent(const BasicCrossThreadPersistent &other, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent(T &raw, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent(internal::BasicMember< U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy, MemberStorageType > member, SourceLocation loc=SourceLocation::Current())
~BasicCrossThreadPersistent()
BasicCrossThreadPersistent & operator=(BasicCrossThreadPersistent &&other)
BasicCrossThreadPersistent(std::nullptr_t, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent(SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent(BasicCrossThreadPersistent &&other, SourceLocation loc=SourceLocation::Current()) noexcept
BasicCrossThreadPersistent(const BasicCrossThreadPersistent< U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy > &other, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent< U, internal::StrongCrossThreadPersistentPolicy > Lock() const
BasicCrossThreadPersistent & operator=(SentinelPointer s)
BasicCrossThreadPersistent & operator=(const BasicCrossThreadPersistent &other)
BasicCrossThreadPersistent & operator=(internal::BasicMember< U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy, MemberStorageType > member)
BasicCrossThreadPersistent(T *raw, SourceLocation loc=SourceLocation::Current())
BasicCrossThreadPersistent< U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy > To() const
PersistentNode * GetNodeSafe() const
void SetNodeSafe(PersistentNode *value) const
CrossThreadPersistentBase()=default
PersistentNode * GetNodeFromGC() const
CrossThreadPersistentBase(const void *raw)
V8_INLINE PersistentNode * AllocateNode(void *owner, TraceRootCallback trace)
V8_INLINE void FreeNode(PersistentNode *node)
const void * GetValue() const
PersistentBase(const void *raw)
void SetValue(const void *value)
PersistentNode * GetNode() const
void SetNode(PersistentNode *node)
static void AssertLocked()
#define CPPGC_DCHECK(condition)
constexpr internal::SentinelPointer kSentinelPointer
#define V8_CLANG_NO_SANITIZE(what)
defined(V8_TRIVIAL_ABI)