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
@@ -0,0 +1,248 @@
1
+ // Copyright 2022 the V8 project authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ #ifndef INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_
6
+ #define INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_
7
+
8
+ #include <atomic>
9
+ #include <cstddef>
10
+ #include <type_traits>
11
+
12
+ #include "cppgc/internal/api-constants.h"
13
+ #include "cppgc/internal/logging.h"
14
+ #include "cppgc/sentinel-pointer.h"
15
+ #include "v8config.h" // NOLINT(build/include_directory)
16
+
17
+ namespace cppgc {
18
+ namespace internal {
19
+
20
+ enum class WriteBarrierSlotType {
21
+ kCompressed,
22
+ kUncompressed,
23
+ };
24
+
25
+ #if defined(CPPGC_POINTER_COMPRESSION)
26
+
27
+ #if defined(__clang__)
28
+ // Attribute const allows the compiler to assume that CageBaseGlobal::g_base_
29
+ // doesn't change (e.g. across calls) and thereby avoid redundant loads.
30
+ #define CPPGC_CONST __attribute__((const))
31
+ #define CPPGC_REQUIRE_CONSTANT_INIT \
32
+ __attribute__((require_constant_initialization))
33
+ #else // defined(__clang__)
34
+ #define CPPGC_CONST
35
+ #define CPPGC_REQUIRE_CONSTANT_INIT
36
+ #endif // defined(__clang__)
37
+
38
+ class V8_EXPORT CageBaseGlobal final {
39
+ public:
40
+ V8_INLINE CPPGC_CONST static uintptr_t Get() {
41
+ CPPGC_DCHECK(IsBaseConsistent());
42
+ return g_base_.base;
43
+ }
44
+
45
+ V8_INLINE CPPGC_CONST static bool IsSet() {
46
+ CPPGC_DCHECK(IsBaseConsistent());
47
+ return (g_base_.base & ~kLowerHalfWordMask) != 0;
48
+ }
49
+
50
+ private:
51
+ // We keep the lower halfword as ones to speed up decompression.
52
+ static constexpr uintptr_t kLowerHalfWordMask =
53
+ (api_constants::kCagedHeapReservationAlignment - 1);
54
+
55
+ static union alignas(api_constants::kCachelineSize) Base {
56
+ uintptr_t base;
57
+ char cache_line[api_constants::kCachelineSize];
58
+ } g_base_ CPPGC_REQUIRE_CONSTANT_INIT;
59
+
60
+ CageBaseGlobal() = delete;
61
+
62
+ V8_INLINE static bool IsBaseConsistent() {
63
+ return kLowerHalfWordMask == (g_base_.base & kLowerHalfWordMask);
64
+ }
65
+
66
+ friend class CageBaseGlobalUpdater;
67
+ };
68
+
69
+ #undef CPPGC_REQUIRE_CONSTANT_INIT
70
+ #undef CPPGC_CONST
71
+
72
+ class V8_TRIVIAL_ABI CompressedPointer final {
73
+ public:
74
+ using IntegralType = uint32_t;
75
+ static constexpr auto kWriteBarrierSlotType =
76
+ WriteBarrierSlotType::kCompressed;
77
+
78
+ V8_INLINE CompressedPointer() : value_(0u) {}
79
+ V8_INLINE explicit CompressedPointer(const void* ptr)
80
+ : value_(Compress(ptr)) {}
81
+ V8_INLINE explicit CompressedPointer(std::nullptr_t) : value_(0u) {}
82
+ V8_INLINE explicit CompressedPointer(SentinelPointer)
83
+ : value_(kCompressedSentinel) {}
84
+
85
+ V8_INLINE const void* Load() const { return Decompress(value_); }
86
+ V8_INLINE const void* LoadAtomic() const {
87
+ return Decompress(
88
+ reinterpret_cast<const std::atomic<IntegralType>&>(value_).load(
89
+ std::memory_order_relaxed));
90
+ }
91
+
92
+ V8_INLINE void Store(const void* ptr) { value_ = Compress(ptr); }
93
+ V8_INLINE void StoreAtomic(const void* value) {
94
+ reinterpret_cast<std::atomic<IntegralType>&>(value_).store(
95
+ Compress(value), std::memory_order_relaxed);
96
+ }
97
+
98
+ V8_INLINE void Clear() { value_ = 0u; }
99
+ V8_INLINE bool IsCleared() const { return !value_; }
100
+
101
+ V8_INLINE bool IsSentinel() const { return value_ == kCompressedSentinel; }
102
+
103
+ V8_INLINE uint32_t GetAsInteger() const { return value_; }
104
+
105
+ V8_INLINE friend bool operator==(CompressedPointer a, CompressedPointer b) {
106
+ return a.value_ == b.value_;
107
+ }
108
+ V8_INLINE friend bool operator!=(CompressedPointer a, CompressedPointer b) {
109
+ return a.value_ != b.value_;
110
+ }
111
+ V8_INLINE friend bool operator<(CompressedPointer a, CompressedPointer b) {
112
+ return a.value_ < b.value_;
113
+ }
114
+ V8_INLINE friend bool operator<=(CompressedPointer a, CompressedPointer b) {
115
+ return a.value_ <= b.value_;
116
+ }
117
+ V8_INLINE friend bool operator>(CompressedPointer a, CompressedPointer b) {
118
+ return a.value_ > b.value_;
119
+ }
120
+ V8_INLINE friend bool operator>=(CompressedPointer a, CompressedPointer b) {
121
+ return a.value_ >= b.value_;
122
+ }
123
+
124
+ static V8_INLINE IntegralType Compress(const void* ptr) {
125
+ static_assert(
126
+ SentinelPointer::kSentinelValue == 0b10,
127
+ "The compression scheme relies on the sentinel encoded as 0b10");
128
+ static constexpr size_t kGigaCageMask =
129
+ ~(api_constants::kCagedHeapReservationAlignment - 1);
130
+
131
+ CPPGC_DCHECK(CageBaseGlobal::IsSet());
132
+ const uintptr_t base = CageBaseGlobal::Get();
133
+ CPPGC_DCHECK(!ptr || ptr == kSentinelPointer ||
134
+ (base & kGigaCageMask) ==
135
+ (reinterpret_cast<uintptr_t>(ptr) & kGigaCageMask));
136
+
137
+ #if defined(CPPGC_2GB_CAGE)
138
+ // Truncate the pointer.
139
+ auto compressed =
140
+ static_cast<IntegralType>(reinterpret_cast<uintptr_t>(ptr));
141
+ #else // !defined(CPPGC_2GB_CAGE)
142
+ const auto uptr = reinterpret_cast<uintptr_t>(ptr);
143
+ // Shift the pointer by one and truncate.
144
+ auto compressed = static_cast<IntegralType>(uptr >> 1);
145
+ #endif // !defined(CPPGC_2GB_CAGE)
146
+ // Normal compressed pointers must have the MSB set.
147
+ CPPGC_DCHECK((!compressed || compressed == kCompressedSentinel) ||
148
+ (compressed & (1 << 31)));
149
+ return compressed;
150
+ }
151
+
152
+ static V8_INLINE void* Decompress(IntegralType ptr) {
153
+ CPPGC_DCHECK(CageBaseGlobal::IsSet());
154
+ const uintptr_t base = CageBaseGlobal::Get();
155
+ // Treat compressed pointer as signed and cast it to uint64_t, which will
156
+ // sign-extend it.
157
+ #if defined(CPPGC_2GB_CAGE)
158
+ const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr));
159
+ #else // !defined(CPPGC_2GB_CAGE)
160
+ // Then, shift the result by one. It's important to shift the unsigned
161
+ // value, as otherwise it would result in undefined behavior.
162
+ const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr)) << 1;
163
+ #endif // !defined(CPPGC_2GB_CAGE)
164
+ return reinterpret_cast<void*>(mask & base);
165
+ }
166
+
167
+ private:
168
+ #if defined(CPPGC_2GB_CAGE)
169
+ static constexpr IntegralType kCompressedSentinel =
170
+ SentinelPointer::kSentinelValue;
171
+ #else // !defined(CPPGC_2GB_CAGE)
172
+ static constexpr IntegralType kCompressedSentinel =
173
+ SentinelPointer::kSentinelValue >> 1;
174
+ #endif // !defined(CPPGC_2GB_CAGE)
175
+ // All constructors initialize `value_`. Do not add a default value here as it
176
+ // results in a non-atomic write on some builds, even when the atomic version
177
+ // of the constructor is used.
178
+ IntegralType value_;
179
+ };
180
+
181
+ #endif // defined(CPPGC_POINTER_COMPRESSION)
182
+
183
+ class V8_TRIVIAL_ABI RawPointer final {
184
+ public:
185
+ using IntegralType = uintptr_t;
186
+ static constexpr auto kWriteBarrierSlotType =
187
+ WriteBarrierSlotType::kUncompressed;
188
+
189
+ V8_INLINE RawPointer() : ptr_(nullptr) {}
190
+ V8_INLINE explicit RawPointer(const void* ptr) : ptr_(ptr) {}
191
+
192
+ V8_INLINE const void* Load() const { return ptr_; }
193
+ V8_INLINE const void* LoadAtomic() const {
194
+ return reinterpret_cast<const std::atomic<const void*>&>(ptr_).load(
195
+ std::memory_order_relaxed);
196
+ }
197
+
198
+ V8_INLINE void Store(const void* ptr) { ptr_ = ptr; }
199
+ V8_INLINE void StoreAtomic(const void* ptr) {
200
+ reinterpret_cast<std::atomic<const void*>&>(ptr_).store(
201
+ ptr, std::memory_order_relaxed);
202
+ }
203
+
204
+ V8_INLINE void Clear() { ptr_ = nullptr; }
205
+ V8_INLINE bool IsCleared() const { return !ptr_; }
206
+
207
+ V8_INLINE bool IsSentinel() const { return ptr_ == kSentinelPointer; }
208
+
209
+ V8_INLINE uintptr_t GetAsInteger() const {
210
+ return reinterpret_cast<uintptr_t>(ptr_);
211
+ }
212
+
213
+ V8_INLINE friend bool operator==(RawPointer a, RawPointer b) {
214
+ return a.ptr_ == b.ptr_;
215
+ }
216
+ V8_INLINE friend bool operator!=(RawPointer a, RawPointer b) {
217
+ return a.ptr_ != b.ptr_;
218
+ }
219
+ V8_INLINE friend bool operator<(RawPointer a, RawPointer b) {
220
+ return a.ptr_ < b.ptr_;
221
+ }
222
+ V8_INLINE friend bool operator<=(RawPointer a, RawPointer b) {
223
+ return a.ptr_ <= b.ptr_;
224
+ }
225
+ V8_INLINE friend bool operator>(RawPointer a, RawPointer b) {
226
+ return a.ptr_ > b.ptr_;
227
+ }
228
+ V8_INLINE friend bool operator>=(RawPointer a, RawPointer b) {
229
+ return a.ptr_ >= b.ptr_;
230
+ }
231
+
232
+ private:
233
+ // All constructors initialize `ptr_`. Do not add a default value here as it
234
+ // results in a non-atomic write on some builds, even when the atomic version
235
+ // of the constructor is used.
236
+ const void* ptr_;
237
+ };
238
+
239
+ #if defined(CPPGC_POINTER_COMPRESSION)
240
+ using DefaultMemberStorage = CompressedPointer;
241
+ #else // !defined(CPPGC_POINTER_COMPRESSION)
242
+ using DefaultMemberStorage = RawPointer;
243
+ #endif // !defined(CPPGC_POINTER_COMPRESSION)
244
+
245
+ } // namespace internal
246
+ } // namespace cppgc
247
+
248
+ #endif // INCLUDE_CPPGC_INTERNAL_MEMBER_STORAGE_H_
@@ -6,6 +6,7 @@
6
6
  #define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
7
7
 
8
8
  #include <cstddef>
9
+ #include <cstdint>
9
10
  #include <type_traits>
10
11
 
11
12
  #include "cppgc/name-provider.h"
@@ -58,6 +59,11 @@ struct HeapObjectName {
58
59
  bool name_was_hidden;
59
60
  };
60
61
 
62
+ enum class HeapObjectNameForUnnamedObject : uint8_t {
63
+ kUseClassNameIfSupported,
64
+ kUseHiddenName,
65
+ };
66
+
61
67
  class V8_EXPORT NameTraitBase {
62
68
  protected:
63
69
  static HeapObjectName GetNameFromTypeSignature(const char*);
@@ -78,16 +84,24 @@ class NameTrait final : public NameTraitBase {
78
84
  #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
79
85
  }
80
86
 
81
- static HeapObjectName GetName(const void* obj) {
82
- return GetNameFor(static_cast<const T*>(obj));
87
+ static HeapObjectName GetName(
88
+ const void* obj, HeapObjectNameForUnnamedObject name_retrieval_mode) {
89
+ return GetNameFor(static_cast<const T*>(obj), name_retrieval_mode);
83
90
  }
84
91
 
85
92
  private:
86
- static HeapObjectName GetNameFor(const NameProvider* name_provider) {
93
+ static HeapObjectName GetNameFor(const NameProvider* name_provider,
94
+ HeapObjectNameForUnnamedObject) {
95
+ // Objects inheriting from `NameProvider` are not considered unnamed as
96
+ // users already provided a name for them.
87
97
  return {name_provider->GetHumanReadableName(), false};
88
98
  }
89
99
 
90
- static HeapObjectName GetNameFor(...) {
100
+ static HeapObjectName GetNameFor(
101
+ const void*, HeapObjectNameForUnnamedObject name_retrieval_mode) {
102
+ if (name_retrieval_mode == HeapObjectNameForUnnamedObject::kUseHiddenName)
103
+ return {NameProvider::kHiddenName, true};
104
+
91
105
  #if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
92
106
  return {GetTypename<T>(), false};
93
107
  #elif CPPGC_SUPPORTS_OBJECT_NAMES
@@ -102,7 +116,7 @@ class NameTrait final : public NameTraitBase {
102
116
 
103
117
  static const HeapObjectName leaky_name =
104
118
  GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
105
- return {leaky_name, false};
119
+ return leaky_name;
106
120
 
107
121
  #undef PRETTY_FUNCTION_VALUE
108
122
 
@@ -112,7 +126,8 @@ class NameTrait final : public NameTraitBase {
112
126
  }
113
127
  };
114
128
 
115
- using NameCallback = HeapObjectName (*)(const void*);
129
+ using NameCallback = HeapObjectName (*)(const void*,
130
+ HeapObjectNameForUnnamedObject);
116
131
 
117
132
  } // namespace internal
118
133
  } // namespace cppgc
@@ -14,13 +14,11 @@
14
14
  #include "v8config.h" // NOLINT(build/include_directory)
15
15
 
16
16
  namespace cppgc {
17
-
18
- class Visitor;
19
-
20
17
  namespace internal {
21
18
 
22
19
  class CrossThreadPersistentRegion;
23
20
  class FatalOutOfMemoryHandler;
21
+ class RootVisitor;
24
22
 
25
23
  // PersistentNode represents a variant of two states:
26
24
  // 1) traceable node with a back pointer to the Persistent object;
@@ -32,7 +30,7 @@ class PersistentNode final {
32
30
  PersistentNode(const PersistentNode&) = delete;
33
31
  PersistentNode& operator=(const PersistentNode&) = delete;
34
32
 
35
- void InitializeAsUsedNode(void* owner, TraceCallback trace) {
33
+ void InitializeAsUsedNode(void* owner, TraceRootCallback trace) {
36
34
  CPPGC_DCHECK(trace);
37
35
  owner_ = owner;
38
36
  trace_ = trace;
@@ -53,9 +51,9 @@ class PersistentNode final {
53
51
  return next_;
54
52
  }
55
53
 
56
- void Trace(Visitor* visitor) const {
54
+ void Trace(RootVisitor& root_visitor) const {
57
55
  CPPGC_DCHECK(IsUsed());
58
- trace_(visitor, owner_);
56
+ trace_(root_visitor, owner_);
59
57
  }
60
58
 
61
59
  bool IsUsed() const { return trace_; }
@@ -73,7 +71,7 @@ class PersistentNode final {
73
71
  void* owner_ = nullptr;
74
72
  PersistentNode* next_;
75
73
  };
76
- TraceCallback trace_ = nullptr;
74
+ TraceRootCallback trace_ = nullptr;
77
75
  };
78
76
 
79
77
  class V8_EXPORT PersistentRegionBase {
@@ -86,7 +84,7 @@ class V8_EXPORT PersistentRegionBase {
86
84
  PersistentRegionBase(const PersistentRegionBase&) = delete;
87
85
  PersistentRegionBase& operator=(const PersistentRegionBase&) = delete;
88
86
 
89
- void Trace(Visitor*);
87
+ void Iterate(RootVisitor&);
90
88
 
91
89
  size_t NodesInUse() const;
92
90
 
@@ -96,7 +94,7 @@ class V8_EXPORT PersistentRegionBase {
96
94
  explicit PersistentRegionBase(const FatalOutOfMemoryHandler& oom_handler);
97
95
 
98
96
  PersistentNode* TryAllocateNodeFromFreeList(void* owner,
99
- TraceCallback trace) {
97
+ TraceRootCallback trace) {
100
98
  PersistentNode* node = nullptr;
101
99
  if (V8_LIKELY(free_list_head_)) {
102
100
  node = free_list_head_;
@@ -118,7 +116,7 @@ class V8_EXPORT PersistentRegionBase {
118
116
  }
119
117
 
120
118
  PersistentNode* RefillFreeListAndAllocateNode(void* owner,
121
- TraceCallback trace);
119
+ TraceRootCallback trace);
122
120
 
123
121
  private:
124
122
  template <typename PersistentBaseClass>
@@ -145,7 +143,7 @@ class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
145
143
  PersistentRegion(const PersistentRegion&) = delete;
146
144
  PersistentRegion& operator=(const PersistentRegion&) = delete;
147
145
 
148
- V8_INLINE PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
146
+ V8_INLINE PersistentNode* AllocateNode(void* owner, TraceRootCallback trace) {
149
147
  CPPGC_DCHECK(IsCreationThread());
150
148
  auto* node = TryAllocateNodeFromFreeList(owner, trace);
151
149
  if (V8_LIKELY(node)) return node;
@@ -189,7 +187,7 @@ class V8_EXPORT CrossThreadPersistentRegion final
189
187
  CrossThreadPersistentRegion& operator=(const CrossThreadPersistentRegion&) =
190
188
  delete;
191
189
 
192
- V8_INLINE PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
190
+ V8_INLINE PersistentNode* AllocateNode(void* owner, TraceRootCallback trace) {
193
191
  PersistentRegionLock::AssertLocked();
194
192
  auto* node = TryAllocateNodeFromFreeList(owner, trace);
195
193
  if (V8_LIKELY(node)) return node;
@@ -202,7 +200,7 @@ class V8_EXPORT CrossThreadPersistentRegion final
202
200
  PersistentRegionBase::FreeNode(node);
203
201
  }
204
202
 
205
- void Trace(Visitor*);
203
+ void Iterate(RootVisitor&);
206
204
 
207
205
  size_t NodesInUse() const;
208
206
 
@@ -8,6 +8,7 @@
8
8
  #include <cstdint>
9
9
  #include <type_traits>
10
10
 
11
+ #include "cppgc/internal/member-storage.h"
11
12
  #include "cppgc/internal/write-barrier.h"
12
13
  #include "cppgc/sentinel-pointer.h"
13
14
  #include "cppgc/source-location.h"
@@ -27,15 +28,67 @@ class WeakMemberTag;
27
28
  class UntracedMemberTag;
28
29
 
29
30
  struct DijkstraWriteBarrierPolicy {
30
- static void InitializingBarrier(const void*, const void*) {
31
+ V8_INLINE static void InitializingBarrier(const void*, const void*) {
31
32
  // Since in initializing writes the source object is always white, having no
32
33
  // barrier doesn't break the tri-color invariant.
33
34
  }
34
- static void AssigningBarrier(const void* slot, const void* value) {
35
+
36
+ template <WriteBarrierSlotType SlotType>
37
+ V8_INLINE static void AssigningBarrier(const void* slot, const void* value) {
38
+ #ifdef CPPGC_SLIM_WRITE_BARRIER
39
+ if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
40
+ WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
41
+ #else // !CPPGC_SLIM_WRITE_BARRIER
42
+ WriteBarrier::Params params;
43
+ const WriteBarrier::Type type =
44
+ WriteBarrier::GetWriteBarrierType(slot, value, params);
45
+ WriteBarrier(type, params, slot, value);
46
+ #endif // !CPPGC_SLIM_WRITE_BARRIER
47
+ }
48
+
49
+ template <WriteBarrierSlotType SlotType>
50
+ V8_INLINE static void AssigningBarrier(const void* slot, RawPointer storage) {
51
+ static_assert(
52
+ SlotType == WriteBarrierSlotType::kUncompressed,
53
+ "Assigning storages of Member and UncompressedMember is not supported");
54
+ #ifdef CPPGC_SLIM_WRITE_BARRIER
55
+ if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
56
+ WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
57
+ #else // !CPPGC_SLIM_WRITE_BARRIER
58
+ WriteBarrier::Params params;
59
+ const WriteBarrier::Type type =
60
+ WriteBarrier::GetWriteBarrierType(slot, storage, params);
61
+ WriteBarrier(type, params, slot, storage.Load());
62
+ #endif // !CPPGC_SLIM_WRITE_BARRIER
63
+ }
64
+
65
+ #if defined(CPPGC_POINTER_COMPRESSION)
66
+ template <WriteBarrierSlotType SlotType>
67
+ V8_INLINE static void AssigningBarrier(const void* slot,
68
+ CompressedPointer storage) {
69
+ static_assert(
70
+ SlotType == WriteBarrierSlotType::kCompressed,
71
+ "Assigning storages of Member and UncompressedMember is not supported");
72
+ #ifdef CPPGC_SLIM_WRITE_BARRIER
73
+ if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
74
+ WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
75
+ #else // !CPPGC_SLIM_WRITE_BARRIER
35
76
  WriteBarrier::Params params;
36
- switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) {
77
+ const WriteBarrier::Type type =
78
+ WriteBarrier::GetWriteBarrierType(slot, storage, params);
79
+ WriteBarrier(type, params, slot, storage.Load());
80
+ #endif // !CPPGC_SLIM_WRITE_BARRIER
81
+ }
82
+ #endif // defined(CPPGC_POINTER_COMPRESSION)
83
+
84
+ private:
85
+ V8_INLINE static void WriteBarrier(WriteBarrier::Type type,
86
+ const WriteBarrier::Params& params,
87
+ const void* slot, const void* value) {
88
+ switch (type) {
37
89
  case WriteBarrier::Type::kGenerational:
38
- WriteBarrier::GenerationalBarrier(params, slot);
90
+ WriteBarrier::GenerationalBarrier<
91
+ WriteBarrier::GenerationalBarrierType::kPreciseSlot>(params, slot);
39
92
  break;
40
93
  case WriteBarrier::Type::kMarking:
41
94
  WriteBarrier::DijkstraMarkingBarrier(params, value);
@@ -47,8 +100,11 @@ struct DijkstraWriteBarrierPolicy {
47
100
  };
48
101
 
49
102
  struct NoWriteBarrierPolicy {
50
- static void InitializingBarrier(const void*, const void*) {}
51
- static void AssigningBarrier(const void*, const void*) {}
103
+ V8_INLINE static void InitializingBarrier(const void*, const void*) {}
104
+ template <WriteBarrierSlotType>
105
+ V8_INLINE static void AssigningBarrier(const void*, const void*) {}
106
+ template <WriteBarrierSlotType, typename MemberStorage>
107
+ V8_INLINE static void AssigningBarrier(const void*, MemberStorage) {}
52
108
  };
53
109
 
54
110
  class V8_EXPORT SameThreadEnabledCheckingPolicyBase {
@@ -89,7 +145,7 @@ class V8_EXPORT SameThreadEnabledCheckingPolicy
89
145
 
90
146
  class DisabledCheckingPolicy {
91
147
  protected:
92
- void CheckPointer(const void*) {}
148
+ V8_INLINE void CheckPointer(const void*) {}
93
149
  };
94
150
 
95
151
  #ifdef DEBUG
@@ -176,7 +232,8 @@ template <typename T, typename WeaknessPolicy,
176
232
  typename CheckingPolicy = DefaultPersistentCheckingPolicy>
177
233
  class BasicPersistent;
178
234
  template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
179
- typename CheckingPolicy = DefaultMemberCheckingPolicy>
235
+ typename CheckingPolicy = DefaultMemberCheckingPolicy,
236
+ typename StorageType = DefaultMemberStorage>
180
237
  class BasicMember;
181
238
 
182
239
  } // namespace internal