Linux vmi2545633.contaboserver.net 6.1.0-32-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06) x86_64
Apache/2.4.62 (Debian)
Server IP : 127.0.0.1 & Your IP : 127.0.0.1
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
usr /
include /
node /
cppgc /
Delete
Unzip
Name
Size
Permission
Date
Action
internal
[ DIR ]
drwxr-xr-x
2025-04-07 20:36
allocation.h
11.61
KB
-rw-r--r--
2022-10-11 10:59
common.h
643
B
-rw-r--r--
2024-04-10 12:29
cross-thread-persistent.h
14.81
KB
-rw-r--r--
2024-04-10 12:29
custom-space.h
2.4
KB
-rw-r--r--
2022-10-11 10:59
default-platform.h
2.18
KB
-rw-r--r--
2022-10-11 10:59
ephemeron-pair.h
804
B
-rw-r--r--
2022-10-11 10:59
explicit-management.h
3.29
KB
-rw-r--r--
2022-10-11 10:59
garbage-collected.h
3.11
KB
-rw-r--r--
2022-10-11 10:59
heap-consistency.h
11.74
KB
-rw-r--r--
2024-04-10 12:29
heap-handle.h
1.26
KB
-rw-r--r--
2024-04-10 12:29
heap-state.h
2.57
KB
-rw-r--r--
2022-10-11 10:59
heap-statistics.h
3.89
KB
-rw-r--r--
2024-04-10 12:29
heap.h
5.7
KB
-rw-r--r--
2024-04-10 12:29
liveness-broker.h
2.34
KB
-rw-r--r--
2024-04-10 12:29
macros.h
1.31
KB
-rw-r--r--
2024-04-10 12:29
member.h
23.55
KB
-rw-r--r--
2024-04-10 12:29
name-provider.h
1.99
KB
-rw-r--r--
2024-04-10 12:29
object-size-trait.h
1.6
KB
-rw-r--r--
2022-10-11 10:59
persistent.h
13.61
KB
-rw-r--r--
2024-04-10 12:29
platform.h
5.9
KB
-rw-r--r--
2024-04-10 12:29
prefinalizer.h
2.88
KB
-rw-r--r--
2022-10-11 10:59
process-heap-statistics.h
1009
B
-rw-r--r--
2022-10-11 10:59
sentinel-pointer.h
1.18
KB
-rw-r--r--
2024-04-10 12:29
source-location.h
414
B
-rw-r--r--
2024-04-10 12:29
testing.h
2.96
KB
-rw-r--r--
2022-10-11 10:59
trace-trait.h
3.4
KB
-rw-r--r--
2024-04-10 12:29
type-traits.h
7.78
KB
-rw-r--r--
2024-04-10 12:29
visitor.h
18.08
KB
-rw-r--r--
2024-04-10 12:29
Save
Rename
// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_ #define INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_ #include <atomic> #include "cppgc/internal/persistent-node.h" #include "cppgc/internal/pointer-policies.h" #include "cppgc/persistent.h" #include "cppgc/visitor.h" namespace cppgc { namespace internal { // Wrapper around PersistentBase that allows accessing poisoned memory when // using ASAN. This is needed as the GC of the heap that owns the value // of a CTP, may clear it (heap termination, weakness) while the object // holding the CTP may be poisoned as itself may be deemed dead. class CrossThreadPersistentBase : public PersistentBase { public: CrossThreadPersistentBase() = default; explicit CrossThreadPersistentBase(const void* raw) : PersistentBase(raw) {} V8_CLANG_NO_SANITIZE("address") const void* GetValueFromGC() const { return raw_; } V8_CLANG_NO_SANITIZE("address") PersistentNode* GetNodeFromGC() const { return node_; } V8_CLANG_NO_SANITIZE("address") void ClearFromGC() const { raw_ = nullptr; SetNodeSafe(nullptr); } // GetNodeSafe() can be used for a thread-safe IsValid() check in a // double-checked locking pattern. See ~BasicCrossThreadPersistent. PersistentNode* GetNodeSafe() const { return reinterpret_cast<std::atomic<PersistentNode*>*>(&node_)->load( std::memory_order_acquire); } // The GC writes using SetNodeSafe() while holding the lock. V8_CLANG_NO_SANITIZE("address") void SetNodeSafe(PersistentNode* value) const { #if defined(__has_feature) #if __has_feature(address_sanitizer) #define V8_IS_ASAN 1 #endif #endif #ifdef V8_IS_ASAN __atomic_store(&node_, &value, __ATOMIC_RELEASE); #else // !V8_IS_ASAN // Non-ASAN builds can use atomics. This also covers MSVC which does not // have the __atomic_store intrinsic. reinterpret_cast<std::atomic<PersistentNode*>*>(&node_)->store( value, std::memory_order_release); #endif // !V8_IS_ASAN #undef V8_IS_ASAN } }; template <typename T, typename WeaknessPolicy, typename LocationPolicy, typename CheckingPolicy> class BasicCrossThreadPersistent final : public CrossThreadPersistentBase, public LocationPolicy, private WeaknessPolicy, private CheckingPolicy { public: using typename WeaknessPolicy::IsStrongPersistent; using PointeeType = T; ~BasicCrossThreadPersistent() { // This implements fast path for destroying empty/sentinel. // // Simplified version of `AssignUnsafe()` to allow calling without a // complete type `T`. Uses double-checked locking with a simple thread-safe // check for a valid handle based on a node. if (GetNodeSafe()) { PersistentRegionLock guard; const void* old_value = GetValue(); // The fast path check (GetNodeSafe()) does not acquire the lock. Recheck // validity while holding the lock to ensure the reference has not been // cleared. if (IsValid(old_value)) { CrossThreadPersistentRegion& region = this->GetPersistentRegion(old_value); region.FreeNode(GetNode()); SetNode(nullptr); } else { CPPGC_DCHECK(!GetNode()); } } // No need to call SetValue() as the handle is not used anymore. This can // leave behind stale sentinel values but will always destroy the underlying // node. } BasicCrossThreadPersistent( const SourceLocation& loc = SourceLocation::Current()) : LocationPolicy(loc) {} BasicCrossThreadPersistent( std::nullptr_t, const SourceLocation& loc = SourceLocation::Current()) : LocationPolicy(loc) {} BasicCrossThreadPersistent( SentinelPointer s, const SourceLocation& loc = SourceLocation::Current()) : CrossThreadPersistentBase(s), LocationPolicy(loc) {} BasicCrossThreadPersistent( T* raw, const SourceLocation& loc = SourceLocation::Current()) : CrossThreadPersistentBase(raw), LocationPolicy(loc) { if (!IsValid(raw)) return; PersistentRegionLock guard; CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw); SetNode(region.AllocateNode(this, &TraceAsRoot)); this->CheckPointer(raw); } class UnsafeCtorTag { private: UnsafeCtorTag() = default; template <typename U, typename OtherWeaknessPolicy, typename OtherLocationPolicy, typename OtherCheckingPolicy> friend class BasicCrossThreadPersistent; }; BasicCrossThreadPersistent( UnsafeCtorTag, T* raw, const SourceLocation& loc = SourceLocation::Current()) : CrossThreadPersistentBase(raw), LocationPolicy(loc) { if (!IsValid(raw)) return; CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw); SetNode(region.AllocateNode(this, &TraceAsRoot)); this->CheckPointer(raw); } BasicCrossThreadPersistent( T& raw, const SourceLocation& loc = SourceLocation::Current()) : BasicCrossThreadPersistent(&raw, loc) {} template <typename U, typename MemberBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberStorageType, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicCrossThreadPersistent( internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy, MemberStorageType> member, const SourceLocation& loc = SourceLocation::Current()) : BasicCrossThreadPersistent(member.Get(), loc) {} BasicCrossThreadPersistent( const BasicCrossThreadPersistent& other, const SourceLocation& loc = SourceLocation::Current()) : BasicCrossThreadPersistent(loc) { // Invoke operator=. *this = other; } // Heterogeneous ctor. template <typename U, typename OtherWeaknessPolicy, typename OtherLocationPolicy, typename OtherCheckingPolicy, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicCrossThreadPersistent( const BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy>& other, const SourceLocation& loc = SourceLocation::Current()) : BasicCrossThreadPersistent(loc) { *this = other; } BasicCrossThreadPersistent( BasicCrossThreadPersistent&& other, const SourceLocation& loc = SourceLocation::Current()) noexcept { // Invoke operator=. *this = std::move(other); } BasicCrossThreadPersistent& operator=( const BasicCrossThreadPersistent& other) { PersistentRegionLock guard; AssignSafe(guard, other.Get()); return *this; } template <typename U, typename OtherWeaknessPolicy, typename OtherLocationPolicy, typename OtherCheckingPolicy, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicCrossThreadPersistent& operator=( const BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy>& other) { PersistentRegionLock guard; AssignSafe(guard, other.Get()); return *this; } BasicCrossThreadPersistent& operator=(BasicCrossThreadPersistent&& other) { if (this == &other) return *this; Clear(); PersistentRegionLock guard; PersistentBase::operator=(std::move(other)); LocationPolicy::operator=(std::move(other)); if (!IsValid(GetValue())) return *this; GetNode()->UpdateOwner(this); other.SetValue(nullptr); other.SetNode(nullptr); this->CheckPointer(Get()); return *this; } /** * Assigns a raw pointer. * * Note: **Not thread-safe.** */ BasicCrossThreadPersistent& operator=(T* other) { AssignUnsafe(other); return *this; } // Assignment from member. template <typename U, typename MemberBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberStorageType, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicCrossThreadPersistent& operator=( internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy, MemberStorageType> member) { return operator=(member.Get()); } /** * Assigns a nullptr. * * \returns the handle. */ BasicCrossThreadPersistent& operator=(std::nullptr_t) { Clear(); return *this; } /** * Assigns the sentinel pointer. * * \returns the handle. */ BasicCrossThreadPersistent& operator=(SentinelPointer s) { PersistentRegionLock guard; AssignSafe(guard, s); return *this; } /** * Returns a pointer to the stored object. * * Note: **Not thread-safe.** * * \returns a pointer to the stored object. */ // CFI cast exemption to allow passing SentinelPointer through T* and support // heterogeneous assignments between different Member and Persistent handles // based on their actual types. V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const { return static_cast<T*>(const_cast<void*>(GetValue())); } /** * Clears the stored object. */ void Clear() { PersistentRegionLock guard; AssignSafe(guard, nullptr); } /** * Returns a pointer to the stored object and releases it. * * Note: **Not thread-safe.** * * \returns a pointer to the stored object. */ T* Release() { T* result = Get(); Clear(); return result; } /** * Conversio to boolean. * * Note: **Not thread-safe.** * * \returns true if an actual object has been stored and false otherwise. */ explicit operator bool() const { return Get(); } /** * Conversion to object of type T. * * Note: **Not thread-safe.** * * \returns the object. */ operator T*() const { return Get(); } /** * Dereferences the stored object. * * Note: **Not thread-safe.** */ T* operator->() const { return Get(); } T& operator*() const { return *Get(); } template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy, typename OtherLocationPolicy = LocationPolicy, typename OtherCheckingPolicy = CheckingPolicy> BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy> To() const { using OtherBasicCrossThreadPersistent = BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy>; PersistentRegionLock guard; return OtherBasicCrossThreadPersistent( typename OtherBasicCrossThreadPersistent::UnsafeCtorTag(), static_cast<U*>(Get())); } template <typename U = T, typename = typename std::enable_if<!BasicCrossThreadPersistent< U, WeaknessPolicy>::IsStrongPersistent::value>::type> BasicCrossThreadPersistent<U, internal::StrongCrossThreadPersistentPolicy> Lock() const { return BasicCrossThreadPersistent< U, internal::StrongCrossThreadPersistentPolicy>(*this); } private: static bool IsValid(const void* ptr) { return ptr && ptr != kSentinelPointer; } static void TraceAsRoot(RootVisitor& root_visitor, const void* ptr) { root_visitor.Trace(*static_cast<const BasicCrossThreadPersistent*>(ptr)); } void AssignUnsafe(T* ptr) { const void* old_value = GetValue(); if (IsValid(old_value)) { PersistentRegionLock guard; old_value = GetValue(); // The fast path check (IsValid()) does not acquire the lock. Reload // the value to ensure the reference has not been cleared. if (IsValid(old_value)) { CrossThreadPersistentRegion& region = this->GetPersistentRegion(old_value); if (IsValid(ptr) && (®ion == &this->GetPersistentRegion(ptr))) { SetValue(ptr); this->CheckPointer(ptr); return; } region.FreeNode(GetNode()); SetNode(nullptr); } else { CPPGC_DCHECK(!GetNode()); } } SetValue(ptr); if (!IsValid(ptr)) return; PersistentRegionLock guard; SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &TraceAsRoot)); this->CheckPointer(ptr); } void AssignSafe(PersistentRegionLock&, T* ptr) { PersistentRegionLock::AssertLocked(); const void* old_value = GetValue(); if (IsValid(old_value)) { CrossThreadPersistentRegion& region = this->GetPersistentRegion(old_value); if (IsValid(ptr) && (®ion == &this->GetPersistentRegion(ptr))) { SetValue(ptr); this->CheckPointer(ptr); return; } region.FreeNode(GetNode()); SetNode(nullptr); } SetValue(ptr); if (!IsValid(ptr)) return; SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &TraceAsRoot)); this->CheckPointer(ptr); } void ClearFromGC() const { if (IsValid(GetValueFromGC())) { WeaknessPolicy::GetPersistentRegion(GetValueFromGC()) .FreeNode(GetNodeFromGC()); CrossThreadPersistentBase::ClearFromGC(); } } // See Get() for details. V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* GetFromGC() const { return static_cast<T*>(const_cast<void*>(GetValueFromGC())); } friend class internal::RootVisitor; }; template <typename T, typename LocationPolicy, typename CheckingPolicy> struct IsWeak< BasicCrossThreadPersistent<T, internal::WeakCrossThreadPersistentPolicy, LocationPolicy, CheckingPolicy>> : std::true_type {}; } // namespace internal namespace subtle { /** * **DO NOT USE: Has known caveats, see below.** * * CrossThreadPersistent allows retaining objects from threads other than the * thread the owning heap is operating on. * * Known caveats: * - Does not protect the heap owning an object from terminating. * - Reaching transitively through the graph is unsupported as objects may be * moved concurrently on the thread owning the object. */ template <typename T> using CrossThreadPersistent = internal::BasicCrossThreadPersistent< T, internal::StrongCrossThreadPersistentPolicy>; /** * **DO NOT USE: Has known caveats, see below.** * * CrossThreadPersistent allows weakly retaining objects from threads other than * the thread the owning heap is operating on. * * Known caveats: * - Does not protect the heap owning an object from terminating. * - Reaching transitively through the graph is unsupported as objects may be * moved concurrently on the thread owning the object. */ template <typename T> using WeakCrossThreadPersistent = internal::BasicCrossThreadPersistent< T, internal::WeakCrossThreadPersistentPolicy>; } // namespace subtle } // namespace cppgc #endif // INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_