libv8-node 15.5.1.0.beta1-arm64-darwin-20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/ext/libv8-node/.location.yml +2 -0
  3. data/ext/libv8-node/location.rb +91 -0
  4. data/ext/libv8-node/paths.rb +30 -0
  5. data/lib/libv8-node.rb +1 -0
  6. data/lib/libv8/node.rb +11 -0
  7. data/lib/libv8/node/version.rb +7 -0
  8. data/vendor/v8/include/cppgc/allocation.h +173 -0
  9. data/vendor/v8/include/cppgc/common.h +26 -0
  10. data/vendor/v8/include/cppgc/custom-space.h +62 -0
  11. data/vendor/v8/include/cppgc/default-platform.h +76 -0
  12. data/vendor/v8/include/cppgc/garbage-collected.h +116 -0
  13. data/vendor/v8/include/cppgc/heap.h +139 -0
  14. data/vendor/v8/include/cppgc/internal/api-constants.h +47 -0
  15. data/vendor/v8/include/cppgc/internal/atomic-entry-flag.h +48 -0
  16. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +67 -0
  17. data/vendor/v8/include/cppgc/internal/compiler-specific.h +38 -0
  18. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +90 -0
  19. data/vendor/v8/include/cppgc/internal/gc-info.h +45 -0
  20. data/vendor/v8/include/cppgc/internal/logging.h +50 -0
  21. data/vendor/v8/include/cppgc/internal/persistent-node.h +116 -0
  22. data/vendor/v8/include/cppgc/internal/pointer-policies.h +134 -0
  23. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +30 -0
  24. data/vendor/v8/include/cppgc/internal/process-heap.h +34 -0
  25. data/vendor/v8/include/cppgc/internal/write-barrier.h +78 -0
  26. data/vendor/v8/include/cppgc/liveness-broker.h +68 -0
  27. data/vendor/v8/include/cppgc/macros.h +24 -0
  28. data/vendor/v8/include/cppgc/member.h +226 -0
  29. data/vendor/v8/include/cppgc/persistent.h +341 -0
  30. data/vendor/v8/include/cppgc/platform.h +130 -0
  31. data/vendor/v8/include/cppgc/prefinalizer.h +52 -0
  32. data/vendor/v8/include/cppgc/source-location.h +91 -0
  33. data/vendor/v8/include/cppgc/trace-trait.h +111 -0
  34. data/vendor/v8/include/cppgc/type-traits.h +109 -0
  35. data/vendor/v8/include/cppgc/visitor.h +213 -0
  36. data/vendor/v8/include/libplatform/libplatform-export.h +29 -0
  37. data/vendor/v8/include/libplatform/libplatform.h +106 -0
  38. data/vendor/v8/include/libplatform/v8-tracing.h +332 -0
  39. data/vendor/v8/include/v8-cppgc.h +226 -0
  40. data/vendor/v8/include/v8-fast-api-calls.h +388 -0
  41. data/vendor/v8/include/v8-inspector-protocol.h +13 -0
  42. data/vendor/v8/include/v8-inspector.h +327 -0
  43. data/vendor/v8/include/v8-internal.h +427 -0
  44. data/vendor/v8/include/v8-metrics.h +133 -0
  45. data/vendor/v8/include/v8-platform.h +684 -0
  46. data/vendor/v8/include/v8-profiler.h +1059 -0
  47. data/vendor/v8/include/v8-util.h +652 -0
  48. data/vendor/v8/include/v8-value-serializer-version.h +24 -0
  49. data/vendor/v8/include/v8-version-string.h +38 -0
  50. data/vendor/v8/include/v8-version.h +20 -0
  51. data/vendor/v8/include/v8-wasm-trap-handler-posix.h +31 -0
  52. data/vendor/v8/include/v8-wasm-trap-handler-win.h +28 -0
  53. data/vendor/v8/include/v8.h +12098 -0
  54. data/vendor/v8/include/v8config.h +484 -0
  55. data/vendor/v8/out.gn/libv8/obj/libv8_monolith.a +0 -0
  56. metadata +112 -0
@@ -0,0 +1,34 @@
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_INTERNAL_PROCESS_HEAP_H_
6
+ #define INCLUDE_CPPGC_INTERNAL_PROCESS_HEAP_H_
7
+
8
+ #include "cppgc/internal/atomic-entry-flag.h"
9
+ #include "v8config.h" // NOLINT(build/include_directory)
10
+
11
+ namespace cppgc {
12
+ namespace internal {
13
+
14
+ class V8_EXPORT ProcessHeap final {
15
+ public:
16
+ static void EnterIncrementalOrConcurrentMarking() {
17
+ concurrent_marking_flag_.Enter();
18
+ }
19
+ static void ExitIncrementalOrConcurrentMarking() {
20
+ concurrent_marking_flag_.Exit();
21
+ }
22
+
23
+ static bool IsAnyIncrementalOrConcurrentMarking() {
24
+ return concurrent_marking_flag_.MightBeEntered();
25
+ }
26
+
27
+ private:
28
+ static AtomicEntryFlag concurrent_marking_flag_;
29
+ };
30
+
31
+ } // namespace internal
32
+ } // namespace cppgc
33
+
34
+ #endif // INCLUDE_CPPGC_INTERNAL_PROCESS_HEAP_H_
@@ -0,0 +1,78 @@
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_INTERNAL_WRITE_BARRIER_H_
6
+ #define INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
7
+
8
+ #include "cppgc/internal/api-constants.h"
9
+ #include "cppgc/internal/process-heap.h"
10
+ #include "v8config.h" // NOLINT(build/include_directory)
11
+
12
+ #if defined(CPPGC_CAGED_HEAP)
13
+ #include "cppgc/internal/caged-heap-local-data.h"
14
+ #endif
15
+
16
+ namespace cppgc {
17
+ namespace internal {
18
+
19
+ class V8_EXPORT WriteBarrier final {
20
+ public:
21
+ static V8_INLINE void MarkingBarrier(const void* slot, const void* value) {
22
+ #if defined(CPPGC_CAGED_HEAP)
23
+ const uintptr_t start =
24
+ reinterpret_cast<uintptr_t>(value) &
25
+ ~(api_constants::kCagedHeapReservationAlignment - 1);
26
+ const uintptr_t slot_offset = reinterpret_cast<uintptr_t>(slot) - start;
27
+ if (slot_offset > api_constants::kCagedHeapReservationSize) {
28
+ // Check if slot is on stack or value is sentinel or nullptr. This relies
29
+ // on the fact that kSentinelPointer is encoded as 0x1.
30
+ return;
31
+ }
32
+
33
+ CagedHeapLocalData* local_data =
34
+ reinterpret_cast<CagedHeapLocalData*>(start);
35
+ if (V8_UNLIKELY(local_data->is_marking_in_progress)) {
36
+ MarkingBarrierSlow(value);
37
+ return;
38
+ }
39
+ #if defined(CPPGC_YOUNG_GENERATION)
40
+ GenerationalBarrier(local_data, slot, slot_offset,
41
+ reinterpret_cast<uintptr_t>(value) - start);
42
+ #endif
43
+ #else
44
+ if (V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking())) return;
45
+
46
+ MarkingBarrierSlowWithSentinelCheck(value);
47
+ #endif // CPPGC_CAGED_HEAP
48
+ }
49
+
50
+ private:
51
+ WriteBarrier() = delete;
52
+
53
+ static void MarkingBarrierSlow(const void* value);
54
+ static void MarkingBarrierSlowWithSentinelCheck(const void* value);
55
+
56
+ #if defined(CPPGC_YOUNG_GENERATION)
57
+ static V8_INLINE void GenerationalBarrier(CagedHeapLocalData* local_data,
58
+ const void* slot,
59
+ uintptr_t slot_offset,
60
+ uintptr_t value_offset) {
61
+ const AgeTable& age_table = local_data->age_table;
62
+
63
+ // Bail out if the slot is in young generation.
64
+ if (V8_LIKELY(age_table[slot_offset] == AgeTable::Age::kYoung)) return;
65
+
66
+ GenerationalBarrierSlow(local_data, age_table, slot, value_offset);
67
+ }
68
+
69
+ static void GenerationalBarrierSlow(CagedHeapLocalData* local_data,
70
+ const AgeTable& ageTable,
71
+ const void* slot, uintptr_t value_offset);
72
+ #endif
73
+ };
74
+
75
+ } // namespace internal
76
+ } // namespace cppgc
77
+
78
+ #endif // INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
@@ -0,0 +1,68 @@
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_LIVENESS_BROKER_H_
6
+ #define INCLUDE_CPPGC_LIVENESS_BROKER_H_
7
+
8
+ #include "cppgc/heap.h"
9
+ #include "cppgc/member.h"
10
+ #include "cppgc/trace-trait.h"
11
+ #include "v8config.h" // NOLINT(build/include_directory)
12
+
13
+ namespace cppgc {
14
+
15
+ namespace internal {
16
+ class LivenessBrokerFactory;
17
+ } // namespace internal
18
+
19
+ /**
20
+ * The broker is passed to weak callbacks to allow (temporarily) querying
21
+ * the liveness state of an object. References to non-live objects must be
22
+ * cleared when IsHeapObjectAlive() returns false.
23
+ *
24
+ * \code
25
+ * class GCedWithCustomWeakCallback final
26
+ * : public GarbageCollected<GCedWithCustomWeakCallback> {
27
+ * public:
28
+ * UntracedMember<Bar> bar;
29
+ *
30
+ * void CustomWeakCallbackMethod(const LivenessBroker& broker) {
31
+ * if (!broker.IsHeapObjectAlive(bar))
32
+ * bar = nullptr;
33
+ * }
34
+ *
35
+ * void Trace(cppgc::Visitor* visitor) const {
36
+ * visitor->RegisterWeakCallbackMethod<
37
+ * GCedWithCustomWeakCallback,
38
+ * &GCedWithCustomWeakCallback::CustomWeakCallbackMethod>(this);
39
+ * }
40
+ * };
41
+ * \endcode
42
+ */
43
+ class V8_EXPORT LivenessBroker final {
44
+ public:
45
+ template <typename T>
46
+ bool IsHeapObjectAlive(const T* object) const {
47
+ return object &&
48
+ IsHeapObjectAliveImpl(
49
+ TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
50
+ }
51
+
52
+ template <typename T>
53
+ bool IsHeapObjectAlive(const UntracedMember<T>& untraced_member) const {
54
+ return (untraced_member != kSentinelPointer) &&
55
+ IsHeapObjectAlive<T>(untraced_member.Get());
56
+ }
57
+
58
+ private:
59
+ LivenessBroker() = default;
60
+
61
+ bool IsHeapObjectAliveImpl(const void*) const;
62
+
63
+ friend class internal::LivenessBrokerFactory;
64
+ };
65
+
66
+ } // namespace cppgc
67
+
68
+ #endif // INCLUDE_CPPGC_LIVENESS_BROKER_H_
@@ -0,0 +1,24 @@
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_MACROS_H_
6
+ #define INCLUDE_CPPGC_MACROS_H_
7
+
8
+ #include "cppgc/internal/compiler-specific.h"
9
+
10
+ namespace cppgc {
11
+
12
+ // Use if the object is only stack allocated.
13
+ #define CPPGC_STACK_ALLOCATED() \
14
+ public: \
15
+ using IsStackAllocatedTypeMarker CPPGC_UNUSED = int; \
16
+ \
17
+ private: \
18
+ void* operator new(size_t) = delete; \
19
+ void* operator new(size_t, void*) = delete; \
20
+ static_assert(true, "Force semicolon.")
21
+
22
+ } // namespace cppgc
23
+
24
+ #endif // INCLUDE_CPPGC_MACROS_H_
@@ -0,0 +1,226 @@
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
+
12
+ #include "cppgc/internal/pointer-policies.h"
13
+ #include "cppgc/type-traits.h"
14
+ #include "v8config.h" // NOLINT(build/include_directory)
15
+
16
+ namespace cppgc {
17
+
18
+ class Visitor;
19
+
20
+ namespace internal {
21
+
22
+ class MemberBase {
23
+ protected:
24
+ MemberBase() = default;
25
+ explicit MemberBase(void* value) : raw_(value) {}
26
+
27
+ void* const* GetRawSlot() const { return &raw_; }
28
+ void* GetRaw() const { return raw_; }
29
+ void SetRaw(void* value) { raw_ = value; }
30
+
31
+ void* GetRawAtomic() const {
32
+ return reinterpret_cast<const std::atomic<void*>*>(&raw_)->load(
33
+ std::memory_order_relaxed);
34
+ }
35
+ void SetRawAtomic(void* value) {
36
+ reinterpret_cast<std::atomic<void*>*>(&raw_)->store(
37
+ value, std::memory_order_relaxed);
38
+ }
39
+
40
+ void ClearFromGC() const { raw_ = nullptr; }
41
+
42
+ private:
43
+ mutable void* raw_ = nullptr;
44
+ };
45
+
46
+ // The basic class from which all Member classes are 'generated'.
47
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
48
+ typename CheckingPolicy>
49
+ class BasicMember final : private MemberBase, private CheckingPolicy {
50
+ public:
51
+ using PointeeType = T;
52
+
53
+ constexpr BasicMember() = default;
54
+ constexpr BasicMember(std::nullptr_t) {} // NOLINT
55
+ BasicMember(SentinelPointer s) : MemberBase(s) {} // NOLINT
56
+ BasicMember(T* raw) : MemberBase(raw) { // NOLINT
57
+ InitializingWriteBarrier();
58
+ this->CheckPointer(Get());
59
+ }
60
+ BasicMember(T& raw) : BasicMember(&raw) {} // NOLINT
61
+ BasicMember(const BasicMember& other) : BasicMember(other.Get()) {}
62
+ // Allow heterogeneous construction.
63
+ template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
64
+ typename OtherCheckingPolicy,
65
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
66
+ BasicMember( // NOLINT
67
+ const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
68
+ OtherCheckingPolicy>& other)
69
+ : BasicMember(other.Get()) {}
70
+ // Construction from Persistent.
71
+ template <typename U, typename PersistentWeaknessPolicy,
72
+ typename PersistentLocationPolicy,
73
+ typename PersistentCheckingPolicy,
74
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
75
+ BasicMember( // NOLINT
76
+ const BasicPersistent<U, PersistentWeaknessPolicy,
77
+ PersistentLocationPolicy, PersistentCheckingPolicy>&
78
+ p)
79
+ : BasicMember(p.Get()) {}
80
+
81
+ BasicMember& operator=(const BasicMember& other) {
82
+ return operator=(other.Get());
83
+ }
84
+ // Allow heterogeneous assignment.
85
+ template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
86
+ typename OtherCheckingPolicy,
87
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
88
+ BasicMember& operator=(
89
+ const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
90
+ OtherCheckingPolicy>& other) {
91
+ return operator=(other.Get());
92
+ }
93
+ // Assignment from Persistent.
94
+ template <typename U, typename PersistentWeaknessPolicy,
95
+ typename PersistentLocationPolicy,
96
+ typename PersistentCheckingPolicy,
97
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
98
+ BasicMember& operator=(
99
+ const BasicPersistent<U, PersistentWeaknessPolicy,
100
+ PersistentLocationPolicy, PersistentCheckingPolicy>&
101
+ other) {
102
+ return operator=(other.Get());
103
+ }
104
+ BasicMember& operator=(T* other) {
105
+ SetRawAtomic(other);
106
+ AssigningWriteBarrier();
107
+ this->CheckPointer(Get());
108
+ return *this;
109
+ }
110
+ BasicMember& operator=(std::nullptr_t) {
111
+ Clear();
112
+ return *this;
113
+ }
114
+ BasicMember& operator=(SentinelPointer s) {
115
+ SetRawAtomic(s);
116
+ return *this;
117
+ }
118
+
119
+ template <typename OtherWeaknessTag, typename OtherBarrierPolicy,
120
+ typename OtherCheckingPolicy>
121
+ void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
122
+ OtherCheckingPolicy>& other) {
123
+ T* tmp = Get();
124
+ *this = other;
125
+ other = tmp;
126
+ }
127
+
128
+ explicit operator bool() const { return Get(); }
129
+ operator T*() const { return Get(); } // NOLINT
130
+ T* operator->() const { return Get(); }
131
+ T& operator*() const { return *Get(); }
132
+
133
+ // CFI cast exemption to allow passing SentinelPointer through T* and support
134
+ // heterogeneous assignments between different Member and Persistent handles
135
+ // based on their actual types.
136
+ V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
137
+ // Executed by the mutator, hence non atomic load.
138
+ return static_cast<T*>(MemberBase::GetRaw());
139
+ }
140
+
141
+ void Clear() { SetRawAtomic(nullptr); }
142
+
143
+ T* Release() {
144
+ T* result = Get();
145
+ Clear();
146
+ return result;
147
+ }
148
+
149
+ private:
150
+ T* GetRawAtomic() const {
151
+ return static_cast<T*>(MemberBase::GetRawAtomic());
152
+ }
153
+
154
+ void InitializingWriteBarrier() const {
155
+ WriteBarrierPolicy::InitializingBarrier(GetRawSlot(), GetRaw());
156
+ }
157
+ void AssigningWriteBarrier() const {
158
+ WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), GetRaw());
159
+ }
160
+
161
+ void ClearFromGC() const { MemberBase::ClearFromGC(); }
162
+
163
+ friend class cppgc::Visitor;
164
+ };
165
+
166
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
167
+ typename CheckingPolicy1, typename T2, typename WeaknessTag2,
168
+ typename WriteBarrierPolicy2, typename CheckingPolicy2>
169
+ bool operator==(
170
+ BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1> member1,
171
+ BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>
172
+ member2) {
173
+ return member1.Get() == member2.Get();
174
+ }
175
+
176
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
177
+ typename CheckingPolicy1, typename T2, typename WeaknessTag2,
178
+ typename WriteBarrierPolicy2, typename CheckingPolicy2>
179
+ bool operator!=(
180
+ BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1> member1,
181
+ BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>
182
+ member2) {
183
+ return !(member1 == member2);
184
+ }
185
+
186
+ template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy>
187
+ struct IsWeak<
188
+ internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy>>
189
+ : std::true_type {};
190
+
191
+ } // namespace internal
192
+
193
+ /**
194
+ * Members are used in classes to contain strong pointers to other garbage
195
+ * collected objects. All Member fields of a class must be traced in the class'
196
+ * trace method.
197
+ */
198
+ template <typename T>
199
+ using Member = internal::BasicMember<T, internal::StrongMemberTag,
200
+ internal::DijkstraWriteBarrierPolicy>;
201
+
202
+ /**
203
+ * WeakMember is similar to Member in that it is used to point to other garbage
204
+ * collected objects. However instead of creating a strong pointer to the
205
+ * object, the WeakMember creates a weak pointer, which does not keep the
206
+ * pointee alive. Hence if all pointers to to a heap allocated object are weak
207
+ * the object will be garbage collected. At the time of GC the weak pointers
208
+ * will automatically be set to null.
209
+ */
210
+ template <typename T>
211
+ using WeakMember = internal::BasicMember<T, internal::WeakMemberTag,
212
+ internal::DijkstraWriteBarrierPolicy>;
213
+
214
+ /**
215
+ * UntracedMember is a pointer to an on-heap object that is not traced for some
216
+ * reason. Do not use this unless you know what you are doing. Keeping raw
217
+ * pointers to on-heap objects is prohibited unless used from stack. Pointee
218
+ * must be kept alive through other means.
219
+ */
220
+ template <typename T>
221
+ using UntracedMember = internal::BasicMember<T, internal::UntracedMemberTag,
222
+ internal::NoWriteBarrierPolicy>;
223
+
224
+ } // namespace cppgc
225
+
226
+ #endif // INCLUDE_CPPGC_MEMBER_H_
@@ -0,0 +1,341 @@
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_PERSISTENT_H_
6
+ #define INCLUDE_CPPGC_PERSISTENT_H_
7
+
8
+ #include <type_traits>
9
+
10
+ #include "cppgc/internal/persistent-node.h"
11
+ #include "cppgc/internal/pointer-policies.h"
12
+ #include "cppgc/source-location.h"
13
+ #include "cppgc/type-traits.h"
14
+ #include "cppgc/visitor.h"
15
+ #include "v8config.h" // NOLINT(build/include_directory)
16
+
17
+ namespace cppgc {
18
+
19
+ class Visitor;
20
+
21
+ namespace internal {
22
+
23
+ class PersistentBase {
24
+ protected:
25
+ PersistentBase() = default;
26
+ explicit PersistentBase(void* raw) : raw_(raw) {}
27
+
28
+ void* GetValue() const { return raw_; }
29
+ void SetValue(void* value) { raw_ = value; }
30
+
31
+ PersistentNode* GetNode() const { return node_; }
32
+ void SetNode(PersistentNode* node) { node_ = node; }
33
+
34
+ // Performs a shallow clear which assumes that internal persistent nodes are
35
+ // destroyed elsewhere.
36
+ void ClearFromGC() const {
37
+ raw_ = nullptr;
38
+ node_ = nullptr;
39
+ }
40
+
41
+ private:
42
+ mutable void* raw_ = nullptr;
43
+ mutable PersistentNode* node_ = nullptr;
44
+
45
+ friend class PersistentRegion;
46
+ };
47
+
48
+ // The basic class from which all Persistent classes are generated.
49
+ template <typename T, typename WeaknessPolicy, typename LocationPolicy,
50
+ typename CheckingPolicy>
51
+ class BasicPersistent final : public PersistentBase,
52
+ public LocationPolicy,
53
+ private WeaknessPolicy,
54
+ private CheckingPolicy {
55
+ public:
56
+ using typename WeaknessPolicy::IsStrongPersistent;
57
+ using PointeeType = T;
58
+
59
+ // Null-state/sentinel constructors.
60
+ BasicPersistent( // NOLINT
61
+ const SourceLocation& loc = SourceLocation::Current())
62
+ : LocationPolicy(loc) {}
63
+
64
+ BasicPersistent(std::nullptr_t, // NOLINT
65
+ const SourceLocation& loc = SourceLocation::Current())
66
+ : LocationPolicy(loc) {}
67
+
68
+ BasicPersistent( // NOLINT
69
+ SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
70
+ : PersistentBase(s), LocationPolicy(loc) {}
71
+
72
+ // Raw value constructors.
73
+ BasicPersistent(T* raw, // NOLINT
74
+ const SourceLocation& loc = SourceLocation::Current())
75
+ : PersistentBase(raw), LocationPolicy(loc) {
76
+ if (!IsValid()) return;
77
+ SetNode(WeaknessPolicy::GetPersistentRegion(GetValue())
78
+ .AllocateNode(this, &BasicPersistent::Trace));
79
+ this->CheckPointer(Get());
80
+ }
81
+
82
+ BasicPersistent(T& raw, // NOLINT
83
+ const SourceLocation& loc = SourceLocation::Current())
84
+ : BasicPersistent(&raw, loc) {}
85
+
86
+ // Copy ctor.
87
+ BasicPersistent(const BasicPersistent& other,
88
+ const SourceLocation& loc = SourceLocation::Current())
89
+ : BasicPersistent(other.Get(), loc) {}
90
+
91
+ // Heterogeneous ctor.
92
+ template <typename U, typename OtherWeaknessPolicy,
93
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
94
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
95
+ BasicPersistent( // NOLINT
96
+ const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
97
+ OtherCheckingPolicy>& other,
98
+ const SourceLocation& loc = SourceLocation::Current())
99
+ : BasicPersistent(other.Get(), loc) {}
100
+
101
+ // Move ctor. The heterogeneous move ctor is not supported since e.g.
102
+ // persistent can't reuse persistent node from weak persistent.
103
+ BasicPersistent(
104
+ BasicPersistent&& other,
105
+ const SourceLocation& loc = SourceLocation::Current()) noexcept
106
+ : PersistentBase(std::move(other)), LocationPolicy(std::move(other)) {
107
+ if (!IsValid()) return;
108
+ GetNode()->UpdateOwner(this);
109
+ other.SetValue(nullptr);
110
+ other.SetNode(nullptr);
111
+ this->CheckPointer(Get());
112
+ }
113
+
114
+ // Constructor from member.
115
+ template <typename U, typename MemberBarrierPolicy,
116
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
117
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
118
+ BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy, // NOLINT
119
+ MemberWeaknessTag, MemberCheckingPolicy>
120
+ member,
121
+ const SourceLocation& loc = SourceLocation::Current())
122
+ : BasicPersistent(member.Get(), loc) {}
123
+
124
+ ~BasicPersistent() { Clear(); }
125
+
126
+ // Copy assignment.
127
+ BasicPersistent& operator=(const BasicPersistent& other) {
128
+ return operator=(other.Get());
129
+ }
130
+
131
+ template <typename U, typename OtherWeaknessPolicy,
132
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
133
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
134
+ BasicPersistent& operator=(
135
+ const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
136
+ OtherCheckingPolicy>& other) {
137
+ return operator=(other.Get());
138
+ }
139
+
140
+ // Move assignment.
141
+ BasicPersistent& operator=(BasicPersistent&& other) {
142
+ if (this == &other) return *this;
143
+ Clear();
144
+ PersistentBase::operator=(std::move(other));
145
+ LocationPolicy::operator=(std::move(other));
146
+ if (!IsValid()) return *this;
147
+ GetNode()->UpdateOwner(this);
148
+ other.SetValue(nullptr);
149
+ other.SetNode(nullptr);
150
+ this->CheckPointer(Get());
151
+ return *this;
152
+ }
153
+
154
+ // Assignment from member.
155
+ template <typename U, typename MemberBarrierPolicy,
156
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
157
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
158
+ BasicPersistent& operator=(
159
+ internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
160
+ MemberCheckingPolicy>
161
+ member) {
162
+ return operator=(member.Get());
163
+ }
164
+
165
+ BasicPersistent& operator=(T* other) {
166
+ Assign(other);
167
+ return *this;
168
+ }
169
+
170
+ BasicPersistent& operator=(std::nullptr_t) {
171
+ Clear();
172
+ return *this;
173
+ }
174
+
175
+ BasicPersistent& operator=(SentinelPointer s) {
176
+ Assign(s);
177
+ return *this;
178
+ }
179
+
180
+ explicit operator bool() const { return Get(); }
181
+ operator T*() const { return Get(); }
182
+ T* operator->() const { return Get(); }
183
+ T& operator*() const { return *Get(); }
184
+
185
+ // CFI cast exemption to allow passing SentinelPointer through T* and support
186
+ // heterogeneous assignments between different Member and Persistent handles
187
+ // based on their actual types.
188
+ V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
189
+ return static_cast<T*>(GetValue());
190
+ }
191
+
192
+ void Clear() { Assign(nullptr); }
193
+
194
+ T* Release() {
195
+ T* result = Get();
196
+ Clear();
197
+ return result;
198
+ }
199
+
200
+ private:
201
+ static void Trace(Visitor* v, const void* ptr) {
202
+ const auto* persistent = static_cast<const BasicPersistent*>(ptr);
203
+ v->TraceRoot(*persistent, persistent->Location());
204
+ }
205
+
206
+ bool IsValid() const {
207
+ // Ideally, handling kSentinelPointer would be done by the embedder. On the
208
+ // other hand, having Persistent aware of it is beneficial since no node
209
+ // gets wasted.
210
+ return GetValue() != nullptr && GetValue() != kSentinelPointer;
211
+ }
212
+
213
+ void Assign(T* ptr) {
214
+ if (IsValid()) {
215
+ if (ptr && ptr != kSentinelPointer) {
216
+ // Simply assign the pointer reusing the existing node.
217
+ SetValue(ptr);
218
+ this->CheckPointer(ptr);
219
+ return;
220
+ }
221
+ WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
222
+ SetNode(nullptr);
223
+ }
224
+ SetValue(ptr);
225
+ if (!IsValid()) return;
226
+ SetNode(WeaknessPolicy::GetPersistentRegion(GetValue())
227
+ .AllocateNode(this, &BasicPersistent::Trace));
228
+ this->CheckPointer(Get());
229
+ }
230
+
231
+ void ClearFromGC() const {
232
+ if (IsValid()) {
233
+ WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
234
+ PersistentBase::ClearFromGC();
235
+ }
236
+ }
237
+
238
+ friend class cppgc::Visitor;
239
+ };
240
+
241
+ template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
242
+ typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
243
+ typename LocationPolicy2, typename CheckingPolicy2>
244
+ bool operator==(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
245
+ CheckingPolicy1>& p1,
246
+ const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
247
+ CheckingPolicy2>& p2) {
248
+ return p1.Get() == p2.Get();
249
+ }
250
+
251
+ template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1,
252
+ typename CheckingPolicy1, typename T2, typename WeaknessPolicy2,
253
+ typename LocationPolicy2, typename CheckingPolicy2>
254
+ bool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
255
+ CheckingPolicy1>& p1,
256
+ const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2,
257
+ CheckingPolicy2>& p2) {
258
+ return !(p1 == p2);
259
+ }
260
+
261
+ template <typename T1, typename PersistentWeaknessPolicy,
262
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
263
+ typename T2, typename MemberWriteBarrierPolicy,
264
+ typename MemberWeaknessTag, typename MemberCheckingPolicy>
265
+ bool operator==(const BasicPersistent<T1, PersistentWeaknessPolicy,
266
+ PersistentLocationPolicy,
267
+ PersistentCheckingPolicy>& p,
268
+ BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
269
+ MemberCheckingPolicy>
270
+ m) {
271
+ return p.Get() == m.Get();
272
+ }
273
+
274
+ template <typename T1, typename PersistentWeaknessPolicy,
275
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
276
+ typename T2, typename MemberWriteBarrierPolicy,
277
+ typename MemberWeaknessTag, typename MemberCheckingPolicy>
278
+ bool operator!=(const BasicPersistent<T1, PersistentWeaknessPolicy,
279
+ PersistentLocationPolicy,
280
+ PersistentCheckingPolicy>& p,
281
+ BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
282
+ MemberCheckingPolicy>
283
+ m) {
284
+ return !(p == m);
285
+ }
286
+
287
+ template <typename T1, typename MemberWriteBarrierPolicy,
288
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
289
+ typename T2, typename PersistentWeaknessPolicy,
290
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
291
+ bool operator==(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
292
+ MemberCheckingPolicy>
293
+ m,
294
+ const BasicPersistent<T1, PersistentWeaknessPolicy,
295
+ PersistentLocationPolicy,
296
+ PersistentCheckingPolicy>& p) {
297
+ return m.Get() == p.Get();
298
+ }
299
+
300
+ template <typename T1, typename MemberWriteBarrierPolicy,
301
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
302
+ typename T2, typename PersistentWeaknessPolicy,
303
+ typename PersistentLocationPolicy, typename PersistentCheckingPolicy>
304
+ bool operator!=(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
305
+ MemberCheckingPolicy>
306
+ m,
307
+ const BasicPersistent<T1, PersistentWeaknessPolicy,
308
+ PersistentLocationPolicy,
309
+ PersistentCheckingPolicy>& p) {
310
+ return !(m == p);
311
+ }
312
+
313
+ template <typename T, typename LocationPolicy, typename CheckingPolicy>
314
+ struct IsWeak<BasicPersistent<T, internal::WeakPersistentPolicy, LocationPolicy,
315
+ CheckingPolicy>> : std::true_type {};
316
+ } // namespace internal
317
+
318
+ /**
319
+ * Persistent is a way to create a strong pointer from an off-heap object to
320
+ * another on-heap object. As long as the Persistent handle is alive the GC will
321
+ * keep the object pointed to alive. The Persistent handle is always a GC root
322
+ * from the point of view of the GC. Persistent must be constructed and
323
+ * destructed in the same thread.
324
+ */
325
+ template <typename T>
326
+ using Persistent =
327
+ internal::BasicPersistent<T, internal::StrongPersistentPolicy>;
328
+
329
+ /**
330
+ * WeakPersistent is a way to create a weak pointer from an off-heap object to
331
+ * an on-heap object. The pointer is automatically cleared when the pointee gets
332
+ * collected. WeakPersistent must be constructed and destructed in the same
333
+ * thread.
334
+ */
335
+ template <typename T>
336
+ using WeakPersistent =
337
+ internal::BasicPersistent<T, internal::WeakPersistentPolicy>;
338
+
339
+ } // namespace cppgc
340
+
341
+ #endif // INCLUDE_CPPGC_PERSISTENT_H_