libv8-node 18.13.0.1-x86_64-darwin → 20.2.0.0-x86_64-darwin

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-darwin/libv8/obj/libv8_monolith.a +0 -0
  70. metadata +5 -1
@@ -8,9 +8,12 @@
8
8
  #include <cstddef>
9
9
  #include <cstdint>
10
10
 
11
+ #include "cppgc/heap-handle.h"
11
12
  #include "cppgc/heap-state.h"
12
13
  #include "cppgc/internal/api-constants.h"
13
14
  #include "cppgc/internal/atomic-entry-flag.h"
15
+ #include "cppgc/internal/base-page-handle.h"
16
+ #include "cppgc/internal/member-storage.h"
14
17
  #include "cppgc/platform.h"
15
18
  #include "cppgc/sentinel-pointer.h"
16
19
  #include "cppgc/trace-trait.h"
@@ -18,6 +21,7 @@
18
21
 
19
22
  #if defined(CPPGC_CAGED_HEAP)
20
23
  #include "cppgc/internal/caged-heap-local-data.h"
24
+ #include "cppgc/internal/caged-heap.h"
21
25
  #endif
22
26
 
23
27
  namespace cppgc {
@@ -40,16 +44,18 @@ class V8_EXPORT WriteBarrier final {
40
44
  kGenerational,
41
45
  };
42
46
 
47
+ enum class GenerationalBarrierType : uint8_t {
48
+ kPreciseSlot,
49
+ kPreciseUncompressedSlot,
50
+ kImpreciseSlot,
51
+ };
52
+
43
53
  struct Params {
44
54
  HeapHandle* heap = nullptr;
45
55
  #if V8_ENABLE_CHECKS
46
56
  Type type = Type::kNone;
47
57
  #endif // !V8_ENABLE_CHECKS
48
58
  #if defined(CPPGC_CAGED_HEAP)
49
- uintptr_t start = 0;
50
- CagedHeapLocalData& caged_heap() const {
51
- return *reinterpret_cast<CagedHeapLocalData*>(start);
52
- }
53
59
  uintptr_t slot_offset = 0;
54
60
  uintptr_t value_offset = 0;
55
61
  #endif // CPPGC_CAGED_HEAP
@@ -63,6 +69,10 @@ class V8_EXPORT WriteBarrier final {
63
69
  // Returns the required write barrier for a given `slot` and `value`.
64
70
  static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value,
65
71
  Params& params);
72
+ // Returns the required write barrier for a given `slot` and `value`.
73
+ template <typename MemberStorage>
74
+ static V8_INLINE Type GetWriteBarrierType(const void* slot, MemberStorage,
75
+ Params& params);
66
76
  // Returns the required write barrier for a given `slot`.
67
77
  template <typename HeapHandleCallback>
68
78
  static V8_INLINE Type GetWriteBarrierType(const void* slot, Params& params,
@@ -70,6 +80,15 @@ class V8_EXPORT WriteBarrier final {
70
80
  // Returns the required write barrier for a given `value`.
71
81
  static V8_INLINE Type GetWriteBarrierType(const void* value, Params& params);
72
82
 
83
+ #ifdef CPPGC_SLIM_WRITE_BARRIER
84
+ // A write barrier that combines `GenerationalBarrier()` and
85
+ // `DijkstraMarkingBarrier()`. We only pass a single parameter here to clobber
86
+ // as few registers as possible.
87
+ template <WriteBarrierSlotType>
88
+ static V8_NOINLINE void V8_PRESERVE_MOST
89
+ CombinedWriteBarrierSlow(const void* slot);
90
+ #endif // CPPGC_SLIM_WRITE_BARRIER
91
+
73
92
  static V8_INLINE void DijkstraMarkingBarrier(const Params& params,
74
93
  const void* object);
75
94
  static V8_INLINE void DijkstraMarkingBarrierRange(
@@ -78,15 +97,13 @@ class V8_EXPORT WriteBarrier final {
78
97
  static V8_INLINE void SteeleMarkingBarrier(const Params& params,
79
98
  const void* object);
80
99
  #if defined(CPPGC_YOUNG_GENERATION)
100
+ template <GenerationalBarrierType>
81
101
  static V8_INLINE void GenerationalBarrier(const Params& params,
82
102
  const void* slot);
83
- static V8_INLINE void GenerationalBarrierForSourceObject(
84
- const Params& params, const void* inner_pointer);
85
103
  #else // !CPPGC_YOUNG_GENERATION
104
+ template <GenerationalBarrierType>
86
105
  static V8_INLINE void GenerationalBarrier(const Params& params,
87
- const void* slot) {}
88
- static V8_INLINE void GenerationalBarrierForSourceObject(
89
- const Params& params, const void* inner_pointer) {}
106
+ const void* slot){}
90
107
  #endif // CPPGC_YOUNG_GENERATION
91
108
 
92
109
  #if V8_ENABLE_CHECKS
@@ -95,12 +112,10 @@ class V8_EXPORT WriteBarrier final {
95
112
  static void CheckParams(Type expected_type, const Params& params) {}
96
113
  #endif // !V8_ENABLE_CHECKS
97
114
 
98
- // The IncrementalOrConcurrentUpdater class allows cppgc internal to update
99
- // |incremental_or_concurrent_marking_flag_|.
100
- class IncrementalOrConcurrentMarkingFlagUpdater;
101
- static bool IsAnyIncrementalOrConcurrentMarking() {
102
- return incremental_or_concurrent_marking_flag_.MightBeEntered();
103
- }
115
+ // The FlagUpdater class allows cppgc internal to update
116
+ // |write_barrier_enabled_|.
117
+ class FlagUpdater;
118
+ static bool IsEnabled() { return write_barrier_enabled_.MightBeEntered(); }
104
119
 
105
120
  private:
106
121
  WriteBarrier() = delete;
@@ -125,17 +140,23 @@ class V8_EXPORT WriteBarrier final {
125
140
  static CagedHeapLocalData& GetLocalData(HeapHandle&);
126
141
  static void GenerationalBarrierSlow(const CagedHeapLocalData& local_data,
127
142
  const AgeTable& age_table,
128
- const void* slot, uintptr_t value_offset);
143
+ const void* slot, uintptr_t value_offset,
144
+ HeapHandle* heap_handle);
145
+ static void GenerationalBarrierForUncompressedSlotSlow(
146
+ const CagedHeapLocalData& local_data, const AgeTable& age_table,
147
+ const void* slot, uintptr_t value_offset, HeapHandle* heap_handle);
129
148
  static void GenerationalBarrierForSourceObjectSlow(
130
- const CagedHeapLocalData& local_data, const void* object);
149
+ const CagedHeapLocalData& local_data, const void* object,
150
+ HeapHandle* heap_handle);
131
151
  #endif // CPPGC_YOUNG_GENERATION
132
152
 
133
- static AtomicEntryFlag incremental_or_concurrent_marking_flag_;
153
+ static AtomicEntryFlag write_barrier_enabled_;
134
154
  };
135
155
 
136
156
  template <WriteBarrier::Type type>
137
157
  V8_INLINE WriteBarrier::Type SetAndReturnType(WriteBarrier::Params& params) {
138
- if (type == WriteBarrier::Type::kNone) return WriteBarrier::Type::kNone;
158
+ if constexpr (type == WriteBarrier::Type::kNone)
159
+ return WriteBarrier::Type::kNone;
139
160
  #if V8_ENABLE_CHECKS
140
161
  params.type = type;
141
162
  #endif // !V8_ENABLE_CHECKS
@@ -152,6 +173,14 @@ class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
152
173
  return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
153
174
  }
154
175
 
176
+ template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback,
177
+ typename MemberStorage>
178
+ static V8_INLINE WriteBarrier::Type Get(const void* slot, MemberStorage value,
179
+ WriteBarrier::Params& params,
180
+ HeapHandleCallback callback) {
181
+ return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
182
+ }
183
+
155
184
  template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
156
185
  static V8_INLINE WriteBarrier::Type Get(const void* value,
157
186
  WriteBarrier::Params& params,
@@ -166,69 +195,77 @@ class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
166
195
  static V8_INLINE WriteBarrier::Type GetNoSlot(const void* value,
167
196
  WriteBarrier::Params& params,
168
197
  HeapHandleCallback) {
169
- if (!TryGetCagedHeap(value, value, params)) {
170
- return WriteBarrier::Type::kNone;
171
- }
172
- if (V8_UNLIKELY(params.caged_heap().is_incremental_marking_in_progress)) {
198
+ const bool within_cage = CagedHeapBase::IsWithinCage(value);
199
+ if (!within_cage) return WriteBarrier::Type::kNone;
200
+
201
+ // We know that |value| points either within the normal page or to the
202
+ // beginning of large-page, so extract the page header by bitmasking.
203
+ BasePageHandle* page =
204
+ BasePageHandle::FromPayload(const_cast<void*>(value));
205
+
206
+ HeapHandle& heap_handle = page->heap_handle();
207
+ if (V8_UNLIKELY(heap_handle.is_incremental_marking_in_progress())) {
173
208
  return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
174
209
  }
210
+
175
211
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
176
212
  }
177
213
 
178
214
  template <WriteBarrier::ValueMode value_mode>
179
215
  struct ValueModeDispatch;
180
-
181
- static V8_INLINE bool TryGetCagedHeap(const void* slot, const void* value,
182
- WriteBarrier::Params& params) {
183
- // TODO(chromium:1056170): Check if the null check can be folded in with
184
- // the rest of the write barrier.
185
- if (!value) return false;
186
- params.start = reinterpret_cast<uintptr_t>(value) &
187
- ~(api_constants::kCagedHeapReservationAlignment - 1);
188
- const uintptr_t slot_offset =
189
- reinterpret_cast<uintptr_t>(slot) - params.start;
190
- if (slot_offset > api_constants::kCagedHeapReservationSize) {
191
- // Check if slot is on stack or value is sentinel or nullptr. This relies
192
- // on the fact that kSentinelPointer is encoded as 0x1.
193
- return false;
194
- }
195
- return true;
196
- }
197
-
198
- // Returns whether marking is in progress. If marking is not in progress
199
- // sets the start of the cage accordingly.
200
- //
201
- // TODO(chromium:1056170): Create fast path on API.
202
- static bool IsMarking(const HeapHandle&, WriteBarrier::Params&);
203
216
  };
204
217
 
205
218
  template <>
206
219
  struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
207
220
  WriteBarrier::ValueMode::kValuePresent> {
221
+ template <typename HeapHandleCallback, typename MemberStorage>
222
+ static V8_INLINE WriteBarrier::Type Get(const void* slot,
223
+ MemberStorage storage,
224
+ WriteBarrier::Params& params,
225
+ HeapHandleCallback) {
226
+ if (V8_LIKELY(!WriteBarrier::IsEnabled()))
227
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
228
+
229
+ return BarrierEnabledGet(slot, storage.Load(), params);
230
+ }
231
+
208
232
  template <typename HeapHandleCallback>
209
233
  static V8_INLINE WriteBarrier::Type Get(const void* slot, const void* value,
210
234
  WriteBarrier::Params& params,
211
235
  HeapHandleCallback) {
212
- #if !defined(CPPGC_YOUNG_GENERATION)
213
- if (V8_LIKELY(!WriteBarrier::IsAnyIncrementalOrConcurrentMarking())) {
236
+ if (V8_LIKELY(!WriteBarrier::IsEnabled()))
214
237
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
215
- }
216
- #endif // !CPPGC_YOUNG_GENERATION
217
- bool within_cage = TryGetCagedHeap(slot, value, params);
218
- if (!within_cage) {
219
- return WriteBarrier::Type::kNone;
220
- }
221
- if (V8_LIKELY(!params.caged_heap().is_incremental_marking_in_progress)) {
238
+
239
+ return BarrierEnabledGet(slot, value, params);
240
+ }
241
+
242
+ private:
243
+ static V8_INLINE WriteBarrier::Type BarrierEnabledGet(
244
+ const void* slot, const void* value, WriteBarrier::Params& params) {
245
+ const bool within_cage = CagedHeapBase::AreWithinCage(slot, value);
246
+ if (!within_cage) return WriteBarrier::Type::kNone;
247
+
248
+ // We know that |value| points either within the normal page or to the
249
+ // beginning of large-page, so extract the page header by bitmasking.
250
+ BasePageHandle* page =
251
+ BasePageHandle::FromPayload(const_cast<void*>(value));
252
+
253
+ HeapHandle& heap_handle = page->heap_handle();
254
+ if (V8_LIKELY(!heap_handle.is_incremental_marking_in_progress())) {
222
255
  #if defined(CPPGC_YOUNG_GENERATION)
223
- params.heap = reinterpret_cast<HeapHandle*>(params.start);
224
- params.slot_offset = reinterpret_cast<uintptr_t>(slot) - params.start;
225
- params.value_offset = reinterpret_cast<uintptr_t>(value) - params.start;
256
+ if (!heap_handle.is_young_generation_enabled())
257
+ return WriteBarrier::Type::kNone;
258
+ params.heap = &heap_handle;
259
+ params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
260
+ params.value_offset = CagedHeapBase::OffsetFromAddress(value);
226
261
  return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
227
262
  #else // !CPPGC_YOUNG_GENERATION
228
263
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
229
264
  #endif // !CPPGC_YOUNG_GENERATION
230
265
  }
231
- params.heap = reinterpret_cast<HeapHandle*>(params.start);
266
+
267
+ // Use marking barrier.
268
+ params.heap = &heap_handle;
232
269
  return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
233
270
  }
234
271
  };
@@ -240,28 +277,28 @@ struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
240
277
  static V8_INLINE WriteBarrier::Type Get(const void* slot, const void*,
241
278
  WriteBarrier::Params& params,
242
279
  HeapHandleCallback callback) {
243
- #if defined(CPPGC_YOUNG_GENERATION)
280
+ if (V8_LIKELY(!WriteBarrier::IsEnabled()))
281
+ return SetAndReturnType<WriteBarrier::Type::kNone>(params);
282
+
244
283
  HeapHandle& handle = callback();
245
- if (V8_LIKELY(!IsMarking(handle, params))) {
246
- // params.start is populated by IsMarking().
284
+ #if defined(CPPGC_YOUNG_GENERATION)
285
+ if (V8_LIKELY(!handle.is_incremental_marking_in_progress())) {
286
+ if (!handle.is_young_generation_enabled()) {
287
+ return WriteBarrier::Type::kNone;
288
+ }
247
289
  params.heap = &handle;
248
- params.slot_offset = reinterpret_cast<uintptr_t>(slot) - params.start;
249
- // params.value_offset stays 0.
250
- if (params.slot_offset > api_constants::kCagedHeapReservationSize) {
251
- // Check if slot is on stack.
290
+ // Check if slot is on stack.
291
+ if (V8_UNLIKELY(!CagedHeapBase::IsWithinCage(slot))) {
252
292
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
253
293
  }
294
+ params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
254
295
  return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
255
296
  }
256
- #else // !CPPGC_YOUNG_GENERATION
257
- if (V8_LIKELY(!WriteBarrier::IsAnyIncrementalOrConcurrentMarking())) {
258
- return SetAndReturnType<WriteBarrier::Type::kNone>(params);
259
- }
260
- HeapHandle& handle = callback();
261
- if (V8_UNLIKELY(!subtle::HeapState::IsMarking(handle))) {
297
+ #else // !defined(CPPGC_YOUNG_GENERATION)
298
+ if (V8_UNLIKELY(!handle.is_incremental_marking_in_progress())) {
262
299
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
263
300
  }
264
- #endif // !CPPGC_YOUNG_GENERATION
301
+ #endif // !defined(CPPGC_YOUNG_GENERATION)
265
302
  params.heap = &handle;
266
303
  return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
267
304
  }
@@ -278,6 +315,14 @@ class V8_EXPORT WriteBarrierTypeForNonCagedHeapPolicy final {
278
315
  return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
279
316
  }
280
317
 
318
+ template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
319
+ static V8_INLINE WriteBarrier::Type Get(const void* slot, RawPointer value,
320
+ WriteBarrier::Params& params,
321
+ HeapHandleCallback callback) {
322
+ return ValueModeDispatch<value_mode>::Get(slot, value.Load(), params,
323
+ callback);
324
+ }
325
+
281
326
  template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
282
327
  static V8_INLINE WriteBarrier::Type Get(const void* value,
283
328
  WriteBarrier::Params& params,
@@ -291,11 +336,6 @@ class V8_EXPORT WriteBarrierTypeForNonCagedHeapPolicy final {
291
336
  template <WriteBarrier::ValueMode value_mode>
292
337
  struct ValueModeDispatch;
293
338
 
294
- // TODO(chromium:1056170): Create fast path on API.
295
- static bool IsMarking(const void*, HeapHandle**);
296
- // TODO(chromium:1056170): Create fast path on API.
297
- static bool IsMarking(HeapHandle&);
298
-
299
339
  WriteBarrierTypeForNonCagedHeapPolicy() = delete;
300
340
  };
301
341
 
@@ -310,10 +350,16 @@ struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
310
350
  if (object <= static_cast<void*>(kSentinelPointer)) {
311
351
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
312
352
  }
313
- if (V8_LIKELY(!WriteBarrier::IsAnyIncrementalOrConcurrentMarking())) {
353
+ if (V8_LIKELY(!WriteBarrier::IsEnabled())) {
314
354
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
315
355
  }
316
- if (IsMarking(object, &params.heap)) {
356
+ // We know that |object| is within the normal page or in the beginning of a
357
+ // large page, so extract the page header by bitmasking.
358
+ BasePageHandle* page =
359
+ BasePageHandle::FromPayload(const_cast<void*>(object));
360
+
361
+ HeapHandle& heap_handle = page->heap_handle();
362
+ if (V8_LIKELY(heap_handle.is_incremental_marking_in_progress())) {
317
363
  return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
318
364
  }
319
365
  return SetAndReturnType<WriteBarrier::Type::kNone>(params);
@@ -327,9 +373,9 @@ struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
327
373
  static V8_INLINE WriteBarrier::Type Get(const void*, const void*,
328
374
  WriteBarrier::Params& params,
329
375
  HeapHandleCallback callback) {
330
- if (V8_UNLIKELY(WriteBarrier::IsAnyIncrementalOrConcurrentMarking())) {
376
+ if (V8_UNLIKELY(WriteBarrier::IsEnabled())) {
331
377
  HeapHandle& handle = callback();
332
- if (IsMarking(handle)) {
378
+ if (V8_LIKELY(handle.is_incremental_marking_in_progress())) {
333
379
  params.heap = &handle;
334
380
  return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
335
381
  }
@@ -345,6 +391,14 @@ WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
345
391
  params, []() {});
346
392
  }
347
393
 
394
+ // static
395
+ template <typename MemberStorage>
396
+ WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
397
+ const void* slot, MemberStorage value, WriteBarrier::Params& params) {
398
+ return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
399
+ params, []() {});
400
+ }
401
+
348
402
  // static
349
403
  template <typename HeapHandleCallback>
350
404
  WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
@@ -397,34 +451,32 @@ void WriteBarrier::SteeleMarkingBarrier(const Params& params,
397
451
  }
398
452
 
399
453
  #if defined(CPPGC_YOUNG_GENERATION)
400
- // static
401
- void WriteBarrier::GenerationalBarrier(const Params& params, const void* slot) {
402
- CheckParams(Type::kGenerational, params);
403
-
404
- const CagedHeapLocalData& local_data = params.caged_heap();
405
- const AgeTable& age_table = local_data.age_table;
406
-
407
- // Bail out if the slot is in young generation.
408
- if (V8_LIKELY(age_table.GetAge(params.slot_offset) == AgeTable::Age::kYoung))
409
- return;
410
-
411
- GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset);
412
- }
413
454
 
414
455
  // static
415
- void WriteBarrier::GenerationalBarrierForSourceObject(
416
- const Params& params, const void* inner_pointer) {
456
+ template <WriteBarrier::GenerationalBarrierType type>
457
+ void WriteBarrier::GenerationalBarrier(const Params& params, const void* slot) {
417
458
  CheckParams(Type::kGenerational, params);
418
459
 
419
- const CagedHeapLocalData& local_data = params.caged_heap();
460
+ const CagedHeapLocalData& local_data = CagedHeapLocalData::Get();
420
461
  const AgeTable& age_table = local_data.age_table;
421
462
 
422
- // Assume that if the first element is in young generation, the whole range is
423
- // in young generation.
463
+ // Bail out if the slot (precise or imprecise) is in young generation.
424
464
  if (V8_LIKELY(age_table.GetAge(params.slot_offset) == AgeTable::Age::kYoung))
425
465
  return;
426
466
 
427
- GenerationalBarrierForSourceObjectSlow(local_data, inner_pointer);
467
+ // Dispatch between different types of barriers.
468
+ // TODO(chromium:1029379): Consider reload local_data in the slow path to
469
+ // reduce register pressure.
470
+ if constexpr (type == GenerationalBarrierType::kPreciseSlot) {
471
+ GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset,
472
+ params.heap);
473
+ } else if constexpr (type ==
474
+ GenerationalBarrierType::kPreciseUncompressedSlot) {
475
+ GenerationalBarrierForUncompressedSlotSlow(
476
+ local_data, age_table, slot, params.value_offset, params.heap);
477
+ } else {
478
+ GenerationalBarrierForSourceObjectSlow(local_data, slot, params.heap);
479
+ }
428
480
  }
429
481
 
430
482
  #endif // !CPPGC_YOUNG_GENERATION
@@ -7,6 +7,7 @@
7
7
 
8
8
  #include "cppgc/heap.h"
9
9
  #include "cppgc/member.h"
10
+ #include "cppgc/sentinel-pointer.h"
10
11
  #include "cppgc/trace-trait.h"
11
12
  #include "v8config.h" // NOLINT(build/include_directory)
12
13
 
@@ -44,24 +45,24 @@ class V8_EXPORT LivenessBroker final {
44
45
  public:
45
46
  template <typename T>
46
47
  bool IsHeapObjectAlive(const T* object) const {
47
- // nullptr objects are considered alive to allow weakness to be used from
48
+ // - nullptr objects are considered alive to allow weakness to be used from
48
49
  // stack while running into a conservative GC. Treating nullptr as dead
49
- // would mean that e.g. custom collectins could not be strongified on stack.
50
- return !object ||
50
+ // would mean that e.g. custom collections could not be strongified on
51
+ // stack.
52
+ // - Sentinel pointers are also preserved in weakness and not cleared.
53
+ return !object || object == kSentinelPointer ||
51
54
  IsHeapObjectAliveImpl(
52
55
  TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
53
56
  }
54
57
 
55
58
  template <typename T>
56
59
  bool IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
57
- return (weak_member != kSentinelPointer) &&
58
- IsHeapObjectAlive<T>(weak_member.Get());
60
+ return IsHeapObjectAlive<T>(weak_member.Get());
59
61
  }
60
62
 
61
63
  template <typename T>
62
64
  bool IsHeapObjectAlive(const UntracedMember<T>& untraced_member) const {
63
- return (untraced_member != kSentinelPointer) &&
64
- IsHeapObjectAlive<T>(untraced_member.Get());
65
+ return IsHeapObjectAlive<T>(untraced_member.Get());
65
66
  }
66
67
 
67
68
  private:
@@ -11,7 +11,10 @@
11
11
 
12
12
  namespace cppgc {
13
13
 
14
- // Use if the object is only stack allocated.
14
+ // Use CPPGC_STACK_ALLOCATED if the object is only stack allocated.
15
+ // Add the CPPGC_STACK_ALLOCATED_IGNORE annotation on a case-by-case basis when
16
+ // enforcement of CPPGC_STACK_ALLOCATED should be suppressed.
17
+ #if defined(__clang__)
15
18
  #define CPPGC_STACK_ALLOCATED() \
16
19
  public: \
17
20
  using IsStackAllocatedTypeMarker CPPGC_UNUSED = int; \
@@ -20,6 +23,12 @@ namespace cppgc {
20
23
  void* operator new(size_t) = delete; \
21
24
  void* operator new(size_t, void*) = delete; \
22
25
  static_assert(true, "Force semicolon.")
26
+ #define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason) \
27
+ __attribute__((annotate("stack_allocated_ignore")))
28
+ #else // !defined(__clang__)
29
+ #define CPPGC_STACK_ALLOCATED() static_assert(true, "Force semicolon.")
30
+ #define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason)
31
+ #endif // !defined(__clang__)
23
32
 
24
33
  } // namespace cppgc
25
34