Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/node/cppgc/internal/member-storage.h
$ cat -n /usr/include/node/cppgc/internal/member-storage.h 1 // Copyright 2022 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_INTERNAL_MEMBER_STORAGE_H_ 6 #define INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_ 7 8 #include
9 #include
10 #include
11 12 #include "cppgc/internal/api-constants.h" 13 #include "cppgc/internal/logging.h" 14 #include "cppgc/sentinel-pointer.h" 15 #include "v8config.h" // NOLINT(build/include_directory) 16 17 namespace cppgc { 18 namespace internal { 19 20 enum class WriteBarrierSlotType { 21 kCompressed, 22 kUncompressed, 23 }; 24 25 #if defined(CPPGC_POINTER_COMPRESSION) 26 27 #if defined(__clang__) 28 // Attribute const allows the compiler to assume that CageBaseGlobal::g_base_ 29 // doesn't change (e.g. across calls) and thereby avoid redundant loads. 30 #define CPPGC_CONST __attribute__((const)) 31 #define CPPGC_REQUIRE_CONSTANT_INIT \ 32 __attribute__((require_constant_initialization)) 33 #else // defined(__clang__) 34 #define CPPGC_CONST 35 #define CPPGC_REQUIRE_CONSTANT_INIT 36 #endif // defined(__clang__) 37 38 class V8_EXPORT CageBaseGlobal final { 39 public: 40 V8_INLINE CPPGC_CONST static uintptr_t Get() { 41 CPPGC_DCHECK(IsBaseConsistent()); 42 return g_base_.base; 43 } 44 45 V8_INLINE CPPGC_CONST static bool IsSet() { 46 CPPGC_DCHECK(IsBaseConsistent()); 47 return (g_base_.base & ~kLowerHalfWordMask) != 0; 48 } 49 50 private: 51 // We keep the lower halfword as ones to speed up decompression. 52 static constexpr uintptr_t kLowerHalfWordMask = 53 (api_constants::kCagedHeapReservationAlignment - 1); 54 55 static union alignas(api_constants::kCachelineSize) Base { 56 uintptr_t base; 57 char cache_line[api_constants::kCachelineSize]; 58 } g_base_ CPPGC_REQUIRE_CONSTANT_INIT; 59 60 CageBaseGlobal() = delete; 61 62 V8_INLINE static bool IsBaseConsistent() { 63 return kLowerHalfWordMask == (g_base_.base & kLowerHalfWordMask); 64 } 65 66 friend class CageBaseGlobalUpdater; 67 }; 68 69 #undef CPPGC_REQUIRE_CONSTANT_INIT 70 #undef CPPGC_CONST 71 72 class V8_TRIVIAL_ABI CompressedPointer final { 73 public: 74 using IntegralType = uint32_t; 75 static constexpr auto kWriteBarrierSlotType = 76 WriteBarrierSlotType::kCompressed; 77 78 V8_INLINE CompressedPointer() : value_(0u) {} 79 V8_INLINE explicit CompressedPointer(const void* ptr) 80 : value_(Compress(ptr)) {} 81 V8_INLINE explicit CompressedPointer(std::nullptr_t) : value_(0u) {} 82 V8_INLINE explicit CompressedPointer(SentinelPointer) 83 : value_(kCompressedSentinel) {} 84 85 V8_INLINE const void* Load() const { return Decompress(value_); } 86 V8_INLINE const void* LoadAtomic() const { 87 return Decompress( 88 reinterpret_cast
&>(value_).load( 89 std::memory_order_relaxed)); 90 } 91 92 V8_INLINE void Store(const void* ptr) { value_ = Compress(ptr); } 93 V8_INLINE void StoreAtomic(const void* value) { 94 reinterpret_cast
&>(value_).store( 95 Compress(value), std::memory_order_relaxed); 96 } 97 98 V8_INLINE void Clear() { value_ = 0u; } 99 V8_INLINE bool IsCleared() const { return !value_; } 100 101 V8_INLINE bool IsSentinel() const { return value_ == kCompressedSentinel; } 102 103 V8_INLINE uint32_t GetAsInteger() const { return value_; } 104 105 V8_INLINE friend bool operator==(CompressedPointer a, CompressedPointer b) { 106 return a.value_ == b.value_; 107 } 108 V8_INLINE friend bool operator!=(CompressedPointer a, CompressedPointer b) { 109 return a.value_ != b.value_; 110 } 111 V8_INLINE friend bool operator<(CompressedPointer a, CompressedPointer b) { 112 return a.value_ < b.value_; 113 } 114 V8_INLINE friend bool operator<=(CompressedPointer a, CompressedPointer b) { 115 return a.value_ <= b.value_; 116 } 117 V8_INLINE friend bool operator>(CompressedPointer a, CompressedPointer b) { 118 return a.value_ > b.value_; 119 } 120 V8_INLINE friend bool operator>=(CompressedPointer a, CompressedPointer b) { 121 return a.value_ >= b.value_; 122 } 123 124 static V8_INLINE IntegralType Compress(const void* ptr) { 125 static_assert(SentinelPointer::kSentinelValue == 126 1 << api_constants::kPointerCompressionShift, 127 "The compression scheme relies on the sentinel encoded as 1 " 128 "<< kPointerCompressionShift"); 129 static constexpr size_t kGigaCageMask = 130 ~(api_constants::kCagedHeapReservationAlignment - 1); 131 static constexpr size_t kPointerCompressionShiftMask = 132 (1 << api_constants::kPointerCompressionShift) - 1; 133 134 CPPGC_DCHECK(CageBaseGlobal::IsSet()); 135 const uintptr_t base = CageBaseGlobal::Get(); 136 CPPGC_DCHECK(!ptr || ptr == kSentinelPointer || 137 (base & kGigaCageMask) == 138 (reinterpret_cast
(ptr) & kGigaCageMask)); 139 CPPGC_DCHECK( 140 (reinterpret_cast
(ptr) & kPointerCompressionShiftMask) == 0); 141 142 #if defined(CPPGC_2GB_CAGE) 143 // Truncate the pointer. 144 auto compressed = 145 static_cast
(reinterpret_cast
(ptr)); 146 #else // !defined(CPPGC_2GB_CAGE) 147 const auto uptr = reinterpret_cast
(ptr); 148 // Shift the pointer and truncate. 149 auto compressed = static_cast
( 150 uptr >> api_constants::kPointerCompressionShift); 151 #endif // !defined(CPPGC_2GB_CAGE) 152 // Normal compressed pointers must have the MSB set. 153 CPPGC_DCHECK((!compressed || compressed == kCompressedSentinel) || 154 (compressed & (1 << 31))); 155 return compressed; 156 } 157 158 static V8_INLINE void* Decompress(IntegralType ptr) { 159 CPPGC_DCHECK(CageBaseGlobal::IsSet()); 160 const uintptr_t base = CageBaseGlobal::Get(); 161 // Treat compressed pointer as signed and cast it to uint64_t, which will 162 // sign-extend it. 163 #if defined(CPPGC_2GB_CAGE) 164 const uint64_t mask = static_cast
(static_cast
(ptr)); 165 #else // !defined(CPPGC_2GB_CAGE) 166 // Then, shift the result. It's important to shift the unsigned 167 // value, as otherwise it would result in undefined behavior. 168 const uint64_t mask = static_cast
(static_cast
(ptr)) 169 << api_constants::kPointerCompressionShift; 170 #endif // !defined(CPPGC_2GB_CAGE) 171 return reinterpret_cast
(mask & base); 172 } 173 174 private: 175 #if defined(CPPGC_2GB_CAGE) 176 static constexpr IntegralType kCompressedSentinel = 177 SentinelPointer::kSentinelValue; 178 #else // !defined(CPPGC_2GB_CAGE) 179 static constexpr IntegralType kCompressedSentinel = 180 SentinelPointer::kSentinelValue >> 181 api_constants::kPointerCompressionShift; 182 #endif // !defined(CPPGC_2GB_CAGE) 183 // All constructors initialize `value_`. Do not add a default value here as it 184 // results in a non-atomic write on some builds, even when the atomic version 185 // of the constructor is used. 186 IntegralType value_; 187 }; 188 189 #endif // defined(CPPGC_POINTER_COMPRESSION) 190 191 class V8_TRIVIAL_ABI RawPointer final { 192 public: 193 using IntegralType = uintptr_t; 194 static constexpr auto kWriteBarrierSlotType = 195 WriteBarrierSlotType::kUncompressed; 196 197 V8_INLINE RawPointer() : ptr_(nullptr) {} 198 V8_INLINE explicit RawPointer(const void* ptr) : ptr_(ptr) {} 199 200 V8_INLINE const void* Load() const { return ptr_; } 201 V8_INLINE const void* LoadAtomic() const { 202 return reinterpret_cast
&>(ptr_).load( 203 std::memory_order_relaxed); 204 } 205 206 V8_INLINE void Store(const void* ptr) { ptr_ = ptr; } 207 V8_INLINE void StoreAtomic(const void* ptr) { 208 reinterpret_cast
&>(ptr_).store( 209 ptr, std::memory_order_relaxed); 210 } 211 212 V8_INLINE void Clear() { ptr_ = nullptr; } 213 V8_INLINE bool IsCleared() const { return !ptr_; } 214 215 V8_INLINE bool IsSentinel() const { return ptr_ == kSentinelPointer; } 216 217 V8_INLINE uintptr_t GetAsInteger() const { 218 return reinterpret_cast
(ptr_); 219 } 220 221 V8_INLINE friend bool operator==(RawPointer a, RawPointer b) { 222 return a.ptr_ == b.ptr_; 223 } 224 V8_INLINE friend bool operator!=(RawPointer a, RawPointer b) { 225 return a.ptr_ != b.ptr_; 226 } 227 V8_INLINE friend bool operator<(RawPointer a, RawPointer b) { 228 return a.ptr_ < b.ptr_; 229 } 230 V8_INLINE friend bool operator<=(RawPointer a, RawPointer b) { 231 return a.ptr_ <= b.ptr_; 232 } 233 V8_INLINE friend bool operator>(RawPointer a, RawPointer b) { 234 return a.ptr_ > b.ptr_; 235 } 236 V8_INLINE friend bool operator>=(RawPointer a, RawPointer b) { 237 return a.ptr_ >= b.ptr_; 238 } 239 240 private: 241 // All constructors initialize `ptr_`. Do not add a default value here as it 242 // results in a non-atomic write on some builds, even when the atomic version 243 // of the constructor is used. 244 const void* ptr_; 245 }; 246 247 #if defined(CPPGC_POINTER_COMPRESSION) 248 using DefaultMemberStorage = CompressedPointer; 249 #else // !defined(CPPGC_POINTER_COMPRESSION) 250 using DefaultMemberStorage = RawPointer; 251 #endif // !defined(CPPGC_POINTER_COMPRESSION) 252 253 } // namespace internal 254 } // namespace cppgc 255 256 #endif // INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2026 MyWebUniversity.com ™