libv8-node 15.14.0.1-aarch64-linux-musl → 16.19.0.0-aarch64-linux-musl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/libv8-node/location.rb +1 -1
- data/ext/libv8-node/paths.rb +5 -1
- data/lib/libv8/node/version.rb +3 -3
- data/vendor/v8/{out.gn → aarch64-linux-musl}/libv8/obj/libv8_monolith.a +0 -0
- data/vendor/v8/include/cppgc/allocation.h +105 -45
- data/vendor/v8/include/cppgc/common.h +9 -6
- data/vendor/v8/include/cppgc/cross-thread-persistent.h +413 -0
- data/vendor/v8/include/cppgc/custom-space.h +37 -2
- data/vendor/v8/include/cppgc/default-platform.h +47 -48
- data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
- data/vendor/v8/include/cppgc/explicit-management.h +82 -0
- data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
- data/vendor/v8/include/cppgc/heap-consistency.h +253 -0
- data/vendor/v8/include/cppgc/heap-state.h +70 -0
- data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
- data/vendor/v8/include/cppgc/heap.h +68 -6
- data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
- data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +2 -1
- data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
- data/vendor/v8/include/cppgc/internal/gc-info.h +44 -13
- data/vendor/v8/include/cppgc/internal/name-trait.h +111 -0
- data/vendor/v8/include/cppgc/internal/persistent-node.h +58 -2
- data/vendor/v8/include/cppgc/internal/pointer-policies.h +69 -28
- data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
- data/vendor/v8/include/cppgc/internal/write-barrier.h +390 -35
- data/vendor/v8/include/cppgc/liveness-broker.h +11 -2
- data/vendor/v8/include/cppgc/macros.h +2 -0
- data/vendor/v8/include/cppgc/member.h +87 -25
- data/vendor/v8/include/cppgc/name-provider.h +65 -0
- data/vendor/v8/include/cppgc/object-size-trait.h +58 -0
- data/vendor/v8/include/cppgc/persistent.h +40 -10
- data/vendor/v8/include/cppgc/platform.h +49 -25
- data/vendor/v8/include/cppgc/prefinalizer.h +1 -1
- data/vendor/v8/include/cppgc/process-heap-statistics.h +36 -0
- data/vendor/v8/include/cppgc/sentinel-pointer.h +32 -0
- data/vendor/v8/include/cppgc/source-location.h +2 -1
- data/vendor/v8/include/cppgc/testing.h +99 -0
- data/vendor/v8/include/cppgc/trace-trait.h +8 -3
- data/vendor/v8/include/cppgc/type-traits.h +157 -19
- data/vendor/v8/include/cppgc/visitor.h +194 -28
- data/vendor/v8/include/libplatform/libplatform.h +11 -0
- data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
- data/vendor/v8/include/v8-cppgc.h +258 -159
- data/vendor/v8/include/v8-fast-api-calls.h +603 -155
- data/vendor/v8/include/v8-inspector.h +22 -4
- data/vendor/v8/include/v8-internal.h +111 -27
- data/vendor/v8/include/v8-metrics.h +77 -8
- data/vendor/v8/include/v8-platform.h +47 -22
- data/vendor/v8/include/v8-profiler.h +75 -11
- data/vendor/v8/include/v8-unwinder-state.h +30 -0
- data/vendor/v8/include/v8-util.h +1 -1
- data/vendor/v8/include/v8-version.h +4 -4
- data/vendor/v8/include/v8.h +1196 -642
- data/vendor/v8/include/v8config.h +87 -11
- metadata +17 -5
- data/vendor/v8/include/cppgc/internal/process-heap.h +0 -34
| @@ -10,6 +10,7 @@ | |
| 10 10 | 
             
            #include <type_traits>
         | 
| 11 11 |  | 
| 12 12 | 
             
            #include "cppgc/internal/pointer-policies.h"
         | 
| 13 | 
            +
            #include "cppgc/sentinel-pointer.h"
         | 
| 13 14 | 
             
            #include "cppgc/type-traits.h"
         | 
| 14 15 | 
             
            #include "v8config.h"  // NOLINT(build/include_directory)
         | 
| 15 16 |  | 
| @@ -19,28 +20,33 @@ class Visitor; | |
| 19 20 |  | 
| 20 21 | 
             
            namespace internal {
         | 
| 21 22 |  | 
| 23 | 
            +
            // MemberBase always refers to the object as const object and defers to
         | 
| 24 | 
            +
            // BasicMember on casting to the right type as needed.
         | 
| 22 25 | 
             
            class MemberBase {
         | 
| 23 26 | 
             
             protected:
         | 
| 27 | 
            +
              struct AtomicInitializerTag {};
         | 
| 28 | 
            +
             | 
| 24 29 | 
             
              MemberBase() = default;
         | 
| 25 | 
            -
              explicit MemberBase(void* value) : raw_(value) {}
         | 
| 30 | 
            +
              explicit MemberBase(const void* value) : raw_(value) {}
         | 
| 31 | 
            +
              MemberBase(const void* value, AtomicInitializerTag) { SetRawAtomic(value); }
         | 
| 26 32 |  | 
| 27 | 
            -
              void | 
| 28 | 
            -
              void* GetRaw() const { return raw_; }
         | 
| 33 | 
            +
              const void** GetRawSlot() const { return &raw_; }
         | 
| 34 | 
            +
              const void* GetRaw() const { return raw_; }
         | 
| 29 35 | 
             
              void SetRaw(void* value) { raw_ = value; }
         | 
| 30 36 |  | 
| 31 | 
            -
              void* GetRawAtomic() const {
         | 
| 32 | 
            -
                return reinterpret_cast<const std::atomic<void*>*>(&raw_)->load(
         | 
| 37 | 
            +
              const void* GetRawAtomic() const {
         | 
| 38 | 
            +
                return reinterpret_cast<const std::atomic<const void*>*>(&raw_)->load(
         | 
| 33 39 | 
             
                    std::memory_order_relaxed);
         | 
| 34 40 | 
             
              }
         | 
| 35 | 
            -
              void SetRawAtomic(void* value) {
         | 
| 36 | 
            -
                reinterpret_cast<std::atomic<void*>*>(&raw_)->store(
         | 
| 41 | 
            +
              void SetRawAtomic(const void* value) {
         | 
| 42 | 
            +
                reinterpret_cast<std::atomic<const void*>*>(&raw_)->store(
         | 
| 37 43 | 
             
                    value, std::memory_order_relaxed);
         | 
| 38 44 | 
             
              }
         | 
| 39 45 |  | 
| 40 46 | 
             
              void ClearFromGC() const { raw_ = nullptr; }
         | 
| 41 47 |  | 
| 42 48 | 
             
             private:
         | 
| 43 | 
            -
              mutable void* raw_ = nullptr;
         | 
| 49 | 
            +
              mutable const void* raw_ = nullptr;
         | 
| 44 50 | 
             
            };
         | 
| 45 51 |  | 
| 46 52 | 
             
            // The basic class from which all Member classes are 'generated'.
         | 
| @@ -58,6 +64,21 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 58 64 | 
             
                this->CheckPointer(Get());
         | 
| 59 65 | 
             
              }
         | 
| 60 66 | 
             
              BasicMember(T& raw) : BasicMember(&raw) {}  // NOLINT
         | 
| 67 | 
            +
              // Atomic ctor. Using the AtomicInitializerTag forces BasicMember to
         | 
| 68 | 
            +
              // initialize using atomic assignments. This is required for preventing
         | 
| 69 | 
            +
              // data races with concurrent marking.
         | 
| 70 | 
            +
              using AtomicInitializerTag = MemberBase::AtomicInitializerTag;
         | 
| 71 | 
            +
              BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
         | 
| 72 | 
            +
                  : MemberBase(nullptr, atomic) {}
         | 
| 73 | 
            +
              BasicMember(SentinelPointer s, AtomicInitializerTag atomic)
         | 
| 74 | 
            +
                  : MemberBase(s, atomic) {}
         | 
| 75 | 
            +
              BasicMember(T* raw, AtomicInitializerTag atomic) : MemberBase(raw, atomic) {
         | 
| 76 | 
            +
                InitializingWriteBarrier();
         | 
| 77 | 
            +
                this->CheckPointer(Get());
         | 
| 78 | 
            +
              }
         | 
| 79 | 
            +
              BasicMember(T& raw, AtomicInitializerTag atomic)
         | 
| 80 | 
            +
                  : BasicMember(&raw, atomic) {}
         | 
| 81 | 
            +
              // Copy ctor.
         | 
| 61 82 | 
             
              BasicMember(const BasicMember& other) : BasicMember(other.Get()) {}
         | 
| 62 83 | 
             
              // Allow heterogeneous construction.
         | 
| 63 84 | 
             
              template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
         | 
| @@ -67,21 +88,34 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 67 88 | 
             
                  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
         | 
| 68 89 | 
             
                                    OtherCheckingPolicy>& other)
         | 
| 69 90 | 
             
                  : BasicMember(other.Get()) {}
         | 
| 91 | 
            +
              // Move ctor.
         | 
| 92 | 
            +
              BasicMember(BasicMember&& other) noexcept : BasicMember(other.Get()) {
         | 
| 93 | 
            +
                other.Clear();
         | 
| 94 | 
            +
              }
         | 
| 95 | 
            +
              // Allow heterogeneous move construction.
         | 
| 96 | 
            +
              template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
         | 
| 97 | 
            +
                        typename OtherCheckingPolicy,
         | 
| 98 | 
            +
                        typename = std::enable_if_t<std::is_base_of<T, U>::value>>
         | 
| 99 | 
            +
              BasicMember(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
         | 
| 100 | 
            +
                                      OtherCheckingPolicy>&& other) noexcept
         | 
| 101 | 
            +
                  : BasicMember(other.Get()) {
         | 
| 102 | 
            +
                other.Clear();
         | 
| 103 | 
            +
              }
         | 
| 70 104 | 
             
              // Construction from Persistent.
         | 
| 71 105 | 
             
              template <typename U, typename PersistentWeaknessPolicy,
         | 
| 72 106 | 
             
                        typename PersistentLocationPolicy,
         | 
| 73 107 | 
             
                        typename PersistentCheckingPolicy,
         | 
| 74 108 | 
             
                        typename = std::enable_if_t<std::is_base_of<T, U>::value>>
         | 
| 75 | 
            -
              BasicMember( | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
                      p)
         | 
| 109 | 
            +
              BasicMember(const BasicPersistent<U, PersistentWeaknessPolicy,
         | 
| 110 | 
            +
                                                PersistentLocationPolicy,
         | 
| 111 | 
            +
                                                PersistentCheckingPolicy>& p)
         | 
| 79 112 | 
             
                  : BasicMember(p.Get()) {}
         | 
| 80 113 |  | 
| 114 | 
            +
              // Copy assignment.
         | 
| 81 115 | 
             
              BasicMember& operator=(const BasicMember& other) {
         | 
| 82 116 | 
             
                return operator=(other.Get());
         | 
| 83 117 | 
             
              }
         | 
| 84 | 
            -
              // Allow heterogeneous assignment.
         | 
| 118 | 
            +
              // Allow heterogeneous copy assignment.
         | 
| 85 119 | 
             
              template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
         | 
| 86 120 | 
             
                        typename OtherCheckingPolicy,
         | 
| 87 121 | 
             
                        typename = std::enable_if_t<std::is_base_of<T, U>::value>>
         | 
| @@ -90,6 +124,22 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 90 124 | 
             
                                    OtherCheckingPolicy>& other) {
         | 
| 91 125 | 
             
                return operator=(other.Get());
         | 
| 92 126 | 
             
              }
         | 
| 127 | 
            +
              // Move assignment.
         | 
| 128 | 
            +
              BasicMember& operator=(BasicMember&& other) noexcept {
         | 
| 129 | 
            +
                operator=(other.Get());
         | 
| 130 | 
            +
                other.Clear();
         | 
| 131 | 
            +
                return *this;
         | 
| 132 | 
            +
              }
         | 
| 133 | 
            +
              // Heterogeneous move assignment.
         | 
| 134 | 
            +
              template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
         | 
| 135 | 
            +
                        typename OtherCheckingPolicy,
         | 
| 136 | 
            +
                        typename = std::enable_if_t<std::is_base_of<T, U>::value>>
         | 
| 137 | 
            +
              BasicMember& operator=(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
         | 
| 138 | 
            +
                                                 OtherCheckingPolicy>&& other) noexcept {
         | 
| 139 | 
            +
                operator=(other.Get());
         | 
| 140 | 
            +
                other.Clear();
         | 
| 141 | 
            +
                return *this;
         | 
| 142 | 
            +
              }
         | 
| 93 143 | 
             
              // Assignment from Persistent.
         | 
| 94 144 | 
             
              template <typename U, typename PersistentWeaknessPolicy,
         | 
| 95 145 | 
             
                        typename PersistentLocationPolicy,
         | 
| @@ -126,7 +176,7 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 126 176 | 
             
              }
         | 
| 127 177 |  | 
| 128 178 | 
             
              explicit operator bool() const { return Get(); }
         | 
| 129 | 
            -
              operator T*() const { return Get(); } | 
| 179 | 
            +
              operator T*() const { return Get(); }
         | 
| 130 180 | 
             
              T* operator->() const { return Get(); }
         | 
| 131 181 | 
             
              T& operator*() const { return *Get(); }
         | 
| 132 182 |  | 
| @@ -135,7 +185,11 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 135 185 | 
             
              // based on their actual types.
         | 
| 136 186 | 
             
              V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
         | 
| 137 187 | 
             
                // Executed by the mutator, hence non atomic load.
         | 
| 138 | 
            -
                 | 
| 188 | 
            +
                //
         | 
| 189 | 
            +
                // The const_cast below removes the constness from MemberBase storage. The
         | 
| 190 | 
            +
                // following static_cast re-adds any constness if specified through the
         | 
| 191 | 
            +
                // user-visible template parameter T.
         | 
| 192 | 
            +
                return static_cast<T*>(const_cast<void*>(MemberBase::GetRaw()));
         | 
| 139 193 | 
             
              }
         | 
| 140 194 |  | 
| 141 195 | 
             
              void Clear() { SetRawAtomic(nullptr); }
         | 
| @@ -146,9 +200,13 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 146 200 | 
             
                return result;
         | 
| 147 201 | 
             
              }
         | 
| 148 202 |  | 
| 203 | 
            +
              const T** GetSlotForTesting() const {
         | 
| 204 | 
            +
                return reinterpret_cast<const T**>(GetRawSlot());
         | 
| 205 | 
            +
              }
         | 
| 206 | 
            +
             | 
| 149 207 | 
             
             private:
         | 
| 150 | 
            -
              T* GetRawAtomic() const {
         | 
| 151 | 
            -
                return static_cast<T*>(MemberBase::GetRawAtomic());
         | 
| 208 | 
            +
              const T* GetRawAtomic() const {
         | 
| 209 | 
            +
                return static_cast<const T*>(MemberBase::GetRawAtomic());
         | 
| 152 210 | 
             
              }
         | 
| 153 211 |  | 
| 154 212 | 
             
              void InitializingWriteBarrier() const {
         | 
| @@ -160,26 +218,30 @@ class BasicMember final : private MemberBase, private CheckingPolicy { | |
| 160 218 |  | 
| 161 219 | 
             
              void ClearFromGC() const { MemberBase::ClearFromGC(); }
         | 
| 162 220 |  | 
| 221 | 
            +
              T* GetFromGC() const { return Get(); }
         | 
| 222 | 
            +
             | 
| 163 223 | 
             
              friend class cppgc::Visitor;
         | 
| 224 | 
            +
              template <typename U>
         | 
| 225 | 
            +
              friend struct cppgc::TraceTrait;
         | 
| 164 226 | 
             
            };
         | 
| 165 227 |  | 
| 166 228 | 
             
            template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
         | 
| 167 229 | 
             
                      typename CheckingPolicy1, typename T2, typename WeaknessTag2,
         | 
| 168 230 | 
             
                      typename WriteBarrierPolicy2, typename CheckingPolicy2>
         | 
| 169 | 
            -
            bool operator==(
         | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 231 | 
            +
            bool operator==(const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1,
         | 
| 232 | 
            +
                                              CheckingPolicy1>& member1,
         | 
| 233 | 
            +
                            const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2,
         | 
| 234 | 
            +
                                              CheckingPolicy2>& member2) {
         | 
| 173 235 | 
             
              return member1.Get() == member2.Get();
         | 
| 174 236 | 
             
            }
         | 
| 175 237 |  | 
| 176 238 | 
             
            template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
         | 
| 177 239 | 
             
                      typename CheckingPolicy1, typename T2, typename WeaknessTag2,
         | 
| 178 240 | 
             
                      typename WriteBarrierPolicy2, typename CheckingPolicy2>
         | 
| 179 | 
            -
            bool operator!=(
         | 
| 180 | 
            -
             | 
| 181 | 
            -
             | 
| 182 | 
            -
             | 
| 241 | 
            +
            bool operator!=(const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1,
         | 
| 242 | 
            +
                                              CheckingPolicy1>& member1,
         | 
| 243 | 
            +
                            const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2,
         | 
| 244 | 
            +
                                              CheckingPolicy2>& member2) {
         | 
| 183 245 | 
             
              return !(member1 == member2);
         | 
| 184 246 | 
             
            }
         | 
| 185 247 |  | 
| @@ -0,0 +1,65 @@ | |
| 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_NAME_PROVIDER_H_
         | 
| 6 | 
            +
            #define INCLUDE_CPPGC_NAME_PROVIDER_H_
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            #include "v8config.h"  // NOLINT(build/include_directory)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            namespace cppgc {
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            /**
         | 
| 13 | 
            +
             * NameProvider allows for providing a human-readable name for garbage-collected
         | 
| 14 | 
            +
             * objects.
         | 
| 15 | 
            +
             *
         | 
| 16 | 
            +
             * There's two cases of names to distinguish:
         | 
| 17 | 
            +
             * a. Explicitly specified names via using NameProvider. Such names are always
         | 
| 18 | 
            +
             *    preserved in the system.
         | 
| 19 | 
            +
             * b. Internal names that Oilpan infers from a C++ type on the class hierarchy
         | 
| 20 | 
            +
             *    of the object. This is not necessarily the type of the actually
         | 
| 21 | 
            +
             *    instantiated object.
         | 
| 22 | 
            +
             *
         | 
| 23 | 
            +
             * Depending on the build configuration, Oilpan may hide names, i.e., represent
         | 
| 24 | 
            +
             * them with kHiddenName, of case b. to avoid exposing internal details.
         | 
| 25 | 
            +
             */
         | 
| 26 | 
            +
            class V8_EXPORT NameProvider {
         | 
| 27 | 
            +
             public:
         | 
| 28 | 
            +
              /**
         | 
| 29 | 
            +
               * Name that is used when hiding internals.
         | 
| 30 | 
            +
               */
         | 
| 31 | 
            +
              static constexpr const char kHiddenName[] = "InternalNode";
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              /**
         | 
| 34 | 
            +
               * Name that is used in case compiler support is missing for composing a name
         | 
| 35 | 
            +
               * from C++ types.
         | 
| 36 | 
            +
               */
         | 
| 37 | 
            +
              static constexpr const char kNoNameDeducible[] = "<No name>";
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              /**
         | 
| 40 | 
            +
               * Indicating whether internal names are hidden or not.
         | 
| 41 | 
            +
               *
         | 
| 42 | 
            +
               * @returns true if C++ names should be hidden and represented by kHiddenName.
         | 
| 43 | 
            +
               */
         | 
| 44 | 
            +
              static constexpr bool HideInternalNames() {
         | 
| 45 | 
            +
            #if CPPGC_SUPPORTS_OBJECT_NAMES
         | 
| 46 | 
            +
                return false;
         | 
| 47 | 
            +
            #else   // !CPPGC_SUPPORTS_OBJECT_NAMES
         | 
| 48 | 
            +
                return true;
         | 
| 49 | 
            +
            #endif  // !CPPGC_SUPPORTS_OBJECT_NAMES
         | 
| 50 | 
            +
              }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              virtual ~NameProvider() = default;
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              /**
         | 
| 55 | 
            +
               * Specifies a name for the garbage-collected object. Such names will never
         | 
| 56 | 
            +
               * be hidden, as they are explicitly specified by the user of this API.
         | 
| 57 | 
            +
               *
         | 
| 58 | 
            +
               * @returns a human readable name for the object.
         | 
| 59 | 
            +
               */
         | 
| 60 | 
            +
              virtual const char* GetHumanReadableName() const = 0;
         | 
| 61 | 
            +
            };
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            }  // namespace cppgc
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            #endif  // INCLUDE_CPPGC_NAME_PROVIDER_H_
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            // Copyright 2021 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_OBJECT_SIZE_TRAIT_H_
         | 
| 6 | 
            +
            #define INCLUDE_CPPGC_OBJECT_SIZE_TRAIT_H_
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            #include <cstddef>
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            #include "cppgc/type-traits.h"
         | 
| 11 | 
            +
            #include "v8config.h"  // NOLINT(build/include_directory)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            namespace cppgc {
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            namespace internal {
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            struct V8_EXPORT BaseObjectSizeTrait {
         | 
| 18 | 
            +
             protected:
         | 
| 19 | 
            +
              static size_t GetObjectSizeForGarbageCollected(const void*);
         | 
| 20 | 
            +
              static size_t GetObjectSizeForGarbageCollectedMixin(const void*);
         | 
| 21 | 
            +
            };
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            }  // namespace internal
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            namespace subtle {
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            /**
         | 
| 28 | 
            +
             * Trait specifying how to get the size of an object that was allocated using
         | 
| 29 | 
            +
             * `MakeGarbageCollected()`. Also supports querying the size with an inner
         | 
| 30 | 
            +
             * pointer to a mixin.
         | 
| 31 | 
            +
             */
         | 
| 32 | 
            +
            template <typename T, bool = IsGarbageCollectedMixinTypeV<T>>
         | 
| 33 | 
            +
            struct ObjectSizeTrait;
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            template <typename T>
         | 
| 36 | 
            +
            struct ObjectSizeTrait<T, false> : cppgc::internal::BaseObjectSizeTrait {
         | 
| 37 | 
            +
              static_assert(sizeof(T), "T must be fully defined");
         | 
| 38 | 
            +
              static_assert(IsGarbageCollectedTypeV<T>,
         | 
| 39 | 
            +
                            "T must be of type GarbageCollected or GarbageCollectedMixin");
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              static size_t GetSize(const T& object) {
         | 
| 42 | 
            +
                return GetObjectSizeForGarbageCollected(&object);
         | 
| 43 | 
            +
              }
         | 
| 44 | 
            +
            };
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            template <typename T>
         | 
| 47 | 
            +
            struct ObjectSizeTrait<T, true> : cppgc::internal::BaseObjectSizeTrait {
         | 
| 48 | 
            +
              static_assert(sizeof(T), "T must be fully defined");
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              static size_t GetSize(const T& object) {
         | 
| 51 | 
            +
                return GetObjectSizeForGarbageCollectedMixin(&object);
         | 
| 52 | 
            +
              }
         | 
| 53 | 
            +
            };
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            }  // namespace subtle
         | 
| 56 | 
            +
            }  // namespace cppgc
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            #endif  // INCLUDE_CPPGC_OBJECT_SIZE_TRAIT_H_
         | 
| @@ -9,6 +9,7 @@ | |
| 9 9 |  | 
| 10 10 | 
             
            #include "cppgc/internal/persistent-node.h"
         | 
| 11 11 | 
             
            #include "cppgc/internal/pointer-policies.h"
         | 
| 12 | 
            +
            #include "cppgc/sentinel-pointer.h"
         | 
| 12 13 | 
             
            #include "cppgc/source-location.h"
         | 
| 13 14 | 
             
            #include "cppgc/type-traits.h"
         | 
| 14 15 | 
             
            #include "cppgc/visitor.h"
         | 
| @@ -20,13 +21,15 @@ class Visitor; | |
| 20 21 |  | 
| 21 22 | 
             
            namespace internal {
         | 
| 22 23 |  | 
| 24 | 
            +
            // PersistentBase always refers to the object as const object and defers to
         | 
| 25 | 
            +
            // BasicPersistent on casting to the right type as needed.
         | 
| 23 26 | 
             
            class PersistentBase {
         | 
| 24 27 | 
             
             protected:
         | 
| 25 28 | 
             
              PersistentBase() = default;
         | 
| 26 | 
            -
              explicit PersistentBase(void* raw) : raw_(raw) {}
         | 
| 29 | 
            +
              explicit PersistentBase(const void* raw) : raw_(raw) {}
         | 
| 27 30 |  | 
| 28 | 
            -
              void* GetValue() const { return raw_; }
         | 
| 29 | 
            -
              void SetValue(void* value) { raw_ = value; }
         | 
| 31 | 
            +
              const void* GetValue() const { return raw_; }
         | 
| 32 | 
            +
              void SetValue(const void* value) { raw_ = value; }
         | 
| 30 33 |  | 
| 31 34 | 
             
              PersistentNode* GetNode() const { return node_; }
         | 
| 32 35 | 
             
              void SetNode(PersistentNode* node) { node_ = node; }
         | 
| @@ -38,8 +41,8 @@ class PersistentBase { | |
| 38 41 | 
             
                node_ = nullptr;
         | 
| 39 42 | 
             
              }
         | 
| 40 43 |  | 
| 41 | 
            -
              | 
| 42 | 
            -
              mutable void* raw_ = nullptr;
         | 
| 44 | 
            +
             protected:
         | 
| 45 | 
            +
              mutable const void* raw_ = nullptr;
         | 
| 43 46 | 
             
              mutable PersistentNode* node_ = nullptr;
         | 
| 44 47 |  | 
| 45 48 | 
             
              friend class PersistentRegion;
         | 
| @@ -92,7 +95,7 @@ class BasicPersistent final : public PersistentBase, | |
| 92 95 | 
             
              template <typename U, typename OtherWeaknessPolicy,
         | 
| 93 96 | 
             
                        typename OtherLocationPolicy, typename OtherCheckingPolicy,
         | 
| 94 97 | 
             
                        typename = std::enable_if_t<std::is_base_of<T, U>::value>>
         | 
| 95 | 
            -
              BasicPersistent( | 
| 98 | 
            +
              BasicPersistent(
         | 
| 96 99 | 
             
                  const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
         | 
| 97 100 | 
             
                                        OtherCheckingPolicy>& other,
         | 
| 98 101 | 
             
                  const SourceLocation& loc = SourceLocation::Current())
         | 
| @@ -115,7 +118,7 @@ class BasicPersistent final : public PersistentBase, | |
| 115 118 | 
             
              template <typename U, typename MemberBarrierPolicy,
         | 
| 116 119 | 
             
                        typename MemberWeaknessTag, typename MemberCheckingPolicy,
         | 
| 117 120 | 
             
                        typename = std::enable_if_t<std::is_base_of<T, U>::value>>
         | 
| 118 | 
            -
              BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy, | 
| 121 | 
            +
              BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy,
         | 
| 119 122 | 
             
                                                    MemberWeaknessTag, MemberCheckingPolicy>
         | 
| 120 123 | 
             
                                  member,
         | 
| 121 124 | 
             
                              const SourceLocation& loc = SourceLocation::Current())
         | 
| @@ -138,7 +141,7 @@ class BasicPersistent final : public PersistentBase, | |
| 138 141 | 
             
              }
         | 
| 139 142 |  | 
| 140 143 | 
             
              // Move assignment.
         | 
| 141 | 
            -
              BasicPersistent& operator=(BasicPersistent&& other) {
         | 
| 144 | 
            +
              BasicPersistent& operator=(BasicPersistent&& other) noexcept {
         | 
| 142 145 | 
             
                if (this == &other) return *this;
         | 
| 143 146 | 
             
                Clear();
         | 
| 144 147 | 
             
                PersistentBase::operator=(std::move(other));
         | 
| @@ -186,10 +189,21 @@ class BasicPersistent final : public PersistentBase, | |
| 186 189 | 
             
              // heterogeneous assignments between different Member and Persistent handles
         | 
| 187 190 | 
             
              // based on their actual types.
         | 
| 188 191 | 
             
              V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
         | 
| 189 | 
            -
                 | 
| 192 | 
            +
                // The const_cast below removes the constness from PersistentBase storage.
         | 
| 193 | 
            +
                // The 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*>(GetValue()));
         | 
| 190 196 | 
             
              }
         | 
| 191 197 |  | 
| 192 | 
            -
              void Clear() { | 
| 198 | 
            +
              void Clear() {
         | 
| 199 | 
            +
                // Simplified version of `Assign()` to allow calling without a complete type
         | 
| 200 | 
            +
                // `T`.
         | 
| 201 | 
            +
                if (IsValid()) {
         | 
| 202 | 
            +
                  WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
         | 
| 203 | 
            +
                  SetNode(nullptr);
         | 
| 204 | 
            +
                }
         | 
| 205 | 
            +
                SetValue(nullptr);
         | 
| 206 | 
            +
              }
         | 
| 193 207 |  | 
| 194 208 | 
             
              T* Release() {
         | 
| 195 209 | 
             
                T* result = Get();
         | 
| @@ -197,6 +211,16 @@ class BasicPersistent final : public PersistentBase, | |
| 197 211 | 
             
                return result;
         | 
| 198 212 | 
             
              }
         | 
| 199 213 |  | 
| 214 | 
            +
              template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy,
         | 
| 215 | 
            +
                        typename OtherLocationPolicy = LocationPolicy,
         | 
| 216 | 
            +
                        typename OtherCheckingPolicy = CheckingPolicy>
         | 
| 217 | 
            +
              BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
         | 
| 218 | 
            +
                              OtherCheckingPolicy>
         | 
| 219 | 
            +
              To() const {
         | 
| 220 | 
            +
                return BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
         | 
| 221 | 
            +
                                       OtherCheckingPolicy>(static_cast<U*>(Get()));
         | 
| 222 | 
            +
              }
         | 
| 223 | 
            +
             | 
| 200 224 | 
             
             private:
         | 
| 201 225 | 
             
              static void Trace(Visitor* v, const void* ptr) {
         | 
| 202 226 | 
             
                const auto* persistent = static_cast<const BasicPersistent*>(ptr);
         | 
| @@ -235,6 +259,12 @@ class BasicPersistent final : public PersistentBase, | |
| 235 259 | 
             
                }
         | 
| 236 260 | 
             
              }
         | 
| 237 261 |  | 
| 262 | 
            +
              // Set Get() for details.
         | 
| 263 | 
            +
              V8_CLANG_NO_SANITIZE("cfi-unrelated-cast")
         | 
| 264 | 
            +
              T* GetFromGC() const {
         | 
| 265 | 
            +
                return static_cast<T*>(const_cast<void*>(GetValue()));
         | 
| 266 | 
            +
              }
         | 
| 267 | 
            +
             | 
| 238 268 | 
             
              friend class cppgc::Visitor;
         | 
| 239 269 | 
             
            };
         | 
| 240 270 |  | 
| @@ -5,6 +5,8 @@ | |
| 5 5 | 
             
            #ifndef INCLUDE_CPPGC_PLATFORM_H_
         | 
| 6 6 | 
             
            #define INCLUDE_CPPGC_PLATFORM_H_
         | 
| 7 7 |  | 
| 8 | 
            +
            #include <memory>
         | 
| 9 | 
            +
             | 
| 8 10 | 
             
            #include "v8-platform.h"  // NOLINT(build/include_directory)
         | 
| 9 11 | 
             
            #include "v8config.h"     // NOLINT(build/include_directory)
         | 
| 10 12 |  | 
| @@ -20,6 +22,7 @@ using PageAllocator = v8::PageAllocator; | |
| 20 22 | 
             
            using Task = v8::Task;
         | 
| 21 23 | 
             
            using TaskPriority = v8::TaskPriority;
         | 
| 22 24 | 
             
            using TaskRunner = v8::TaskRunner;
         | 
| 25 | 
            +
            using TracingController = v8::TracingController;
         | 
| 23 26 |  | 
| 24 27 | 
             
            /**
         | 
| 25 28 | 
             
             * Platform interface used by Heap. Contains allocators and executors.
         | 
| @@ -51,22 +54,23 @@ class V8_EXPORT Platform { | |
| 51 54 | 
             
              }
         | 
| 52 55 |  | 
| 53 56 | 
             
              /**
         | 
| 54 | 
            -
               * Posts  | 
| 55 | 
            -
               * the Job | 
| 57 | 
            +
               * Posts `job_task` to run in parallel. Returns a `JobHandle` associated with
         | 
| 58 | 
            +
               * the `Job`, which can be joined or canceled.
         | 
| 56 59 | 
             
               * This avoids degenerate cases:
         | 
| 57 | 
            -
               * - Calling CallOnWorkerThread() for each work item, causing significant
         | 
| 60 | 
            +
               * - Calling `CallOnWorkerThread()` for each work item, causing significant
         | 
| 58 61 | 
             
               *   overhead.
         | 
| 59 | 
            -
               * - Fixed number of CallOnWorkerThread() calls that split the work and | 
| 60 | 
            -
               *   run for a long time. This is problematic when many components post
         | 
| 62 | 
            +
               * - Fixed number of `CallOnWorkerThread()` calls that split the work and
         | 
| 63 | 
            +
               *   might run for a long time. This is problematic when many components post
         | 
| 61 64 | 
             
               *   "num cores" tasks and all expect to use all the cores. In these cases,
         | 
| 62 65 | 
             
               *   the scheduler lacks context to be fair to multiple same-priority requests
         | 
| 63 66 | 
             
               *   and/or ability to request lower priority work to yield when high priority
         | 
| 64 67 | 
             
               *   work comes in.
         | 
| 65 | 
            -
               * A canonical implementation of  | 
| 68 | 
            +
               * A canonical implementation of `job_task` looks like:
         | 
| 69 | 
            +
               * \code
         | 
| 66 70 | 
             
               * class MyJobTask : public JobTask {
         | 
| 67 71 | 
             
               *  public:
         | 
| 68 72 | 
             
               *   MyJobTask(...) : worker_queue_(...) {}
         | 
| 69 | 
            -
               *   // JobTask | 
| 73 | 
            +
               *   // JobTask implementation.
         | 
| 70 74 | 
             
               *   void Run(JobDelegate* delegate) override {
         | 
| 71 75 | 
             
               *     while (!delegate->ShouldYield()) {
         | 
| 72 76 | 
             
               *       // Smallest unit of work.
         | 
| @@ -80,43 +84,62 @@ class V8_EXPORT Platform { | |
| 80 84 | 
             
               *     return worker_queue_.GetSize(); // Thread safe.
         | 
| 81 85 | 
             
               *   }
         | 
| 82 86 | 
             
               * };
         | 
| 87 | 
            +
               *
         | 
| 88 | 
            +
               * // ...
         | 
| 83 89 | 
             
               * auto handle = PostJob(TaskPriority::kUserVisible,
         | 
| 84 90 | 
             
               *                       std::make_unique<MyJobTask>(...));
         | 
| 85 91 | 
             
               * handle->Join();
         | 
| 92 | 
            +
               * \endcode
         | 
| 86 93 | 
             
               *
         | 
| 87 | 
            -
               * PostJob() and methods of the returned JobHandle/JobDelegate, must never | 
| 88 | 
            -
               * called while holding a lock that could be acquired by JobTask::Run | 
| 89 | 
            -
               * JobTask::GetMaxConcurrency -- that could result in a deadlock. This | 
| 90 | 
            -
               * because  | 
| 91 | 
            -
               * internal lock (A), hence JobTask::GetMaxConcurrency can only use a lock | 
| 92 | 
            -
               * if that lock is *never* held while calling back into JobHandle from | 
| 93 | 
            -
               * thread (A=>B/B=>A deadlock) and  | 
| 94 | 
            -
               * JobTask::GetMaxConcurrency may be invoked synchronously from | 
| 95 | 
            -
               * (B=>JobHandle::foo=>B deadlock).
         | 
| 94 | 
            +
               * `PostJob()` and methods of the returned JobHandle/JobDelegate, must never
         | 
| 95 | 
            +
               * be called while holding a lock that could be acquired by `JobTask::Run()`
         | 
| 96 | 
            +
               * or `JobTask::GetMaxConcurrency()` -- that could result in a deadlock. This
         | 
| 97 | 
            +
               * is because (1) `JobTask::GetMaxConcurrency()` may be invoked while holding
         | 
| 98 | 
            +
               * internal lock (A), hence `JobTask::GetMaxConcurrency()` can only use a lock
         | 
| 99 | 
            +
               * (B) if that lock is *never* held while calling back into `JobHandle` from
         | 
| 100 | 
            +
               * any thread (A=>B/B=>A deadlock) and (2) `JobTask::Run()` or
         | 
| 101 | 
            +
               * `JobTask::GetMaxConcurrency()` may be invoked synchronously from
         | 
| 102 | 
            +
               * `JobHandle` (B=>JobHandle::foo=>B deadlock).
         | 
| 96 103 | 
             
               *
         | 
| 97 | 
            -
               * A sufficient PostJob() implementation that uses the default Job provided | 
| 98 | 
            -
               * libplatform looks like:
         | 
| 99 | 
            -
               * | 
| 100 | 
            -
               * | 
| 101 | 
            -
               * | 
| 102 | 
            -
               * | 
| 103 | 
            -
               * | 
| 104 | 
            +
               * A sufficient `PostJob()` implementation that uses the default Job provided
         | 
| 105 | 
            +
               * in libplatform looks like:
         | 
| 106 | 
            +
               * \code
         | 
| 107 | 
            +
               * std::unique_ptr<JobHandle> PostJob(
         | 
| 108 | 
            +
               *     TaskPriority priority, std::unique_ptr<JobTask> job_task) override {
         | 
| 109 | 
            +
               *   return std::make_unique<DefaultJobHandle>(
         | 
| 110 | 
            +
               *       std::make_shared<DefaultJobState>(
         | 
| 111 | 
            +
               *           this, std::move(job_task), kNumThreads));
         | 
| 104 112 | 
             
               * }
         | 
| 113 | 
            +
               * \endcode
         | 
| 105 114 | 
             
               */
         | 
| 106 115 | 
             
              virtual std::unique_ptr<JobHandle> PostJob(
         | 
| 107 116 | 
             
                  TaskPriority priority, std::unique_ptr<JobTask> job_task) {
         | 
| 108 117 | 
             
                return nullptr;
         | 
| 109 118 | 
             
              }
         | 
| 119 | 
            +
             | 
| 120 | 
            +
              /**
         | 
| 121 | 
            +
               * Returns an instance of a `TracingController`. This must be non-nullptr. The
         | 
| 122 | 
            +
               * default implementation returns an empty `TracingController` that consumes
         | 
| 123 | 
            +
               * trace data without effect.
         | 
| 124 | 
            +
               */
         | 
| 125 | 
            +
              virtual TracingController* GetTracingController();
         | 
| 110 126 | 
             
            };
         | 
| 111 127 |  | 
| 112 128 | 
             
            /**
         | 
| 113 129 | 
             
             * Process-global initialization of the garbage collector. Must be called before
         | 
| 114 130 | 
             
             * creating a Heap.
         | 
| 131 | 
            +
             *
         | 
| 132 | 
            +
             * Can be called multiple times when paired with `ShutdownProcess()`.
         | 
| 133 | 
            +
             *
         | 
| 134 | 
            +
             * \param page_allocator The allocator used for maintaining meta data. Must not
         | 
| 135 | 
            +
             *   change between multiple calls to InitializeProcess.
         | 
| 115 136 | 
             
             */
         | 
| 116 | 
            -
            V8_EXPORT void InitializeProcess(PageAllocator*);
         | 
| 137 | 
            +
            V8_EXPORT void InitializeProcess(PageAllocator* page_allocator);
         | 
| 117 138 |  | 
| 118 139 | 
             
            /**
         | 
| 119 | 
            -
             * Must be called after destroying the last used heap.
         | 
| 140 | 
            +
             * Must be called after destroying the last used heap. Some process-global
         | 
| 141 | 
            +
             * metadata may not be returned and reused upon a subsequent
         | 
| 142 | 
            +
             * `InitializeProcess()` call.
         | 
| 120 143 | 
             
             */
         | 
| 121 144 | 
             
            V8_EXPORT void ShutdownProcess();
         | 
| 122 145 |  | 
| @@ -125,6 +148,7 @@ namespace internal { | |
| 125 148 | 
             
            V8_EXPORT void Abort();
         | 
| 126 149 |  | 
| 127 150 | 
             
            }  // namespace internal
         | 
| 151 | 
            +
             | 
| 128 152 | 
             
            }  // namespace cppgc
         | 
| 129 153 |  | 
| 130 154 | 
             
            #endif  // INCLUDE_CPPGC_PLATFORM_H_
         | 
| @@ -34,7 +34,7 @@ class PrefinalizerRegistration final { | |
| 34 34 | 
             
             public:                                                                       \
         | 
| 35 35 | 
             
              static bool InvokePreFinalizer(const cppgc::LivenessBroker& liveness_broker, \
         | 
| 36 36 | 
             
                                             void* object) {                               \
         | 
| 37 | 
            -
                static_assert(cppgc:: | 
| 37 | 
            +
                static_assert(cppgc::IsGarbageCollectedOrMixinTypeV<Class>,                \
         | 
| 38 38 | 
             
                              "Only garbage collected objects can have prefinalizers");    \
         | 
| 39 39 | 
             
                Class* self = static_cast<Class*>(object);                                 \
         | 
| 40 40 | 
             
                if (liveness_broker.IsHeapObjectAlive(self)) return false;                 \
         | 
| @@ -0,0 +1,36 @@ | |
| 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_PROCESS_HEAP_STATISTICS_H_
         | 
| 6 | 
            +
            #define INCLUDE_CPPGC_PROCESS_HEAP_STATISTICS_H_
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            #include <atomic>
         | 
| 9 | 
            +
            #include <cstddef>
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #include "v8config.h"  // NOLINT(build/include_directory)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            namespace cppgc {
         | 
| 14 | 
            +
            namespace internal {
         | 
| 15 | 
            +
            class ProcessHeapStatisticsUpdater;
         | 
| 16 | 
            +
            }  // namespace internal
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            class V8_EXPORT ProcessHeapStatistics final {
         | 
| 19 | 
            +
             public:
         | 
| 20 | 
            +
              static size_t TotalAllocatedObjectSize() {
         | 
| 21 | 
            +
                return total_allocated_object_size_.load(std::memory_order_relaxed);
         | 
| 22 | 
            +
              }
         | 
| 23 | 
            +
              static size_t TotalAllocatedSpace() {
         | 
| 24 | 
            +
                return total_allocated_space_.load(std::memory_order_relaxed);
         | 
| 25 | 
            +
              }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
             private:
         | 
| 28 | 
            +
              static std::atomic_size_t total_allocated_space_;
         | 
| 29 | 
            +
              static std::atomic_size_t total_allocated_object_size_;
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              friend class internal::ProcessHeapStatisticsUpdater;
         | 
| 32 | 
            +
            };
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            }  // namespace cppgc
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            #endif  // INCLUDE_CPPGC_PROCESS_HEAP_STATISTICS_H_
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            // Copyright 2021 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_SENTINEL_POINTER_H_
         | 
| 6 | 
            +
            #define INCLUDE_CPPGC_SENTINEL_POINTER_H_
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            #include <cstdint>
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            namespace cppgc {
         | 
| 11 | 
            +
            namespace internal {
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            // Special tag type used to denote some sentinel member. The semantics of the
         | 
| 14 | 
            +
            // sentinel is defined by the embedder.
         | 
| 15 | 
            +
            struct SentinelPointer {
         | 
| 16 | 
            +
              template <typename T>
         | 
| 17 | 
            +
              operator T*() const {
         | 
| 18 | 
            +
                static constexpr intptr_t kSentinelValue = 1;
         | 
| 19 | 
            +
                return reinterpret_cast<T*>(kSentinelValue);
         | 
| 20 | 
            +
              }
         | 
| 21 | 
            +
              // Hidden friends.
         | 
| 22 | 
            +
              friend bool operator==(SentinelPointer, SentinelPointer) { return true; }
         | 
| 23 | 
            +
              friend bool operator!=(SentinelPointer, SentinelPointer) { return false; }
         | 
| 24 | 
            +
            };
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            }  // namespace internal
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            constexpr internal::SentinelPointer kSentinelPointer;
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            }  // namespace cppgc
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            #endif  // INCLUDE_CPPGC_SENTINEL_POINTER_H_
         |