libv8-node 18.13.0.1-x86_64-linux → 20.2.0.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/libv8/node/version.rb +3 -3
  3. data/vendor/v8/include/cppgc/common.h +0 -1
  4. data/vendor/v8/include/cppgc/cross-thread-persistent.h +11 -10
  5. data/vendor/v8/include/cppgc/heap-consistency.h +46 -3
  6. data/vendor/v8/include/cppgc/heap-handle.h +48 -0
  7. data/vendor/v8/include/cppgc/heap-statistics.h +2 -2
  8. data/vendor/v8/include/cppgc/heap.h +3 -7
  9. data/vendor/v8/include/cppgc/internal/api-constants.h +14 -1
  10. data/vendor/v8/include/cppgc/internal/base-page-handle.h +45 -0
  11. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +40 -8
  12. data/vendor/v8/include/cppgc/internal/caged-heap.h +61 -0
  13. data/vendor/v8/include/cppgc/internal/gc-info.h +35 -34
  14. data/vendor/v8/include/cppgc/internal/member-storage.h +248 -0
  15. data/vendor/v8/include/cppgc/internal/name-trait.h +21 -6
  16. data/vendor/v8/include/cppgc/internal/persistent-node.h +11 -13
  17. data/vendor/v8/include/cppgc/internal/pointer-policies.h +65 -8
  18. data/vendor/v8/include/cppgc/internal/write-barrier.h +153 -101
  19. data/vendor/v8/include/cppgc/liveness-broker.h +8 -7
  20. data/vendor/v8/include/cppgc/macros.h +10 -1
  21. data/vendor/v8/include/cppgc/member.h +424 -111
  22. data/vendor/v8/include/cppgc/name-provider.h +4 -4
  23. data/vendor/v8/include/cppgc/persistent.h +27 -24
  24. data/vendor/v8/include/cppgc/platform.h +7 -5
  25. data/vendor/v8/include/cppgc/sentinel-pointer.h +1 -1
  26. data/vendor/v8/include/cppgc/trace-trait.h +4 -0
  27. data/vendor/v8/include/cppgc/type-traits.h +13 -3
  28. data/vendor/v8/include/cppgc/visitor.h +104 -57
  29. data/vendor/v8/include/libplatform/v8-tracing.h +2 -2
  30. data/vendor/v8/include/v8-array-buffer.h +59 -0
  31. data/vendor/v8/include/v8-callbacks.h +32 -5
  32. data/vendor/v8/include/v8-context.h +63 -11
  33. data/vendor/v8/include/v8-cppgc.h +22 -0
  34. data/vendor/v8/include/v8-data.h +1 -1
  35. data/vendor/v8/include/v8-date.h +5 -0
  36. data/vendor/v8/include/v8-embedder-heap.h +0 -164
  37. data/vendor/v8/include/v8-exception.h +1 -1
  38. data/vendor/v8/include/v8-fast-api-calls.h +49 -31
  39. data/vendor/v8/include/v8-function-callback.h +69 -42
  40. data/vendor/v8/include/v8-function.h +9 -0
  41. data/vendor/v8/include/v8-initialization.h +23 -49
  42. data/vendor/v8/include/v8-inspector.h +32 -11
  43. data/vendor/v8/include/v8-internal.h +480 -183
  44. data/vendor/v8/include/v8-isolate.h +52 -77
  45. data/vendor/v8/include/v8-local-handle.h +86 -53
  46. data/vendor/v8/include/v8-locker.h +0 -11
  47. data/vendor/v8/include/v8-maybe.h +24 -1
  48. data/vendor/v8/include/v8-message.h +2 -4
  49. data/vendor/v8/include/v8-metrics.h +48 -40
  50. data/vendor/v8/include/v8-microtask-queue.h +6 -1
  51. data/vendor/v8/include/v8-object.h +29 -18
  52. data/vendor/v8/include/v8-persistent-handle.h +25 -18
  53. data/vendor/v8/include/v8-platform.h +133 -35
  54. data/vendor/v8/include/v8-primitive.h +27 -20
  55. data/vendor/v8/include/v8-profiler.h +133 -53
  56. data/vendor/v8/include/v8-regexp.h +2 -1
  57. data/vendor/v8/include/v8-script.h +91 -7
  58. data/vendor/v8/include/v8-snapshot.h +4 -8
  59. data/vendor/v8/include/v8-template.h +16 -77
  60. data/vendor/v8/include/v8-traced-handle.h +22 -28
  61. data/vendor/v8/include/v8-unwinder-state.h +4 -4
  62. data/vendor/v8/include/v8-util.h +11 -7
  63. data/vendor/v8/include/v8-value-serializer.h +46 -23
  64. data/vendor/v8/include/v8-value.h +31 -4
  65. data/vendor/v8/include/v8-version.h +4 -4
  66. data/vendor/v8/include/v8-wasm.h +7 -63
  67. data/vendor/v8/include/v8-weak-callback-info.h +0 -7
  68. data/vendor/v8/include/v8config.h +353 -15
  69. data/vendor/v8/x86_64-linux/libv8/obj/libv8_monolith.a +0 -0
  70. metadata +5 -1
@@ -9,6 +9,8 @@
9
9
  #include <cstddef>
10
10
  #include <type_traits>
11
11
 
12
+ #include "cppgc/internal/api-constants.h"
13
+ #include "cppgc/internal/member-storage.h"
12
14
  #include "cppgc/internal/pointer-policies.h"
13
15
  #include "cppgc/sentinel-pointer.h"
14
16
  #include "cppgc/type-traits.h"
@@ -16,241 +18,536 @@
16
18
 
17
19
  namespace cppgc {
18
20
 
21
+ namespace subtle {
22
+ class HeapConsistency;
23
+ } // namespace subtle
24
+
19
25
  class Visitor;
20
26
 
21
27
  namespace internal {
22
28
 
23
29
  // MemberBase always refers to the object as const object and defers to
24
30
  // BasicMember on casting to the right type as needed.
25
- class MemberBase {
31
+ template <typename StorageType>
32
+ class V8_TRIVIAL_ABI MemberBase {
33
+ public:
34
+ using RawStorage = StorageType;
35
+
26
36
  protected:
27
37
  struct AtomicInitializerTag {};
28
38
 
29
- MemberBase() : raw_(nullptr) {}
30
- explicit MemberBase(const void* value) : raw_(value) {}
31
- MemberBase(const void* value, AtomicInitializerTag) { SetRawAtomic(value); }
39
+ V8_INLINE MemberBase() = default;
40
+ V8_INLINE explicit MemberBase(const void* value) : raw_(value) {}
41
+ V8_INLINE MemberBase(const void* value, AtomicInitializerTag) {
42
+ SetRawAtomic(value);
43
+ }
32
44
 
33
- const void** GetRawSlot() const { return &raw_; }
34
- const void* GetRaw() const { return raw_; }
35
- void SetRaw(void* value) { raw_ = value; }
45
+ V8_INLINE explicit MemberBase(RawStorage raw) : raw_(raw) {}
46
+ V8_INLINE explicit MemberBase(std::nullptr_t) : raw_(nullptr) {}
47
+ V8_INLINE explicit MemberBase(SentinelPointer s) : raw_(s) {}
36
48
 
37
- const void* GetRawAtomic() const {
38
- return reinterpret_cast<const std::atomic<const void*>*>(&raw_)->load(
39
- std::memory_order_relaxed);
49
+ V8_INLINE const void** GetRawSlot() const {
50
+ return reinterpret_cast<const void**>(const_cast<MemberBase*>(this));
40
51
  }
41
- void SetRawAtomic(const void* value) {
42
- reinterpret_cast<std::atomic<const void*>*>(&raw_)->store(
43
- value, std::memory_order_relaxed);
52
+ V8_INLINE const void* GetRaw() const { return raw_.Load(); }
53
+ V8_INLINE void SetRaw(void* value) { raw_.Store(value); }
54
+
55
+ V8_INLINE const void* GetRawAtomic() const { return raw_.LoadAtomic(); }
56
+ V8_INLINE void SetRawAtomic(const void* value) { raw_.StoreAtomic(value); }
57
+
58
+ V8_INLINE RawStorage GetRawStorage() const { return raw_; }
59
+ V8_INLINE void SetRawStorageAtomic(RawStorage other) {
60
+ reinterpret_cast<std::atomic<RawStorage>&>(raw_).store(
61
+ other, std::memory_order_relaxed);
44
62
  }
45
63
 
46
- void ClearFromGC() const { raw_ = nullptr; }
64
+ V8_INLINE bool IsCleared() const { return raw_.IsCleared(); }
65
+
66
+ V8_INLINE void ClearFromGC() const { raw_.Clear(); }
47
67
 
48
68
  private:
49
- // All constructors initialize `raw_`. Do not add a default value here as it
50
- // results in a non-atomic write on some builds, even when the atomic version
51
- // of the constructor is used.
52
- mutable const void* raw_;
69
+ friend class MemberDebugHelper;
70
+
71
+ mutable RawStorage raw_;
53
72
  };
54
73
 
55
74
  // The basic class from which all Member classes are 'generated'.
56
75
  template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
57
- typename CheckingPolicy>
58
- class BasicMember final : private MemberBase, private CheckingPolicy {
76
+ typename CheckingPolicy, typename StorageType>
77
+ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
78
+ private CheckingPolicy {
79
+ using Base = MemberBase<StorageType>;
80
+
59
81
  public:
60
82
  using PointeeType = T;
83
+ using RawStorage = typename Base::RawStorage;
61
84
 
62
- constexpr BasicMember() = default;
63
- constexpr BasicMember(std::nullptr_t) {} // NOLINT
64
- BasicMember(SentinelPointer s) : MemberBase(s) {} // NOLINT
65
- BasicMember(T* raw) : MemberBase(raw) { // NOLINT
66
- InitializingWriteBarrier();
85
+ V8_INLINE constexpr BasicMember() = default;
86
+ V8_INLINE constexpr BasicMember(std::nullptr_t) {} // NOLINT
87
+ V8_INLINE BasicMember(SentinelPointer s) : Base(s) {} // NOLINT
88
+ V8_INLINE BasicMember(T* raw) : Base(raw) { // NOLINT
89
+ InitializingWriteBarrier(raw);
67
90
  this->CheckPointer(Get());
68
91
  }
69
- BasicMember(T& raw) : BasicMember(&raw) {} // NOLINT
92
+ V8_INLINE BasicMember(T& raw) // NOLINT
93
+ : BasicMember(&raw) {}
94
+
70
95
  // Atomic ctor. Using the AtomicInitializerTag forces BasicMember to
71
96
  // initialize using atomic assignments. This is required for preventing
72
97
  // data races with concurrent marking.
73
- using AtomicInitializerTag = MemberBase::AtomicInitializerTag;
74
- BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
75
- : MemberBase(nullptr, atomic) {}
76
- BasicMember(SentinelPointer s, AtomicInitializerTag atomic)
77
- : MemberBase(s, atomic) {}
78
- BasicMember(T* raw, AtomicInitializerTag atomic) : MemberBase(raw, atomic) {
79
- InitializingWriteBarrier();
98
+ using AtomicInitializerTag = typename Base::AtomicInitializerTag;
99
+ V8_INLINE BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
100
+ : Base(nullptr, atomic) {}
101
+ V8_INLINE BasicMember(SentinelPointer s, AtomicInitializerTag atomic)
102
+ : Base(s, atomic) {}
103
+ V8_INLINE BasicMember(T* raw, AtomicInitializerTag atomic)
104
+ : Base(raw, atomic) {
105
+ InitializingWriteBarrier(raw);
80
106
  this->CheckPointer(Get());
81
107
  }
82
- BasicMember(T& raw, AtomicInitializerTag atomic)
108
+ V8_INLINE BasicMember(T& raw, AtomicInitializerTag atomic)
83
109
  : BasicMember(&raw, atomic) {}
110
+
84
111
  // Copy ctor.
85
- BasicMember(const BasicMember& other) : BasicMember(other.Get()) {}
86
- // Allow heterogeneous construction.
112
+ V8_INLINE BasicMember(const BasicMember& other)
113
+ : BasicMember(other.GetRawStorage()) {}
114
+
115
+ // Heterogeneous copy constructors. When the source pointer have a different
116
+ // type, perform a compress-decompress round, because the source pointer may
117
+ // need to be adjusted.
87
118
  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
88
119
  typename OtherCheckingPolicy,
89
- typename = std::enable_if_t<std::is_base_of<T, U>::value>>
90
- BasicMember( // NOLINT
120
+ std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
121
+ V8_INLINE BasicMember( // NOLINT
122
+ const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
123
+ OtherCheckingPolicy, StorageType>& other)
124
+ : BasicMember(other.GetRawStorage()) {}
125
+
126
+ template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
127
+ typename OtherCheckingPolicy,
128
+ std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
129
+ V8_INLINE BasicMember( // NOLINT
91
130
  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
92
- OtherCheckingPolicy>& other)
131
+ OtherCheckingPolicy, StorageType>& other)
93
132
  : BasicMember(other.Get()) {}
133
+
94
134
  // Move ctor.
95
- BasicMember(BasicMember&& other) noexcept : BasicMember(other.Get()) {
135
+ V8_INLINE BasicMember(BasicMember&& other) noexcept
136
+ : BasicMember(other.GetRawStorage()) {
96
137
  other.Clear();
97
138
  }
98
- // Allow heterogeneous move construction.
139
+
140
+ // Heterogeneous move constructors. When the source pointer have a different
141
+ // type, perform a compress-decompress round, because the source pointer may
142
+ // need to be adjusted.
99
143
  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
100
144
  typename OtherCheckingPolicy,
101
- typename = std::enable_if_t<std::is_base_of<T, U>::value>>
102
- BasicMember(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
103
- OtherCheckingPolicy>&& other) noexcept
145
+ std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
146
+ V8_INLINE BasicMember(
147
+ BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
148
+ StorageType>&& other) noexcept
149
+ : BasicMember(other.GetRawStorage()) {
150
+ other.Clear();
151
+ }
152
+
153
+ template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
154
+ typename OtherCheckingPolicy,
155
+ std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
156
+ V8_INLINE BasicMember(
157
+ BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
158
+ StorageType>&& other) noexcept
104
159
  : BasicMember(other.Get()) {
105
160
  other.Clear();
106
161
  }
162
+
107
163
  // Construction from Persistent.
108
164
  template <typename U, typename PersistentWeaknessPolicy,
109
165
  typename PersistentLocationPolicy,
110
166
  typename PersistentCheckingPolicy,
111
167
  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
112
- BasicMember(const BasicPersistent<U, PersistentWeaknessPolicy,
113
- PersistentLocationPolicy,
114
- PersistentCheckingPolicy>& p)
168
+ V8_INLINE BasicMember(const BasicPersistent<U, PersistentWeaknessPolicy,
169
+ PersistentLocationPolicy,
170
+ PersistentCheckingPolicy>& p)
115
171
  : BasicMember(p.Get()) {}
116
172
 
117
173
  // Copy assignment.
118
- BasicMember& operator=(const BasicMember& other) {
119
- return operator=(other.Get());
174
+ V8_INLINE BasicMember& operator=(const BasicMember& other) {
175
+ return operator=(other.GetRawStorage());
120
176
  }
121
- // Allow heterogeneous copy assignment.
177
+
178
+ // Heterogeneous copy assignment. When the source pointer have a different
179
+ // type, perform a compress-decompress round, because the source pointer may
180
+ // need to be adjusted.
122
181
  template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
123
- typename OtherCheckingPolicy,
124
- typename = std::enable_if_t<std::is_base_of<T, U>::value>>
125
- BasicMember& operator=(
182
+ typename OtherCheckingPolicy>
183
+ V8_INLINE BasicMember& operator=(
126
184
  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
127
- OtherCheckingPolicy>& other) {
128
- return operator=(other.Get());
185
+ OtherCheckingPolicy, StorageType>& other) {
186
+ if constexpr (internal::IsDecayedSameV<T, U>) {
187
+ return operator=(other.GetRawStorage());
188
+ } else {
189
+ static_assert(internal::IsStrictlyBaseOfV<T, U>);
190
+ return operator=(other.Get());
191
+ }
129
192
  }
193
+
130
194
  // Move assignment.
131
- BasicMember& operator=(BasicMember&& other) noexcept {
132
- operator=(other.Get());
195
+ V8_INLINE BasicMember& operator=(BasicMember&& other) noexcept {
196
+ operator=(other.GetRawStorage());
133
197
  other.Clear();
134
198
  return *this;
135
199
  }
136
- // Heterogeneous move assignment.
200
+
201
+ // Heterogeneous move assignment. When the source pointer have a different
202
+ // type, perform a compress-decompress round, because the source pointer may
203
+ // need to be adjusted.
137
204
  template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
138
- typename OtherCheckingPolicy,
139
- typename = std::enable_if_t<std::is_base_of<T, U>::value>>
140
- BasicMember& operator=(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
141
- OtherCheckingPolicy>&& other) noexcept {
142
- operator=(other.Get());
205
+ typename OtherCheckingPolicy>
206
+ V8_INLINE BasicMember& operator=(
207
+ BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
208
+ StorageType>&& other) noexcept {
209
+ if constexpr (internal::IsDecayedSameV<T, U>) {
210
+ operator=(other.GetRawStorage());
211
+ } else {
212
+ static_assert(internal::IsStrictlyBaseOfV<T, U>);
213
+ operator=(other.Get());
214
+ }
143
215
  other.Clear();
144
216
  return *this;
145
217
  }
218
+
146
219
  // Assignment from Persistent.
147
220
  template <typename U, typename PersistentWeaknessPolicy,
148
221
  typename PersistentLocationPolicy,
149
222
  typename PersistentCheckingPolicy,
150
223
  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
151
- BasicMember& operator=(
224
+ V8_INLINE BasicMember& operator=(
152
225
  const BasicPersistent<U, PersistentWeaknessPolicy,
153
226
  PersistentLocationPolicy, PersistentCheckingPolicy>&
154
227
  other) {
155
228
  return operator=(other.Get());
156
229
  }
157
- BasicMember& operator=(T* other) {
158
- SetRawAtomic(other);
159
- AssigningWriteBarrier();
230
+
231
+ V8_INLINE BasicMember& operator=(T* other) {
232
+ Base::SetRawAtomic(other);
233
+ AssigningWriteBarrier(other);
160
234
  this->CheckPointer(Get());
161
235
  return *this;
162
236
  }
163
- BasicMember& operator=(std::nullptr_t) {
237
+
238
+ V8_INLINE BasicMember& operator=(std::nullptr_t) {
164
239
  Clear();
165
240
  return *this;
166
241
  }
167
- BasicMember& operator=(SentinelPointer s) {
168
- SetRawAtomic(s);
242
+ V8_INLINE BasicMember& operator=(SentinelPointer s) {
243
+ Base::SetRawAtomic(s);
169
244
  return *this;
170
245
  }
171
246
 
172
247
  template <typename OtherWeaknessTag, typename OtherBarrierPolicy,
173
248
  typename OtherCheckingPolicy>
174
- void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
175
- OtherCheckingPolicy>& other) {
176
- T* tmp = Get();
249
+ V8_INLINE void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
250
+ OtherCheckingPolicy, StorageType>& other) {
251
+ auto tmp = GetRawStorage();
177
252
  *this = other;
178
253
  other = tmp;
179
254
  }
180
255
 
181
- explicit operator bool() const { return Get(); }
182
- operator T*() const { return Get(); }
183
- T* operator->() const { return Get(); }
184
- T& operator*() const { return *Get(); }
256
+ V8_INLINE explicit operator bool() const { return !Base::IsCleared(); }
257
+ V8_INLINE operator T*() const { return Get(); }
258
+ V8_INLINE T* operator->() const { return Get(); }
259
+ V8_INLINE T& operator*() const { return *Get(); }
185
260
 
186
261
  // CFI cast exemption to allow passing SentinelPointer through T* and support
187
262
  // heterogeneous assignments between different Member and Persistent handles
188
263
  // based on their actual types.
189
- V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
264
+ V8_INLINE V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
190
265
  // Executed by the mutator, hence non atomic load.
191
266
  //
192
267
  // The const_cast below removes the constness from MemberBase storage. The
193
268
  // following static_cast re-adds any constness if specified through the
194
269
  // user-visible template parameter T.
195
- return static_cast<T*>(const_cast<void*>(MemberBase::GetRaw()));
270
+ return static_cast<T*>(const_cast<void*>(Base::GetRaw()));
196
271
  }
197
272
 
198
- void Clear() { SetRawAtomic(nullptr); }
273
+ V8_INLINE void Clear() {
274
+ Base::SetRawStorageAtomic(RawStorage{});
275
+ }
199
276
 
200
- T* Release() {
277
+ V8_INLINE T* Release() {
201
278
  T* result = Get();
202
279
  Clear();
203
280
  return result;
204
281
  }
205
282
 
206
- const T** GetSlotForTesting() const {
207
- return reinterpret_cast<const T**>(GetRawSlot());
283
+ V8_INLINE const T** GetSlotForTesting() const {
284
+ return reinterpret_cast<const T**>(Base::GetRawSlot());
285
+ }
286
+
287
+ V8_INLINE RawStorage GetRawStorage() const {
288
+ return Base::GetRawStorage();
208
289
  }
209
290
 
210
291
  private:
211
- const T* GetRawAtomic() const {
212
- return static_cast<const T*>(MemberBase::GetRawAtomic());
292
+ V8_INLINE explicit BasicMember(RawStorage raw) : Base(raw) {
293
+ InitializingWriteBarrier(Get());
294
+ this->CheckPointer(Get());
295
+ }
296
+
297
+ V8_INLINE BasicMember& operator=(RawStorage other) {
298
+ Base::SetRawStorageAtomic(other);
299
+ AssigningWriteBarrier();
300
+ this->CheckPointer(Get());
301
+ return *this;
302
+ }
303
+
304
+ V8_INLINE const T* GetRawAtomic() const {
305
+ return static_cast<const T*>(Base::GetRawAtomic());
213
306
  }
214
307
 
215
- void InitializingWriteBarrier() const {
216
- WriteBarrierPolicy::InitializingBarrier(GetRawSlot(), GetRaw());
308
+ V8_INLINE void InitializingWriteBarrier(T* value) const {
309
+ WriteBarrierPolicy::InitializingBarrier(Base::GetRawSlot(), value);
310
+ }
311
+ V8_INLINE void AssigningWriteBarrier(T* value) const {
312
+ WriteBarrierPolicy::template AssigningBarrier<
313
+ StorageType::kWriteBarrierSlotType>(Base::GetRawSlot(), value);
217
314
  }
218
- void AssigningWriteBarrier() const {
219
- WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), GetRaw());
315
+ V8_INLINE void AssigningWriteBarrier() const {
316
+ WriteBarrierPolicy::template AssigningBarrier<
317
+ StorageType::kWriteBarrierSlotType>(Base::GetRawSlot(),
318
+ Base::GetRawStorage());
220
319
  }
221
320
 
222
- void ClearFromGC() const { MemberBase::ClearFromGC(); }
321
+ V8_INLINE void ClearFromGC() const { Base::ClearFromGC(); }
223
322
 
224
- T* GetFromGC() const { return Get(); }
323
+ V8_INLINE T* GetFromGC() const { return Get(); }
225
324
 
325
+ friend class cppgc::subtle::HeapConsistency;
226
326
  friend class cppgc::Visitor;
227
327
  template <typename U>
228
328
  friend struct cppgc::TraceTrait;
329
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
330
+ typename CheckingPolicy1, typename StorageType1>
331
+ friend class BasicMember;
229
332
  };
230
333
 
334
+ // Member equality operators.
231
335
  template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
232
336
  typename CheckingPolicy1, typename T2, typename WeaknessTag2,
233
- typename WriteBarrierPolicy2, typename CheckingPolicy2>
234
- bool operator==(const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1,
235
- CheckingPolicy1>& member1,
236
- const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2,
237
- CheckingPolicy2>& member2) {
238
- return member1.Get() == member2.Get();
337
+ typename WriteBarrierPolicy2, typename CheckingPolicy2,
338
+ typename StorageType>
339
+ V8_INLINE bool operator==(
340
+ const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
341
+ StorageType>& member1,
342
+ const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
343
+ StorageType>& member2) {
344
+ if constexpr (internal::IsDecayedSameV<T1, T2>) {
345
+ // Check compressed pointers if types are the same.
346
+ return member1.GetRawStorage() == member2.GetRawStorage();
347
+ } else {
348
+ static_assert(internal::IsStrictlyBaseOfV<T1, T2> ||
349
+ internal::IsStrictlyBaseOfV<T2, T1>);
350
+ // Otherwise, check decompressed pointers.
351
+ return member1.Get() == member2.Get();
352
+ }
239
353
  }
240
354
 
241
355
  template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
242
356
  typename CheckingPolicy1, typename T2, typename WeaknessTag2,
243
- typename WriteBarrierPolicy2, typename CheckingPolicy2>
244
- bool operator!=(const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1,
245
- CheckingPolicy1>& member1,
246
- const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2,
247
- CheckingPolicy2>& member2) {
357
+ typename WriteBarrierPolicy2, typename CheckingPolicy2,
358
+ typename StorageType>
359
+ V8_INLINE bool operator!=(
360
+ const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
361
+ StorageType>& member1,
362
+ const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
363
+ StorageType>& member2) {
248
364
  return !(member1 == member2);
249
365
  }
250
366
 
251
- template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy>
252
- struct IsWeak<
253
- internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy>>
367
+ // Equality with raw pointers.
368
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
369
+ typename CheckingPolicy, typename StorageType, typename U>
370
+ V8_INLINE bool operator==(
371
+ const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
372
+ StorageType>& member,
373
+ U* raw) {
374
+ // Never allow comparison with erased pointers.
375
+ static_assert(!internal::IsDecayedSameV<void, U>);
376
+
377
+ if constexpr (internal::IsDecayedSameV<T, U>) {
378
+ // Check compressed pointers if types are the same.
379
+ return member.GetRawStorage() == StorageType(raw);
380
+ } else if constexpr (internal::IsStrictlyBaseOfV<T, U>) {
381
+ // Cast the raw pointer to T, which may adjust the pointer.
382
+ return member.GetRawStorage() == StorageType(static_cast<T*>(raw));
383
+ } else {
384
+ // Otherwise, decompressed the member.
385
+ return member.Get() == raw;
386
+ }
387
+ }
388
+
389
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
390
+ typename CheckingPolicy, typename StorageType, typename U>
391
+ V8_INLINE bool operator!=(
392
+ const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
393
+ StorageType>& member,
394
+ U* raw) {
395
+ return !(member == raw);
396
+ }
397
+
398
+ template <typename T, typename U, typename WeaknessTag,
399
+ typename WriteBarrierPolicy, typename CheckingPolicy,
400
+ typename StorageType>
401
+ V8_INLINE bool operator==(
402
+ T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
403
+ CheckingPolicy, StorageType>& member) {
404
+ return member == raw;
405
+ }
406
+
407
+ template <typename T, typename U, typename WeaknessTag,
408
+ typename WriteBarrierPolicy, typename CheckingPolicy,
409
+ typename StorageType>
410
+ V8_INLINE bool operator!=(
411
+ T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
412
+ CheckingPolicy, StorageType>& member) {
413
+ return !(raw == member);
414
+ }
415
+
416
+ // Equality with sentinel.
417
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
418
+ typename CheckingPolicy, typename StorageType>
419
+ V8_INLINE bool operator==(
420
+ const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
421
+ StorageType>& member,
422
+ SentinelPointer) {
423
+ return member.GetRawStorage().IsSentinel();
424
+ }
425
+
426
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
427
+ typename CheckingPolicy, typename StorageType>
428
+ V8_INLINE bool operator!=(
429
+ const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
430
+ StorageType>& member,
431
+ SentinelPointer s) {
432
+ return !(member == s);
433
+ }
434
+
435
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
436
+ typename CheckingPolicy, typename StorageType>
437
+ V8_INLINE bool operator==(
438
+ SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
439
+ CheckingPolicy, StorageType>& member) {
440
+ return member == s;
441
+ }
442
+
443
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
444
+ typename CheckingPolicy, typename StorageType>
445
+ V8_INLINE bool operator!=(
446
+ SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
447
+ CheckingPolicy, StorageType>& member) {
448
+ return !(s == member);
449
+ }
450
+
451
+ // Equality with nullptr.
452
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
453
+ typename CheckingPolicy, typename StorageType>
454
+ V8_INLINE bool operator==(
455
+ const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
456
+ StorageType>& member,
457
+ std::nullptr_t) {
458
+ return !static_cast<bool>(member);
459
+ }
460
+
461
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
462
+ typename CheckingPolicy, typename StorageType>
463
+ V8_INLINE bool operator!=(
464
+ const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
465
+ StorageType>& member,
466
+ std::nullptr_t n) {
467
+ return !(member == n);
468
+ }
469
+
470
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
471
+ typename CheckingPolicy, typename StorageType>
472
+ V8_INLINE bool operator==(
473
+ std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
474
+ CheckingPolicy, StorageType>& member) {
475
+ return member == n;
476
+ }
477
+
478
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
479
+ typename CheckingPolicy, typename StorageType>
480
+ V8_INLINE bool operator!=(
481
+ std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
482
+ CheckingPolicy, StorageType>& member) {
483
+ return !(n == member);
484
+ }
485
+
486
+ // Relational operators.
487
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
488
+ typename CheckingPolicy1, typename T2, typename WeaknessTag2,
489
+ typename WriteBarrierPolicy2, typename CheckingPolicy2,
490
+ typename StorageType>
491
+ V8_INLINE bool operator<(
492
+ const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
493
+ StorageType>& member1,
494
+ const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
495
+ StorageType>& member2) {
496
+ static_assert(
497
+ internal::IsDecayedSameV<T1, T2>,
498
+ "Comparison works only for same pointer type modulo cv-qualifiers");
499
+ return member1.GetRawStorage() < member2.GetRawStorage();
500
+ }
501
+
502
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
503
+ typename CheckingPolicy1, typename T2, typename WeaknessTag2,
504
+ typename WriteBarrierPolicy2, typename CheckingPolicy2,
505
+ typename StorageType>
506
+ V8_INLINE bool operator<=(
507
+ const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
508
+ StorageType>& member1,
509
+ const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
510
+ StorageType>& member2) {
511
+ static_assert(
512
+ internal::IsDecayedSameV<T1, T2>,
513
+ "Comparison works only for same pointer type modulo cv-qualifiers");
514
+ return member1.GetRawStorage() <= member2.GetRawStorage();
515
+ }
516
+
517
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
518
+ typename CheckingPolicy1, typename T2, typename WeaknessTag2,
519
+ typename WriteBarrierPolicy2, typename CheckingPolicy2,
520
+ typename StorageType>
521
+ V8_INLINE bool operator>(
522
+ const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
523
+ StorageType>& member1,
524
+ const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
525
+ StorageType>& member2) {
526
+ static_assert(
527
+ internal::IsDecayedSameV<T1, T2>,
528
+ "Comparison works only for same pointer type modulo cv-qualifiers");
529
+ return member1.GetRawStorage() > member2.GetRawStorage();
530
+ }
531
+
532
+ template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
533
+ typename CheckingPolicy1, typename T2, typename WeaknessTag2,
534
+ typename WriteBarrierPolicy2, typename CheckingPolicy2,
535
+ typename StorageType>
536
+ V8_INLINE bool operator>=(
537
+ const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
538
+ StorageType>& member1,
539
+ const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
540
+ StorageType>& member2) {
541
+ static_assert(
542
+ internal::IsDecayedSameV<T1, T2>,
543
+ "Comparison works only for same pointer type modulo cv-qualifiers");
544
+ return member1.GetRawStorage() >= member2.GetRawStorage();
545
+ }
546
+
547
+ template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy,
548
+ typename StorageType>
549
+ struct IsWeak<internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy,
550
+ CheckingPolicy, StorageType>>
254
551
  : std::true_type {};
255
552
 
256
553
  } // namespace internal
@@ -261,8 +558,9 @@ struct IsWeak<
261
558
  * trace method.
262
559
  */
263
560
  template <typename T>
264
- using Member = internal::BasicMember<T, internal::StrongMemberTag,
265
- internal::DijkstraWriteBarrierPolicy>;
561
+ using Member = internal::BasicMember<
562
+ T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
563
+ internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
266
564
 
267
565
  /**
268
566
  * WeakMember is similar to Member in that it is used to point to other garbage
@@ -273,8 +571,9 @@ using Member = internal::BasicMember<T, internal::StrongMemberTag,
273
571
  * will automatically be set to null.
274
572
  */
275
573
  template <typename T>
276
- using WeakMember = internal::BasicMember<T, internal::WeakMemberTag,
277
- internal::DijkstraWriteBarrierPolicy>;
574
+ using WeakMember = internal::BasicMember<
575
+ T, internal::WeakMemberTag, internal::DijkstraWriteBarrierPolicy,
576
+ internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
278
577
 
279
578
  /**
280
579
  * UntracedMember is a pointer to an on-heap object that is not traced for some
@@ -283,8 +582,22 @@ using WeakMember = internal::BasicMember<T, internal::WeakMemberTag,
283
582
  * must be kept alive through other means.
284
583
  */
285
584
  template <typename T>
286
- using UntracedMember = internal::BasicMember<T, internal::UntracedMemberTag,
287
- internal::NoWriteBarrierPolicy>;
585
+ using UntracedMember = internal::BasicMember<
586
+ T, internal::UntracedMemberTag, internal::NoWriteBarrierPolicy,
587
+ internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
588
+
589
+ namespace subtle {
590
+
591
+ /**
592
+ * UncompressedMember. Use with care in hot paths that would otherwise cause
593
+ * many decompression cycles.
594
+ */
595
+ template <typename T>
596
+ using UncompressedMember = internal::BasicMember<
597
+ T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
598
+ internal::DefaultMemberCheckingPolicy, internal::RawPointer>;
599
+
600
+ } // namespace subtle
288
601
 
289
602
  } // namespace cppgc
290
603