libv8-node 15.14.0.1-x86_64-linux → 16.10.0.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/location.rb +1 -1
  3. data/ext/libv8-node/paths.rb +1 -1
  4. data/lib/libv8/node/version.rb +3 -3
  5. data/vendor/v8/include/cppgc/allocation.h +104 -45
  6. data/vendor/v8/include/cppgc/common.h +9 -6
  7. data/vendor/v8/include/cppgc/cross-thread-persistent.h +384 -0
  8. data/vendor/v8/include/cppgc/custom-space.h +37 -2
  9. data/vendor/v8/include/cppgc/default-platform.h +47 -48
  10. data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
  11. data/vendor/v8/include/cppgc/explicit-management.h +82 -0
  12. data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
  13. data/vendor/v8/include/cppgc/heap-consistency.h +236 -0
  14. data/vendor/v8/include/cppgc/heap-state.h +70 -0
  15. data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
  16. data/vendor/v8/include/cppgc/heap.h +68 -6
  17. data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
  18. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +2 -1
  19. data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
  20. data/vendor/v8/include/cppgc/internal/gc-info.h +44 -13
  21. data/vendor/v8/include/cppgc/internal/name-trait.h +111 -0
  22. data/vendor/v8/include/cppgc/internal/persistent-node.h +57 -1
  23. data/vendor/v8/include/cppgc/internal/pointer-policies.h +69 -28
  24. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
  25. data/vendor/v8/include/cppgc/internal/write-barrier.h +353 -35
  26. data/vendor/v8/include/cppgc/liveness-broker.h +7 -1
  27. data/vendor/v8/include/cppgc/macros.h +2 -0
  28. data/vendor/v8/include/cppgc/member.h +85 -25
  29. data/vendor/v8/include/cppgc/name-provider.h +65 -0
  30. data/vendor/v8/include/cppgc/object-size-trait.h +58 -0
  31. data/vendor/v8/include/cppgc/persistent.h +33 -9
  32. data/vendor/v8/include/cppgc/platform.h +48 -25
  33. data/vendor/v8/include/cppgc/prefinalizer.h +1 -1
  34. data/vendor/v8/include/cppgc/process-heap-statistics.h +36 -0
  35. data/vendor/v8/include/cppgc/sentinel-pointer.h +32 -0
  36. data/vendor/v8/include/cppgc/source-location.h +2 -1
  37. data/vendor/v8/include/cppgc/testing.h +99 -0
  38. data/vendor/v8/include/cppgc/trace-trait.h +8 -3
  39. data/vendor/v8/include/cppgc/type-traits.h +157 -19
  40. data/vendor/v8/include/cppgc/visitor.h +187 -23
  41. data/vendor/v8/include/libplatform/libplatform.h +11 -0
  42. data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
  43. data/vendor/v8/include/v8-cppgc.h +258 -159
  44. data/vendor/v8/include/v8-fast-api-calls.h +562 -159
  45. data/vendor/v8/include/v8-inspector.h +23 -2
  46. data/vendor/v8/include/v8-internal.h +99 -27
  47. data/vendor/v8/include/v8-metrics.h +77 -8
  48. data/vendor/v8/include/v8-platform.h +47 -22
  49. data/vendor/v8/include/v8-profiler.h +75 -11
  50. data/vendor/v8/include/v8-unwinder-state.h +30 -0
  51. data/vendor/v8/include/v8-util.h +1 -1
  52. data/vendor/v8/include/v8-version.h +4 -4
  53. data/vendor/v8/include/v8.h +1192 -642
  54. data/vendor/v8/include/v8config.h +40 -9
  55. data/vendor/v8/{out.gn → x86_64-linux}/libv8/obj/libv8_monolith.a +0 -0
  56. metadata +17 -5
  57. data/vendor/v8/include/cppgc/internal/process-heap.h +0 -34
@@ -9,13 +9,17 @@
9
9
  #include <type_traits>
10
10
 
11
11
  #include "cppgc/internal/write-barrier.h"
12
+ #include "cppgc/sentinel-pointer.h"
12
13
  #include "cppgc/source-location.h"
14
+ #include "cppgc/type-traits.h"
13
15
  #include "v8config.h" // NOLINT(build/include_directory)
14
16
 
15
17
  namespace cppgc {
16
18
  namespace internal {
17
19
 
20
+ class HeapBase;
18
21
  class PersistentRegion;
22
+ class CrossThreadPersistentRegion;
19
23
 
20
24
  // Tags to distinguish between strong and weak member types.
21
25
  class StrongMemberTag;
@@ -28,7 +32,17 @@ struct DijkstraWriteBarrierPolicy {
28
32
  // barrier doesn't break the tri-color invariant.
29
33
  }
30
34
  static void AssigningBarrier(const void* slot, const void* value) {
31
- WriteBarrier::MarkingBarrier(slot, value);
35
+ WriteBarrier::Params params;
36
+ switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) {
37
+ case WriteBarrier::Type::kGenerational:
38
+ WriteBarrier::GenerationalBarrier(params, slot);
39
+ break;
40
+ case WriteBarrier::Type::kMarking:
41
+ WriteBarrier::DijkstraMarkingBarrier(params, value);
42
+ break;
43
+ case WriteBarrier::Type::kNone:
44
+ break;
45
+ }
32
46
  }
33
47
  };
34
48
 
@@ -39,29 +53,56 @@ struct NoWriteBarrierPolicy {
39
53
 
40
54
  class V8_EXPORT EnabledCheckingPolicy {
41
55
  protected:
42
- EnabledCheckingPolicy();
43
- void CheckPointer(const void* ptr);
56
+ template <typename T>
57
+ void CheckPointer(const T* ptr) {
58
+ if (!ptr || (kSentinelPointer == ptr)) return;
59
+
60
+ CheckPointersImplTrampoline<T>::Call(this, ptr);
61
+ }
44
62
 
45
63
  private:
46
- void* impl_;
64
+ void CheckPointerImpl(const void* ptr, bool points_to_payload);
65
+
66
+ template <typename T, bool = IsCompleteV<T>>
67
+ struct CheckPointersImplTrampoline {
68
+ static void Call(EnabledCheckingPolicy* policy, const T* ptr) {
69
+ policy->CheckPointerImpl(ptr, false);
70
+ }
71
+ };
72
+
73
+ template <typename T>
74
+ struct CheckPointersImplTrampoline<T, true> {
75
+ static void Call(EnabledCheckingPolicy* policy, const T* ptr) {
76
+ policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV<T>);
77
+ }
78
+ };
79
+
80
+ const HeapBase* heap_ = nullptr;
47
81
  };
48
82
 
49
83
  class DisabledCheckingPolicy {
50
84
  protected:
51
- void CheckPointer(const void* raw) {}
85
+ void CheckPointer(const void*) {}
52
86
  };
53
87
 
54
88
  #if V8_ENABLE_CHECKS
55
- using DefaultCheckingPolicy = EnabledCheckingPolicy;
89
+ using DefaultMemberCheckingPolicy = EnabledCheckingPolicy;
90
+ using DefaultPersistentCheckingPolicy = EnabledCheckingPolicy;
56
91
  #else
57
- using DefaultCheckingPolicy = DisabledCheckingPolicy;
92
+ using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
93
+ using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
58
94
  #endif
95
+ // For CT(W)P neither marking information (for value), nor objectstart bitmap
96
+ // (for slot) are guaranteed to be present because there's no synchonization
97
+ // between heaps after marking.
98
+ using DefaultCrossThreadPersistentCheckingPolicy = DisabledCheckingPolicy;
59
99
 
60
100
  class KeepLocationPolicy {
61
101
  public:
62
102
  constexpr const SourceLocation& Location() const { return location_; }
63
103
 
64
104
  protected:
105
+ constexpr KeepLocationPolicy() = default;
65
106
  constexpr explicit KeepLocationPolicy(const SourceLocation& location)
66
107
  : location_(location) {}
67
108
 
@@ -82,6 +123,7 @@ class IgnoreLocationPolicy {
82
123
  constexpr SourceLocation Location() const { return {}; }
83
124
 
84
125
  protected:
126
+ constexpr IgnoreLocationPolicy() = default;
85
127
  constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {}
86
128
  };
87
129
 
@@ -93,42 +135,41 @@ using DefaultLocationPolicy = IgnoreLocationPolicy;
93
135
 
94
136
  struct StrongPersistentPolicy {
95
137
  using IsStrongPersistent = std::true_type;
96
-
97
- static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object);
138
+ static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
98
139
  };
99
140
 
100
141
  struct WeakPersistentPolicy {
101
142
  using IsStrongPersistent = std::false_type;
143
+ static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object);
144
+ };
145
+
146
+ struct StrongCrossThreadPersistentPolicy {
147
+ using IsStrongPersistent = std::true_type;
148
+ static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
149
+ const void* object);
150
+ };
102
151
 
103
- static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object);
152
+ struct WeakCrossThreadPersistentPolicy {
153
+ using IsStrongPersistent = std::false_type;
154
+ static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion(
155
+ const void* object);
104
156
  };
105
157
 
106
- // Persistent/Member forward declarations.
158
+ // Forward declarations setting up the default policies.
159
+ template <typename T, typename WeaknessPolicy,
160
+ typename LocationPolicy = DefaultLocationPolicy,
161
+ typename CheckingPolicy = DefaultCrossThreadPersistentCheckingPolicy>
162
+ class BasicCrossThreadPersistent;
107
163
  template <typename T, typename WeaknessPolicy,
108
164
  typename LocationPolicy = DefaultLocationPolicy,
109
- typename CheckingPolicy = DefaultCheckingPolicy>
165
+ typename CheckingPolicy = DefaultPersistentCheckingPolicy>
110
166
  class BasicPersistent;
111
167
  template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
112
- typename CheckingPolicy = DefaultCheckingPolicy>
168
+ typename CheckingPolicy = DefaultMemberCheckingPolicy>
113
169
  class BasicMember;
114
170
 
115
- // Special tag type used to denote some sentinel member. The semantics of the
116
- // sentinel is defined by the embedder.
117
- struct SentinelPointer {
118
- template <typename T>
119
- operator T*() const { // NOLINT
120
- static constexpr intptr_t kSentinelValue = 1;
121
- return reinterpret_cast<T*>(kSentinelValue);
122
- }
123
- // Hidden friends.
124
- friend bool operator==(SentinelPointer, SentinelPointer) { return true; }
125
- friend bool operator!=(SentinelPointer, SentinelPointer) { return false; }
126
- };
127
-
128
171
  } // namespace internal
129
172
 
130
- constexpr internal::SentinelPointer kSentinelPointer;
131
-
132
173
  } // namespace cppgc
133
174
 
134
175
  #endif // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_
@@ -18,7 +18,7 @@ class V8_EXPORT PreFinalizerRegistrationDispatcher final {
18
18
  void* object;
19
19
  PreFinalizerCallback callback;
20
20
 
21
- bool operator==(const PreFinalizer& other);
21
+ bool operator==(const PreFinalizer& other) const;
22
22
  };
23
23
 
24
24
  static void RegisterPrefinalizer(PreFinalizer pre_finalizer);
@@ -5,8 +5,14 @@
5
5
  #ifndef INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
6
6
  #define INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
7
7
 
8
+ #include <cstddef>
9
+ #include <cstdint>
10
+
11
+ #include "cppgc/heap-state.h"
8
12
  #include "cppgc/internal/api-constants.h"
9
- #include "cppgc/internal/process-heap.h"
13
+ #include "cppgc/internal/atomic-entry-flag.h"
14
+ #include "cppgc/sentinel-pointer.h"
15
+ #include "cppgc/trace-trait.h"
10
16
  #include "v8config.h" // NOLINT(build/include_directory)
11
17
 
12
18
  #if defined(CPPGC_CAGED_HEAP)
@@ -14,64 +20,376 @@
14
20
  #endif
15
21
 
16
22
  namespace cppgc {
23
+
24
+ class HeapHandle;
25
+
17
26
  namespace internal {
18
27
 
28
+ #if defined(CPPGC_CAGED_HEAP)
29
+ class WriteBarrierTypeForCagedHeapPolicy;
30
+ #else // !CPPGC_CAGED_HEAP
31
+ class WriteBarrierTypeForNonCagedHeapPolicy;
32
+ #endif // !CPPGC_CAGED_HEAP
33
+
19
34
  class V8_EXPORT WriteBarrier final {
20
35
  public:
21
- static V8_INLINE void MarkingBarrier(const void* slot, const void* value) {
36
+ enum class Type : uint8_t {
37
+ kNone,
38
+ kMarking,
39
+ kGenerational,
40
+ };
41
+
42
+ struct Params {
43
+ HeapHandle* heap = nullptr;
44
+ #if V8_ENABLE_CHECKS
45
+ Type type = Type::kNone;
46
+ #endif // !V8_ENABLE_CHECKS
47
+ #if defined(CPPGC_CAGED_HEAP)
48
+ uintptr_t start = 0;
49
+ CagedHeapLocalData& caged_heap() const {
50
+ return *reinterpret_cast<CagedHeapLocalData*>(start);
51
+ }
52
+ uintptr_t slot_offset = 0;
53
+ uintptr_t value_offset = 0;
54
+ #endif // CPPGC_CAGED_HEAP
55
+ };
56
+
57
+ enum class ValueMode {
58
+ kValuePresent,
59
+ kNoValuePresent,
60
+ };
61
+
62
+ // Returns the required write barrier for a given `slot` and `value`.
63
+ static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value,
64
+ Params& params);
65
+ // Returns the required write barrier for a given `slot`.
66
+ template <typename HeapHandleCallback>
67
+ static V8_INLINE Type GetWriteBarrierType(const void* slot, Params& params,
68
+ HeapHandleCallback callback);
69
+
70
+ template <typename HeapHandleCallback>
71
+ static V8_INLINE Type GetWriteBarrierTypeForExternallyReferencedObject(
72
+ const void* value, Params& params, HeapHandleCallback callback);
73
+
74
+ static V8_INLINE void DijkstraMarkingBarrier(const Params& params,
75
+ const void* object);
76
+ static V8_INLINE void DijkstraMarkingBarrierRange(
77
+ const Params& params, const void* first_element, size_t element_size,
78
+ size_t number_of_elements, TraceCallback trace_callback);
79
+ static V8_INLINE void SteeleMarkingBarrier(const Params& params,
80
+ const void* object);
81
+ #if defined(CPPGC_YOUNG_GENERATION)
82
+ static V8_INLINE void GenerationalBarrier(const Params& params,
83
+ const void* slot);
84
+ #else // !CPPGC_YOUNG_GENERATION
85
+ static V8_INLINE void GenerationalBarrier(const Params& params,
86
+ const void* slot) {}
87
+ #endif // CPPGC_YOUNG_GENERATION
88
+
89
+ #if V8_ENABLE_CHECKS
90
+ static void CheckParams(Type expected_type, const Params& params);
91
+ #else // !V8_ENABLE_CHECKS
92
+ static void CheckParams(Type expected_type, const Params& params) {}
93
+ #endif // !V8_ENABLE_CHECKS
94
+
95
+ // The IncrementalOrConcurrentUpdater class allows cppgc internal to update
96
+ // |incremental_or_concurrent_marking_flag_|.
97
+ class IncrementalOrConcurrentMarkingFlagUpdater;
98
+ static bool IsAnyIncrementalOrConcurrentMarking() {
99
+ return incremental_or_concurrent_marking_flag_.MightBeEntered();
100
+ }
101
+
102
+ private:
103
+ WriteBarrier() = delete;
104
+
22
105
  #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;
106
+ using WriteBarrierTypePolicy = WriteBarrierTypeForCagedHeapPolicy;
107
+ #else // !CPPGC_CAGED_HEAP
108
+ using WriteBarrierTypePolicy = WriteBarrierTypeForNonCagedHeapPolicy;
109
+ #endif // !CPPGC_CAGED_HEAP
110
+
111
+ static void DijkstraMarkingBarrierSlow(const void* value);
112
+ static void DijkstraMarkingBarrierSlowWithSentinelCheck(const void* value);
113
+ static void DijkstraMarkingBarrierRangeSlow(HeapHandle& heap_handle,
114
+ const void* first_element,
115
+ size_t element_size,
116
+ size_t number_of_elements,
117
+ TraceCallback trace_callback);
118
+ static void SteeleMarkingBarrierSlow(const void* value);
119
+ static void SteeleMarkingBarrierSlowWithSentinelCheck(const void* value);
120
+
121
+ #if defined(CPPGC_YOUNG_GENERATION)
122
+ static CagedHeapLocalData& GetLocalData(HeapHandle&);
123
+ static void GenerationalBarrierSlow(const CagedHeapLocalData& local_data,
124
+ const AgeTable& ageTable,
125
+ const void* slot, uintptr_t value_offset);
126
+ #endif // CPPGC_YOUNG_GENERATION
127
+
128
+ static AtomicEntryFlag incremental_or_concurrent_marking_flag_;
129
+ };
130
+
131
+ template <WriteBarrier::Type type>
132
+ V8_INLINE WriteBarrier::Type SetAndReturnType(WriteBarrier::Params& params) {
133
+ if (type == WriteBarrier::Type::kNone) return WriteBarrier::Type::kNone;
134
+ #if V8_ENABLE_CHECKS
135
+ params.type = type;
136
+ #endif // !V8_ENABLE_CHECKS
137
+ return type;
138
+ }
139
+
140
+ #if defined(CPPGC_CAGED_HEAP)
141
+ class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
142
+ public:
143
+ template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
144
+ static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
145
+ WriteBarrier::Params& params,
146
+ HeapHandleCallback callback) {
147
+ return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
148
+ }
149
+
150
+ template <typename HeapHandleCallback>
151
+ static V8_INLINE WriteBarrier::Type GetForExternallyReferenced(
152
+ const void* value, WriteBarrier::Params& params, HeapHandleCallback) {
153
+ if (!TryGetCagedHeap(value, value, params)) {
154
+ return WriteBarrier::Type::kNone;
155
+ }
156
+ if (V8_UNLIKELY(params.caged_heap().is_incremental_marking_in_progress)) {
157
+ return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
158
+ }
159
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
160
+ }
161
+
162
+ private:
163
+ WriteBarrierTypeForCagedHeapPolicy() = delete;
164
+
165
+ template <WriteBarrier::ValueMode value_mode>
166
+ struct ValueModeDispatch;
167
+
168
+ static V8_INLINE bool TryGetCagedHeap(const void* slot, const void* value,
169
+ WriteBarrier::Params& params) {
170
+ params.start = reinterpret_cast<uintptr_t>(value) &
171
+ ~(api_constants::kCagedHeapReservationAlignment - 1);
172
+ const uintptr_t slot_offset =
173
+ reinterpret_cast<uintptr_t>(slot) - params.start;
27
174
  if (slot_offset > api_constants::kCagedHeapReservationSize) {
28
175
  // Check if slot is on stack or value is sentinel or nullptr. This relies
29
176
  // on the fact that kSentinelPointer is encoded as 0x1.
30
- return;
177
+ return false;
31
178
  }
179
+ return true;
180
+ }
32
181
 
33
- CagedHeapLocalData* local_data =
34
- reinterpret_cast<CagedHeapLocalData*>(start);
35
- if (V8_UNLIKELY(local_data->is_marking_in_progress)) {
36
- MarkingBarrierSlow(value);
37
- return;
182
+ // Returns whether marking is in progress. If marking is not in progress
183
+ // sets the start of the cage accordingly.
184
+ //
185
+ // TODO(chromium:1056170): Create fast path on API.
186
+ static bool IsMarking(const HeapHandle&, WriteBarrier::Params&);
187
+ };
188
+
189
+ template <>
190
+ struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
191
+ WriteBarrier::ValueMode::kValuePresent> {
192
+ template <typename HeapHandleCallback>
193
+ static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
194
+ WriteBarrier::Params& params,
195
+ HeapHandleCallback) {
196
+ bool within_cage = TryGetCagedHeap(slot, value, params);
197
+ if (!within_cage) {
198
+ return WriteBarrier::Type::kNone;
38
199
  }
200
+ if (V8_LIKELY(!params.caged_heap().is_incremental_marking_in_progress)) {
39
201
  #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;
202
+ params.heap = reinterpret_cast<HeapHandle*>(params.start);
203
+ params.slot_offset = reinterpret_cast<uintptr_t>(slot) - params.start;
204
+ params.value_offset = reinterpret_cast<uintptr_t>(value) - params.start;
205
+ return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
206
+ #else // !CPPGC_YOUNG_GENERATION
207
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
208
+ #endif // !CPPGC_YOUNG_GENERATION
209
+ }
210
+ params.heap = reinterpret_cast<HeapHandle*>(params.start);
211
+ return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
212
+ }
213
+ };
214
+
215
+ template <>
216
+ struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
217
+ WriteBarrier::ValueMode::kNoValuePresent> {
218
+ template <typename HeapHandleCallback>
219
+ static V8_INLINE WriteBarrier::Type Get(const void* slot, const void*,
220
+ WriteBarrier::Params& params,
221
+ HeapHandleCallback callback) {
222
+ #if defined(CPPGC_YOUNG_GENERATION)
223
+ HeapHandle& handle = callback();
224
+ if (V8_LIKELY(!IsMarking(handle, params))) {
225
+ // params.start is populated by IsMarking().
226
+ params.heap = &handle;
227
+ params.slot_offset = reinterpret_cast<uintptr_t>(slot) - params.start;
228
+ // params.value_offset stays 0.
229
+ if (params.slot_offset > api_constants::kCagedHeapReservationSize) {
230
+ // Check if slot is on stack.
231
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
232
+ }
233
+ return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
234
+ }
235
+ #else // !CPPGC_YOUNG_GENERATION
236
+ if (V8_LIKELY(!WriteBarrier::IsAnyIncrementalOrConcurrentMarking())) {
237
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
238
+ }
239
+ HeapHandle& handle = callback();
240
+ if (V8_UNLIKELY(!subtle::HeapState::IsMarking(handle))) {
241
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
242
+ }
243
+ #endif // !CPPGC_YOUNG_GENERATION
244
+ params.heap = &handle;
245
+ return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
246
+ }
247
+ };
45
248
 
46
- MarkingBarrierSlowWithSentinelCheck(value);
47
249
  #endif // CPPGC_CAGED_HEAP
250
+
251
+ class V8_EXPORT WriteBarrierTypeForNonCagedHeapPolicy final {
252
+ public:
253
+ template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
254
+ static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
255
+ WriteBarrier::Params& params,
256
+ HeapHandleCallback callback) {
257
+ return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
48
258
  }
49
259
 
50
- private:
51
- WriteBarrier() = delete;
260
+ template <typename HeapHandleCallback>
261
+ static V8_INLINE WriteBarrier::Type GetForExternallyReferenced(
262
+ const void* value, WriteBarrier::Params& params,
263
+ HeapHandleCallback callback) {
264
+ // The slot will never be used in `Get()` below.
265
+ return Get<WriteBarrier::ValueMode::kValuePresent>(nullptr, value, params,
266
+ callback);
267
+ }
52
268
 
53
- static void MarkingBarrierSlow(const void* value);
54
- static void MarkingBarrierSlowWithSentinelCheck(const void* value);
269
+ private:
270
+ template <WriteBarrier::ValueMode value_mode>
271
+ struct ValueModeDispatch;
55
272
 
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;
273
+ // TODO(chromium:1056170): Create fast path on API.
274
+ static bool IsMarking(const void*, HeapHandle**);
275
+ // TODO(chromium:1056170): Create fast path on API.
276
+ static bool IsMarking(HeapHandle&);
62
277
 
63
- // Bail out if the slot is in young generation.
64
- if (V8_LIKELY(age_table[slot_offset] == AgeTable::Age::kYoung)) return;
278
+ WriteBarrierTypeForNonCagedHeapPolicy() = delete;
279
+ };
65
280
 
66
- GenerationalBarrierSlow(local_data, age_table, slot, value_offset);
281
+ template <>
282
+ struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
283
+ WriteBarrier::ValueMode::kValuePresent> {
284
+ template <typename HeapHandleCallback>
285
+ static V8_INLINE WriteBarrier::Type Get(const void*, const void* object,
286
+ WriteBarrier::Params& params,
287
+ HeapHandleCallback callback) {
288
+ // The following check covers nullptr as well as sentinel pointer.
289
+ if (object <= static_cast<void*>(kSentinelPointer)) {
290
+ return WriteBarrier::Type::kNone;
291
+ }
292
+ if (IsMarking(object, &params.heap)) {
293
+ return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
294
+ }
295
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
67
296
  }
297
+ };
68
298
 
69
- static void GenerationalBarrierSlow(CagedHeapLocalData* local_data,
70
- const AgeTable& ageTable,
71
- const void* slot, uintptr_t value_offset);
72
- #endif
299
+ template <>
300
+ struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
301
+ WriteBarrier::ValueMode::kNoValuePresent> {
302
+ template <typename HeapHandleCallback>
303
+ static V8_INLINE WriteBarrier::Type Get(const void*, const void*,
304
+ WriteBarrier::Params& params,
305
+ HeapHandleCallback callback) {
306
+ if (V8_UNLIKELY(WriteBarrier::IsAnyIncrementalOrConcurrentMarking())) {
307
+ HeapHandle& handle = callback();
308
+ if (IsMarking(handle)) {
309
+ params.heap = &handle;
310
+ return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
311
+ }
312
+ }
313
+ return WriteBarrier::Type::kNone;
314
+ }
73
315
  };
74
316
 
317
+ // static
318
+ WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
319
+ const void* slot, const void* value, WriteBarrier::Params& params) {
320
+ return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
321
+ params, []() {});
322
+ }
323
+
324
+ // static
325
+ template <typename HeapHandleCallback>
326
+ WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
327
+ const void* slot, WriteBarrier::Params& params,
328
+ HeapHandleCallback callback) {
329
+ return WriteBarrierTypePolicy::Get<ValueMode::kNoValuePresent>(
330
+ slot, nullptr, params, callback);
331
+ }
332
+
333
+ // static
334
+ template <typename HeapHandleCallback>
335
+ WriteBarrier::Type
336
+ WriteBarrier::GetWriteBarrierTypeForExternallyReferencedObject(
337
+ const void* value, Params& params, HeapHandleCallback callback) {
338
+ return WriteBarrierTypePolicy::GetForExternallyReferenced(value, params,
339
+ callback);
340
+ }
341
+
342
+ // static
343
+ void WriteBarrier::DijkstraMarkingBarrier(const Params& params,
344
+ const void* object) {
345
+ CheckParams(Type::kMarking, params);
346
+ #if defined(CPPGC_CAGED_HEAP)
347
+ // Caged heap already filters out sentinels.
348
+ DijkstraMarkingBarrierSlow(object);
349
+ #else // !CPPGC_CAGED_HEAP
350
+ DijkstraMarkingBarrierSlowWithSentinelCheck(object);
351
+ #endif // !CPPGC_CAGED_HEAP
352
+ }
353
+
354
+ // static
355
+ void WriteBarrier::DijkstraMarkingBarrierRange(const Params& params,
356
+ const void* first_element,
357
+ size_t element_size,
358
+ size_t number_of_elements,
359
+ TraceCallback trace_callback) {
360
+ CheckParams(Type::kMarking, params);
361
+ DijkstraMarkingBarrierRangeSlow(*params.heap, first_element, element_size,
362
+ number_of_elements, trace_callback);
363
+ }
364
+
365
+ // static
366
+ void WriteBarrier::SteeleMarkingBarrier(const Params& params,
367
+ const void* object) {
368
+ CheckParams(Type::kMarking, params);
369
+ #if defined(CPPGC_CAGED_HEAP)
370
+ // Caged heap already filters out sentinels.
371
+ SteeleMarkingBarrierSlow(object);
372
+ #else // !CPPGC_CAGED_HEAP
373
+ SteeleMarkingBarrierSlowWithSentinelCheck(object);
374
+ #endif // !CPPGC_CAGED_HEAP
375
+ }
376
+
377
+ #if defined(CPPGC_YOUNG_GENERATION)
378
+ // static
379
+ void WriteBarrier::GenerationalBarrier(const Params& params, const void* slot) {
380
+ CheckParams(Type::kGenerational, params);
381
+
382
+ const CagedHeapLocalData& local_data = params.caged_heap();
383
+ const AgeTable& age_table = local_data.age_table;
384
+
385
+ // Bail out if the slot is in young generation.
386
+ if (V8_LIKELY(age_table[params.slot_offset] == AgeTable::Age::kYoung)) return;
387
+
388
+ GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset);
389
+ }
390
+
391
+ #endif // !CPPGC_YOUNG_GENERATION
392
+
75
393
  } // namespace internal
76
394
  } // namespace cppgc
77
395
 
@@ -19,7 +19,7 @@ class LivenessBrokerFactory;
19
19
  /**
20
20
  * The broker is passed to weak callbacks to allow (temporarily) querying
21
21
  * the liveness state of an object. References to non-live objects must be
22
- * cleared when IsHeapObjectAlive() returns false.
22
+ * cleared when `IsHeapObjectAlive()` returns false.
23
23
  *
24
24
  * \code
25
25
  * class GCedWithCustomWeakCallback final
@@ -49,6 +49,12 @@ class V8_EXPORT LivenessBroker final {
49
49
  TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
50
50
  }
51
51
 
52
+ template <typename T>
53
+ bool IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
54
+ return (weak_member != kSentinelPointer) &&
55
+ IsHeapObjectAlive<T>(weak_member.Get());
56
+ }
57
+
52
58
  template <typename T>
53
59
  bool IsHeapObjectAlive(const UntracedMember<T>& untraced_member) const {
54
60
  return (untraced_member != kSentinelPointer) &&
@@ -5,6 +5,8 @@
5
5
  #ifndef INCLUDE_CPPGC_MACROS_H_
6
6
  #define INCLUDE_CPPGC_MACROS_H_
7
7
 
8
+ #include <cstddef>
9
+
8
10
  #include "cppgc/internal/compiler-specific.h"
9
11
 
10
12
  namespace cppgc {