node-linux-arm64 23.10.0 → 24.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +427 -1829
  2. package/LICENSE +3 -3
  3. package/README.md +8 -4
  4. package/bin/node +0 -0
  5. package/include/node/common.gypi +4 -11
  6. package/include/node/config.gypi +5 -6
  7. package/include/node/cppgc/allocation.h +1 -2
  8. package/include/node/cppgc/default-platform.h +3 -2
  9. package/include/node/cppgc/heap-consistency.h +1 -1
  10. package/include/node/cppgc/internal/api-constants.h +0 -17
  11. package/include/node/cppgc/internal/base-page-handle.h +2 -4
  12. package/include/node/cppgc/internal/caged-heap-local-data.h +0 -4
  13. package/include/node/cppgc/internal/caged-heap.h +0 -4
  14. package/include/node/cppgc/internal/conditional-stack-allocated.h +41 -0
  15. package/include/node/cppgc/internal/logging.h +3 -3
  16. package/include/node/cppgc/internal/member-storage.h +63 -20
  17. package/include/node/cppgc/internal/persistent-node.h +8 -3
  18. package/include/node/cppgc/internal/pointer-policies.h +48 -11
  19. package/include/node/cppgc/macros.h +21 -0
  20. package/include/node/cppgc/member.h +70 -36
  21. package/include/node/cppgc/name-provider.h +3 -0
  22. package/include/node/cppgc/platform.h +11 -0
  23. package/include/node/cppgc/type-traits.h +1 -0
  24. package/include/node/cppgc/visitor.h +25 -1
  25. package/include/node/libplatform/libplatform-export.h +2 -2
  26. package/include/node/libplatform/v8-tracing.h +0 -1
  27. package/include/node/node.h +58 -15
  28. package/include/node/node_version.h +3 -3
  29. package/include/node/v8-array-buffer.h +111 -34
  30. package/include/node/v8-callbacks.h +84 -26
  31. package/include/node/v8-context.h +7 -6
  32. package/include/node/v8-cppgc.h +2 -1
  33. package/include/node/v8-data.h +5 -0
  34. package/include/node/v8-debug.h +11 -0
  35. package/include/node/v8-embedder-heap.h +1 -32
  36. package/include/node/v8-exception.h +2 -0
  37. package/include/node/v8-function-callback.h +4 -33
  38. package/include/node/v8-function.h +7 -0
  39. package/include/node/v8-handle-base.h +18 -0
  40. package/include/node/v8-initialization.h +9 -1
  41. package/include/node/v8-internal.h +477 -399
  42. package/include/node/v8-isolate.h +218 -151
  43. package/include/node/v8-local-handle.h +56 -28
  44. package/include/node/v8-maybe.h +2 -1
  45. package/include/node/v8-memory-span.h +149 -24
  46. package/include/node/v8-message.h +9 -1
  47. package/include/node/v8-object.h +7 -2
  48. package/include/node/v8-persistent-handle.h +17 -17
  49. package/include/node/v8-platform.h +48 -13
  50. package/include/node/v8-primitive.h +131 -6
  51. package/include/node/v8-profiler.h +13 -1
  52. package/include/node/v8-proxy.h +0 -1
  53. package/include/node/v8-regexp.h +0 -1
  54. package/include/node/v8-sandbox.h +3 -3
  55. package/include/node/v8-script.h +21 -3
  56. package/include/node/v8-source-location.h +6 -1
  57. package/include/node/v8-template.h +8 -2
  58. package/include/node/v8-traced-handle.h +16 -17
  59. package/include/node/v8-typed-array.h +6 -10
  60. package/include/node/v8-value.h +18 -0
  61. package/include/node/v8-version.h +4 -4
  62. package/include/node/v8-wasm.h +24 -0
  63. package/include/node/v8-weak-callback-info.h +20 -12
  64. package/include/node/v8.h +3 -3
  65. package/include/node/v8config.h +34 -40
  66. package/package.json +1 -1
  67. package/share/doc/node/gdbinit +94 -30
  68. package/share/doc/node/lldb_commands.py +107 -13
  69. package/share/man/man1/node.1 +4 -1
  70. package/include/node/cppgc/ephemeron-pair.h +0 -30
@@ -28,13 +28,19 @@ class WeakMemberTag;
28
28
  class UntracedMemberTag;
29
29
 
30
30
  struct DijkstraWriteBarrierPolicy {
31
- V8_INLINE static void InitializingBarrier(const void*, const void*) {
32
31
  // Since in initializing writes the source object is always white, having no
33
32
  // barrier doesn't break the tri-color invariant.
34
- }
33
+ V8_INLINE static void InitializingBarrier(const void*, const void*) {}
34
+ V8_INLINE static void InitializingBarrier(const void*, RawPointer storage) {
35
+ }
36
+ #if defined(CPPGC_POINTER_COMPRESSION)
37
+ V8_INLINE static void InitializingBarrier(const void*,
38
+ CompressedPointer storage) {}
39
+ #endif
35
40
 
36
- template <WriteBarrierSlotType SlotType>
37
- V8_INLINE static void AssigningBarrier(const void* slot, const void* value) {
41
+ template <WriteBarrierSlotType SlotType>
42
+ V8_INLINE static void AssigningBarrier(const void* slot,
43
+ const void* value) {
38
44
  #ifdef CPPGC_SLIM_WRITE_BARRIER
39
45
  if (V8_UNLIKELY(WriteBarrier::IsEnabled()))
40
46
  WriteBarrier::CombinedWriteBarrierSlow<SlotType>(slot);
@@ -44,7 +50,7 @@ struct DijkstraWriteBarrierPolicy {
44
50
  WriteBarrier::GetWriteBarrierType(slot, value, params);
45
51
  WriteBarrier(type, params, slot, value);
46
52
  #endif // !CPPGC_SLIM_WRITE_BARRIER
47
- }
53
+ }
48
54
 
49
55
  template <WriteBarrierSlotType SlotType>
50
56
  V8_INLINE static void AssigningBarrier(const void* slot, RawPointer storage) {
@@ -101,6 +107,11 @@ struct DijkstraWriteBarrierPolicy {
101
107
 
102
108
  struct NoWriteBarrierPolicy {
103
109
  V8_INLINE static void InitializingBarrier(const void*, const void*) {}
110
+ V8_INLINE static void InitializingBarrier(const void*, RawPointer storage) {}
111
+ #if defined(CPPGC_POINTER_COMPRESSION)
112
+ V8_INLINE static void InitializingBarrier(const void*,
113
+ CompressedPointer storage) {}
114
+ #endif
104
115
  template <WriteBarrierSlotType>
105
116
  V8_INLINE static void AssigningBarrier(const void*, const void*) {}
106
117
  template <WriteBarrierSlotType, typename MemberStorage>
@@ -119,10 +130,29 @@ template <bool kCheckOffHeapAssignments>
119
130
  class V8_EXPORT SameThreadEnabledCheckingPolicy
120
131
  : private SameThreadEnabledCheckingPolicyBase {
121
132
  protected:
133
+ template <typename T>
134
+ V8_INLINE void CheckPointer(RawPointer raw_pointer) {
135
+ if (raw_pointer.IsCleared() || raw_pointer.IsSentinel()) {
136
+ return;
137
+ }
138
+ CheckPointersImplTrampoline<T>::Call(
139
+ this, static_cast<const T*>(raw_pointer.Load()));
140
+ }
141
+ #if defined(CPPGC_POINTER_COMPRESSION)
142
+ template <typename T>
143
+ V8_INLINE void CheckPointer(CompressedPointer compressed_pointer) {
144
+ if (compressed_pointer.IsCleared() || compressed_pointer.IsSentinel()) {
145
+ return;
146
+ }
147
+ CheckPointersImplTrampoline<T>::Call(
148
+ this, static_cast<const T*>(compressed_pointer.Load()));
149
+ }
150
+ #endif
122
151
  template <typename T>
123
152
  void CheckPointer(const T* ptr) {
124
- if (!ptr || (kSentinelPointer == ptr)) return;
125
-
153
+ if (!ptr || (kSentinelPointer == ptr)) {
154
+ return;
155
+ }
126
156
  CheckPointersImplTrampoline<T>::Call(this, ptr);
127
157
  }
128
158
 
@@ -145,20 +175,27 @@ class V8_EXPORT SameThreadEnabledCheckingPolicy
145
175
 
146
176
  class DisabledCheckingPolicy {
147
177
  protected:
148
- V8_INLINE void CheckPointer(const void*) {}
178
+ template <typename T>
179
+ V8_INLINE void CheckPointer(T*) {}
180
+ template <typename T>
181
+ V8_INLINE void CheckPointer(RawPointer) {}
182
+ #if defined(CPPGC_POINTER_COMPRESSION)
183
+ template <typename T>
184
+ V8_INLINE void CheckPointer(CompressedPointer) {}
185
+ #endif
149
186
  };
150
187
 
151
- #ifdef DEBUG
188
+ #ifdef CPPGC_ENABLE_SLOW_API_CHECKS
152
189
  // Off heap members are not connected to object graph and thus cannot ressurect
153
190
  // dead objects.
154
191
  using DefaultMemberCheckingPolicy =
155
192
  SameThreadEnabledCheckingPolicy<false /* kCheckOffHeapAssignments*/>;
156
193
  using DefaultPersistentCheckingPolicy =
157
194
  SameThreadEnabledCheckingPolicy<true /* kCheckOffHeapAssignments*/>;
158
- #else // !DEBUG
195
+ #else // !CPPGC_ENABLE_SLOW_API_CHECKS
159
196
  using DefaultMemberCheckingPolicy = DisabledCheckingPolicy;
160
197
  using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
161
- #endif // !DEBUG
198
+ #endif // !CPPGC_ENABLE_SLOW_API_CHECKS
162
199
  // For CT(W)P neither marking information (for value), nor objectstart bitmap
163
200
  // (for slot) are guaranteed to be present because there's no synchronization
164
201
  // between heaps after marking.
@@ -11,10 +11,18 @@
11
11
 
12
12
  namespace cppgc {
13
13
 
14
+ #define CPPGC_DISALLOW_NEW() \
15
+ public: \
16
+ using IsDisallowNewMarker CPPGC_UNUSED = int; \
17
+ void* operator new(size_t, void* location) { return location; } \
18
+ void* operator new(size_t) = delete; \
19
+ static_assert(true, "Force semicolon.")
20
+
14
21
  // Use CPPGC_STACK_ALLOCATED if the object is only stack allocated.
15
22
  // Add the CPPGC_STACK_ALLOCATED_IGNORE annotation on a case-by-case basis when
16
23
  // enforcement of CPPGC_STACK_ALLOCATED should be suppressed.
17
24
  #if defined(__clang__)
25
+
18
26
  #define CPPGC_STACK_ALLOCATED() \
19
27
  public: \
20
28
  using IsStackAllocatedTypeMarker CPPGC_UNUSED = int; \
@@ -23,13 +31,26 @@ namespace cppgc {
23
31
  void* operator new(size_t) = delete; \
24
32
  void* operator new(size_t, void*) = delete; \
25
33
  static_assert(true, "Force semicolon.")
34
+
26
35
  #define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason) \
27
36
  __attribute__((annotate("stack_allocated_ignore")))
37
+
38
+ #define CPPGC_PLUGIN_IGNORE(bug_or_reason) \
39
+ __attribute__((annotate("blink_gc_plugin_ignore"), \
40
+ annotate("stack_allocated_ignore")))
41
+
28
42
  #else // !defined(__clang__)
43
+
29
44
  #define CPPGC_STACK_ALLOCATED() static_assert(true, "Force semicolon.")
30
45
  #define CPPGC_STACK_ALLOCATED_IGNORE(bug_or_reason)
46
+ #define CPPGC_PLUGIN_IGNORE(bug_or_reason)
47
+
31
48
  #endif // !defined(__clang__)
32
49
 
50
+ template <typename T>
51
+ concept IsStackAllocatedType =
52
+ requires { typename T::IsStackAllocatedTypeMarker; };
53
+
33
54
  } // namespace cppgc
34
55
 
35
56
  #endif // INCLUDE_CPPGC_MACROS_H_
@@ -38,9 +38,8 @@ class V8_TRIVIAL_ABI MemberBase {
38
38
 
39
39
  V8_INLINE MemberBase() = default;
40
40
  V8_INLINE explicit MemberBase(const void* value) : raw_(value) {}
41
- V8_INLINE MemberBase(const void* value, AtomicInitializerTag) {
42
- SetRawAtomic(value);
43
- }
41
+ V8_INLINE MemberBase(const void* value, AtomicInitializerTag)
42
+ : raw_(value, typename RawStorage::AtomicInitializerTag{}) {}
44
43
 
45
44
  V8_INLINE explicit MemberBase(RawStorage raw) : raw_(raw) {}
46
45
  V8_INLINE explicit MemberBase(std::nullptr_t) : raw_(nullptr) {}
@@ -87,7 +86,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
87
86
  V8_INLINE BasicMember(SentinelPointer s) : Base(s) {} // NOLINT
88
87
  V8_INLINE BasicMember(T* raw) : Base(raw) { // NOLINT
89
88
  InitializingWriteBarrier(raw);
90
- this->CheckPointer(Get());
89
+ CheckPointer(raw);
91
90
  }
92
91
  V8_INLINE BasicMember(T& raw) // NOLINT
93
92
  : BasicMember(&raw) {}
@@ -103,7 +102,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
103
102
  V8_INLINE BasicMember(T* raw, AtomicInitializerTag atomic)
104
103
  : Base(raw, atomic) {
105
104
  InitializingWriteBarrier(raw);
106
- this->CheckPointer(Get());
105
+ CheckPointer(raw);
107
106
  }
108
107
  V8_INLINE BasicMember(T& raw, AtomicInitializerTag atomic)
109
108
  : BasicMember(&raw, atomic) {}
@@ -117,7 +116,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
117
116
  // need to be adjusted.
118
117
  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
119
118
  typename OtherCheckingPolicy,
120
- std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
119
+ std::enable_if_t<IsDecayedSameV<T, U>>* = nullptr>
121
120
  V8_INLINE BasicMember( // NOLINT
122
121
  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
123
122
  OtherCheckingPolicy, StorageType>& other)
@@ -125,7 +124,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
125
124
 
126
125
  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
127
126
  typename OtherCheckingPolicy,
128
- std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
127
+ std::enable_if_t<IsStrictlyBaseOfV<T, U>>* = nullptr>
129
128
  V8_INLINE BasicMember( // NOLINT
130
129
  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
131
130
  OtherCheckingPolicy, StorageType>& other)
@@ -142,7 +141,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
142
141
  // need to be adjusted.
143
142
  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
144
143
  typename OtherCheckingPolicy,
145
- std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
144
+ std::enable_if_t<IsDecayedSameV<T, U>>* = nullptr>
146
145
  V8_INLINE BasicMember(
147
146
  BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
148
147
  StorageType>&& other) noexcept
@@ -152,7 +151,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
152
151
 
153
152
  template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
154
153
  typename OtherCheckingPolicy,
155
- std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
154
+ std::enable_if_t<IsStrictlyBaseOfV<T, U>>* = nullptr>
156
155
  V8_INLINE BasicMember(
157
156
  BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
158
157
  StorageType>&& other) noexcept
@@ -183,10 +182,10 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
183
182
  V8_INLINE BasicMember& operator=(
184
183
  const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
185
184
  OtherCheckingPolicy, StorageType>& other) {
186
- if constexpr (internal::IsDecayedSameV<T, U>) {
185
+ if constexpr (IsDecayedSameV<T, U>) {
187
186
  return operator=(other.GetRawStorage());
188
187
  } else {
189
- static_assert(internal::IsStrictlyBaseOfV<T, U>);
188
+ static_assert(IsStrictlyBaseOfV<T, U>);
190
189
  return operator=(other.Get());
191
190
  }
192
191
  }
@@ -206,10 +205,10 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
206
205
  V8_INLINE BasicMember& operator=(
207
206
  BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
208
207
  StorageType>&& other) noexcept {
209
- if constexpr (internal::IsDecayedSameV<T, U>) {
208
+ if constexpr (IsDecayedSameV<T, U>) {
210
209
  operator=(other.GetRawStorage());
211
210
  } else {
212
- static_assert(internal::IsStrictlyBaseOfV<T, U>);
211
+ static_assert(IsStrictlyBaseOfV<T, U>);
213
212
  operator=(other.Get());
214
213
  }
215
214
  other.Clear();
@@ -231,7 +230,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
231
230
  V8_INLINE BasicMember& operator=(T* other) {
232
231
  Base::SetRawAtomic(other);
233
232
  AssigningWriteBarrier(other);
234
- this->CheckPointer(Get());
233
+ CheckPointer(other);
235
234
  return *this;
236
235
  }
237
236
 
@@ -270,9 +269,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
270
269
  return static_cast<T*>(const_cast<void*>(Base::GetRaw()));
271
270
  }
272
271
 
273
- V8_INLINE void Clear() {
274
- Base::SetRawStorageAtomic(RawStorage{});
275
- }
272
+ V8_INLINE void Clear() { Base::SetRawStorageAtomic(RawStorage{}); }
276
273
 
277
274
  V8_INLINE T* Release() {
278
275
  T* result = Get();
@@ -284,20 +281,18 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
284
281
  return reinterpret_cast<const T**>(Base::GetRawSlot());
285
282
  }
286
283
 
287
- V8_INLINE RawStorage GetRawStorage() const {
288
- return Base::GetRawStorage();
289
- }
284
+ V8_INLINE RawStorage GetRawStorage() const { return Base::GetRawStorage(); }
290
285
 
291
286
  private:
292
287
  V8_INLINE explicit BasicMember(RawStorage raw) : Base(raw) {
293
- InitializingWriteBarrier(Get());
294
- this->CheckPointer(Get());
288
+ InitializingWriteBarrier();
289
+ CheckPointer();
295
290
  }
296
291
 
297
292
  V8_INLINE BasicMember& operator=(RawStorage other) {
298
293
  Base::SetRawStorageAtomic(other);
299
294
  AssigningWriteBarrier();
300
- this->CheckPointer(Get());
295
+ CheckPointer();
301
296
  return *this;
302
297
  }
303
298
 
@@ -308,6 +303,10 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
308
303
  V8_INLINE void InitializingWriteBarrier(T* value) const {
309
304
  WriteBarrierPolicy::InitializingBarrier(Base::GetRawSlot(), value);
310
305
  }
306
+ V8_INLINE void InitializingWriteBarrier() const {
307
+ WriteBarrierPolicy::InitializingBarrier(Base::GetRawSlot(),
308
+ Base::GetRawStorage());
309
+ }
311
310
  V8_INLINE void AssigningWriteBarrier(T* value) const {
312
311
  WriteBarrierPolicy::template AssigningBarrier<
313
312
  StorageType::kWriteBarrierSlotType>(Base::GetRawSlot(), value);
@@ -317,6 +316,12 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
317
316
  StorageType::kWriteBarrierSlotType>(Base::GetRawSlot(),
318
317
  Base::GetRawStorage());
319
318
  }
319
+ V8_INLINE void CheckPointer(T* value) {
320
+ CheckingPolicy::template CheckPointer<T>(value);
321
+ }
322
+ V8_INLINE void CheckPointer() {
323
+ CheckingPolicy::template CheckPointer<T>(Base::GetRawStorage());
324
+ }
320
325
 
321
326
  V8_INLINE void ClearFromGC() const { Base::ClearFromGC(); }
322
327
 
@@ -341,12 +346,11 @@ V8_INLINE bool operator==(
341
346
  StorageType>& member1,
342
347
  const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
343
348
  StorageType>& member2) {
344
- if constexpr (internal::IsDecayedSameV<T1, T2>) {
349
+ if constexpr (IsDecayedSameV<T1, T2>) {
345
350
  // Check compressed pointers if types are the same.
346
351
  return member1.GetRawStorage() == member2.GetRawStorage();
347
352
  } else {
348
- static_assert(internal::IsStrictlyBaseOfV<T1, T2> ||
349
- internal::IsStrictlyBaseOfV<T2, T1>);
353
+ static_assert(IsStrictlyBaseOfV<T1, T2> || IsStrictlyBaseOfV<T2, T1>);
350
354
  // Otherwise, check decompressed pointers.
351
355
  return member1.Get() == member2.Get();
352
356
  }
@@ -372,12 +376,12 @@ V8_INLINE bool operator==(
372
376
  StorageType>& member,
373
377
  U* raw) {
374
378
  // Never allow comparison with erased pointers.
375
- static_assert(!internal::IsDecayedSameV<void, U>);
379
+ static_assert(!IsDecayedSameV<void, U>);
376
380
 
377
- if constexpr (internal::IsDecayedSameV<T, U>) {
381
+ if constexpr (IsDecayedSameV<T, U>) {
378
382
  // Check compressed pointers if types are the same.
379
383
  return member.GetRawStorage() == StorageType(raw);
380
- } else if constexpr (internal::IsStrictlyBaseOfV<T, U>) {
384
+ } else if constexpr (IsStrictlyBaseOfV<T, U>) {
381
385
  // Cast the raw pointer to T, which may adjust the pointer.
382
386
  return member.GetRawStorage() == StorageType(static_cast<T*>(raw));
383
387
  } else {
@@ -494,7 +498,7 @@ V8_INLINE bool operator<(
494
498
  const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
495
499
  StorageType>& member2) {
496
500
  static_assert(
497
- internal::IsDecayedSameV<T1, T2>,
501
+ IsDecayedSameV<T1, T2>,
498
502
  "Comparison works only for same pointer type modulo cv-qualifiers");
499
503
  return member1.GetRawStorage() < member2.GetRawStorage();
500
504
  }
@@ -509,7 +513,7 @@ V8_INLINE bool operator<=(
509
513
  const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
510
514
  StorageType>& member2) {
511
515
  static_assert(
512
- internal::IsDecayedSameV<T1, T2>,
516
+ IsDecayedSameV<T1, T2>,
513
517
  "Comparison works only for same pointer type modulo cv-qualifiers");
514
518
  return member1.GetRawStorage() <= member2.GetRawStorage();
515
519
  }
@@ -524,7 +528,7 @@ V8_INLINE bool operator>(
524
528
  const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
525
529
  StorageType>& member2) {
526
530
  static_assert(
527
- internal::IsDecayedSameV<T1, T2>,
531
+ IsDecayedSameV<T1, T2>,
528
532
  "Comparison works only for same pointer type modulo cv-qualifiers");
529
533
  return member1.GetRawStorage() > member2.GetRawStorage();
530
534
  }
@@ -539,16 +543,15 @@ V8_INLINE bool operator>=(
539
543
  const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
540
544
  StorageType>& member2) {
541
545
  static_assert(
542
- internal::IsDecayedSameV<T1, T2>,
546
+ IsDecayedSameV<T1, T2>,
543
547
  "Comparison works only for same pointer type modulo cv-qualifiers");
544
548
  return member1.GetRawStorage() >= member2.GetRawStorage();
545
549
  }
546
550
 
547
551
  template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy,
548
552
  typename StorageType>
549
- struct IsWeak<internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy,
550
- CheckingPolicy, StorageType>>
551
- : std::true_type {};
553
+ struct IsWeak<BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy,
554
+ StorageType>> : std::true_type {};
552
555
 
553
556
  } // namespace internal
554
557
 
@@ -626,4 +629,35 @@ static constexpr size_t kSizeofCompressedMember =
626
629
 
627
630
  } // namespace cppgc
628
631
 
632
+ // Mark `BasicMember<T>` and `T*` as having a common reference type of `T*` (the
633
+ // type to which both can be converted or bound). This makes them satisfy
634
+ // `std::equality_comparable`, which allows usage like the following:
635
+ // ```
636
+ // HeapVector<Member<T>> v;
637
+ // T* e;
638
+ // auto it = std::ranges::find(v, e);
639
+ // ```
640
+ // Without this, the `find()` call above would fail to compile with an error
641
+ // about being unable to invoke `std::ranges::equal_to()`.
642
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
643
+ typename CheckingPolicy, typename StorageType,
644
+ template <typename> typename TQ, template <typename> typename UQ>
645
+ struct std::basic_common_reference<
646
+ cppgc::internal::BasicMember<T, WeaknessTag, WriteBarrierPolicy,
647
+ CheckingPolicy, StorageType>,
648
+ T*, TQ, UQ> {
649
+ using type = T*;
650
+ };
651
+
652
+ template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
653
+ typename CheckingPolicy, typename StorageType,
654
+ template <typename> typename TQ, template <typename> typename UQ>
655
+ struct std::basic_common_reference<
656
+ T*,
657
+ cppgc::internal::BasicMember<T, WeaknessTag, WriteBarrierPolicy,
658
+ CheckingPolicy, StorageType>,
659
+ TQ, UQ> {
660
+ using type = T*;
661
+ };
662
+
629
663
  #endif // INCLUDE_CPPGC_MEMBER_H_
@@ -55,6 +55,9 @@ class V8_EXPORT NameProvider {
55
55
  * Specifies a name for the garbage-collected object. Such names will never
56
56
  * be hidden, as they are explicitly specified by the user of this API.
57
57
  *
58
+ * Implementations of this function must not allocate garbage-collected
59
+ * objects or otherwise modify the cppgc heap.
60
+ *
58
61
  * V8 may call this function while generating a heap snapshot or at other
59
62
  * times. If V8 is currently generating a heap snapshot (according to
60
63
  * HeapProfiler::IsTakingSnapshot), then the returned string must stay alive
@@ -52,6 +52,15 @@ class V8_EXPORT Platform {
52
52
  * Foreground task runner that should be used by a Heap.
53
53
  */
54
54
  virtual std::shared_ptr<TaskRunner> GetForegroundTaskRunner() {
55
+ return GetForegroundTaskRunner(TaskPriority::kUserBlocking);
56
+ }
57
+
58
+ /**
59
+ * Returns a TaskRunner with a specific |priority| which can be used to post a
60
+ * task on the foreground thread.
61
+ */
62
+ virtual std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
63
+ TaskPriority priority) {
55
64
  return nullptr;
56
65
  }
57
66
 
@@ -127,6 +136,8 @@ class V8_EXPORT Platform {
127
136
  virtual TracingController* GetTracingController();
128
137
  };
129
138
 
139
+ V8_EXPORT bool IsInitialized();
140
+
130
141
  /**
131
142
  * Process-global initialization of the garbage collector. Must be called before
132
143
  * creating a Heap.
@@ -9,6 +9,7 @@
9
9
  // against Oilpan types without including any other parts.
10
10
  #include <cstddef>
11
11
  #include <type_traits>
12
+ #include <utility>
12
13
 
13
14
  namespace cppgc {
14
15
 
@@ -8,12 +8,12 @@
8
8
  #include <type_traits>
9
9
 
10
10
  #include "cppgc/custom-space.h"
11
- #include "cppgc/ephemeron-pair.h"
12
11
  #include "cppgc/garbage-collected.h"
13
12
  #include "cppgc/internal/logging.h"
14
13
  #include "cppgc/internal/member-storage.h"
15
14
  #include "cppgc/internal/pointer-policies.h"
16
15
  #include "cppgc/liveness-broker.h"
16
+ #include "cppgc/macros.h"
17
17
  #include "cppgc/member.h"
18
18
  #include "cppgc/sentinel-pointer.h"
19
19
  #include "cppgc/source-location.h"
@@ -36,6 +36,25 @@ class VisitorFactory;
36
36
 
37
37
  using WeakCallback = void (*)(const LivenessBroker&, const void*);
38
38
 
39
+ /**
40
+ * An ephemeron pair is used to conditionally retain an object.
41
+ * The `value` will be kept alive only if the `key` is alive.
42
+ */
43
+ template <typename K, typename V>
44
+ struct EphemeronPair {
45
+ CPPGC_DISALLOW_NEW();
46
+
47
+ EphemeronPair(K* k, V* v) : key(k), value(v) {}
48
+ WeakMember<K> key;
49
+ Member<V> value;
50
+
51
+ void ClearValueIfKeyIsDead(const LivenessBroker& broker) {
52
+ if (!broker.IsHeapObjectAlive(key)) value = nullptr;
53
+ }
54
+
55
+ void Trace(Visitor* visitor) const;
56
+ };
57
+
39
58
  /**
40
59
  * Visitor passed to trace methods. All managed pointers must have called the
41
60
  * Visitor's trace method on them.
@@ -436,6 +455,11 @@ class V8_EXPORT Visitor {
436
455
  friend class internal::VisitorBase;
437
456
  };
438
457
 
458
+ template <typename K, typename V>
459
+ void EphemeronPair<K, V>::Trace(Visitor* visitor) const {
460
+ visitor->TraceEphemeron(key, value);
461
+ }
462
+
439
463
  namespace internal {
440
464
 
441
465
  class V8_EXPORT RootVisitor {
@@ -18,11 +18,11 @@
18
18
  #else // defined(_WIN32)
19
19
 
20
20
  // Setup for Linux shared library export.
21
- #ifdef BUILDING_V8_PLATFORM_SHARED
21
+ #if defined(BUILDING_V8_PLATFORM_SHARED) || USING_V8_PLATFORM_SHARED
22
22
  #define V8_PLATFORM_EXPORT __attribute__((visibility("default")))
23
23
  #else
24
24
  #define V8_PLATFORM_EXPORT
25
- #endif
25
+ #endif // defined(BUILDING_V8_PLATFORM_SHARED) || ...
26
26
 
27
27
  #endif // defined(_WIN32)
28
28
 
@@ -6,7 +6,6 @@
6
6
  #define V8_LIBPLATFORM_V8_TRACING_H_
7
7
 
8
8
  #include <atomic>
9
- #include <fstream>
10
9
  #include <memory>
11
10
  #include <unordered_set>
12
11
  #include <vector>
@@ -67,7 +67,8 @@
67
67
  #endif
68
68
 
69
69
  #ifdef _WIN32
70
- # define SIGKILL 9
70
+ #define SIGQUIT 3
71
+ #define SIGKILL 9
71
72
  #endif
72
73
 
73
74
  #include "v8.h" // NOLINT(build/include_order)
@@ -374,10 +375,6 @@ enum OptionEnvvarSettings {
374
375
  // Disallow the options to be set via the environment variable, like
375
376
  // `NODE_OPTIONS`.
376
377
  kDisallowedInEnvvar = 1,
377
- // Deprecated, use kAllowedInEnvvar instead.
378
- kAllowedInEnvironment = kAllowedInEnvvar,
379
- // Deprecated, use kDisallowedInEnvvar instead.
380
- kDisallowedInEnvironment = kDisallowedInEnvvar,
381
378
  };
382
379
 
383
380
  // Process the arguments and set up the per-process options.
@@ -450,8 +447,11 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform {
450
447
 
451
448
  // This function may only be called once per `Isolate`, and discard any
452
449
  // pending delayed tasks scheduled for that isolate.
453
- // This needs to be called right before calling `Isolate::Dispose()`.
450
+ // This needs to be called right after calling `Isolate::Dispose()`.
454
451
  virtual void UnregisterIsolate(v8::Isolate* isolate) = 0;
452
+ // This disposes, unregisters and frees up an isolate that's allocated using
453
+ // v8::Isolate::Allocate() in the correct order to prevent race conditions.
454
+ void DisposeIsolate(v8::Isolate* isolate);
455
455
 
456
456
  // The platform should call the passed function once all state associated
457
457
  // with the given isolate has been cleaned up. This can, but does not have to,
@@ -492,6 +492,21 @@ struct IsolateSettings {
492
492
  allow_wasm_code_generation_callback = nullptr;
493
493
  v8::ModifyCodeGenerationFromStringsCallback2
494
494
  modify_code_generation_from_strings_callback = nullptr;
495
+
496
+ // When the settings is passed to NewIsolate():
497
+ // - If cpp_heap is not nullptr, this CppHeap will be used to create
498
+ // the isolate and its ownership will be passed to V8.
499
+ // - If this is nullptr, Node.js will create a CppHeap that will be
500
+ // owned by V8.
501
+ //
502
+ // When the settings is passed to SetIsolateUpForNode():
503
+ // cpp_heap will be ignored. Embedders must ensure that the
504
+ // v8::Isolate has a CppHeap attached while it's still used by
505
+ // Node.js, for example using v8::CreateParams.
506
+ //
507
+ // See https://issues.chromium.org/issues/42203693. In future version
508
+ // of V8, this CppHeap will be created by V8 if not provided.
509
+ v8::CppHeap* cpp_heap = nullptr;
495
510
  };
496
511
 
497
512
  // Represents a startup snapshot blob, e.g. created by passing
@@ -546,8 +561,8 @@ class EmbedderSnapshotData {
546
561
  void ToFile(FILE* out) const;
547
562
  std::vector<char> ToBlob() const;
548
563
 
549
- // Returns whether custom snapshots can be used. Currently, this means
550
- // that V8 was configured without the shared-readonly-heap feature.
564
+ // Returns whether custom snapshots can be used. Currently, this always
565
+ // returns false since V8 enforces shared readonly-heap.
551
566
  static bool CanUseCustomSnapshotPerIsolate();
552
567
 
553
568
  EmbedderSnapshotData(const EmbedderSnapshotData&) = delete;
@@ -1127,16 +1142,37 @@ NODE_EXTERN enum encoding ParseEncoding(
1127
1142
  NODE_EXTERN void FatalException(v8::Isolate* isolate,
1128
1143
  const v8::TryCatch& try_catch);
1129
1144
 
1130
- NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
1131
- const char* buf,
1132
- size_t len,
1133
- enum encoding encoding = LATIN1);
1145
+ NODE_EXTERN v8::MaybeLocal<v8::Value> TryEncode(
1146
+ v8::Isolate* isolate,
1147
+ const char* buf,
1148
+ size_t len,
1149
+ enum encoding encoding = LATIN1);
1134
1150
 
1135
1151
  // Warning: This reverses endianness on Big Endian platforms, even though the
1136
1152
  // signature using uint16_t implies that it should not.
1137
- NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
1138
- const uint16_t* buf,
1139
- size_t len);
1153
+ NODE_EXTERN v8::MaybeLocal<v8::Value> TryEncode(v8::Isolate* isolate,
1154
+ const uint16_t* buf,
1155
+ size_t len);
1156
+
1157
+ // The original Encode(...) functions are deprecated because they do not
1158
+ // appropriately propagate exceptions and instead rely on ToLocalChecked()
1159
+ // which crashes the process if an exception occurs. We cannot just remove
1160
+ // these as it would break ABI compatibility, so we keep them around but
1161
+ // deprecate them in favor of the TryEncode(...) variations which return
1162
+ // a MaybeLocal<> and do not crash the process if an exception occurs.
1163
+ NODE_DEPRECATED(
1164
+ "Use TryEncode(...) instead",
1165
+ NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
1166
+ const char* buf,
1167
+ size_t len,
1168
+ enum encoding encoding = LATIN1));
1169
+
1170
+ // Warning: This reverses endianness on Big Endian platforms, even though the
1171
+ // signature using uint16_t implies that it should not.
1172
+ NODE_DEPRECATED("Use TryEncode(...) instead",
1173
+ NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
1174
+ const uint16_t* buf,
1175
+ size_t len));
1140
1176
 
1141
1177
  // Returns -1 if the handle was not valid for decoding
1142
1178
  NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
@@ -1386,6 +1422,12 @@ NODE_EXTERN void RequestInterrupt(Environment* env,
1386
1422
  * I/O from native code. */
1387
1423
  NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate);
1388
1424
 
1425
+ /* Returns the id of the current execution context. If the return value is
1426
+ * zero then no execution has been set. This will happen if the user handles
1427
+ * I/O from native code. */
1428
+ NODE_EXTERN async_id
1429
+ AsyncHooksGetExecutionAsyncId(v8::Local<v8::Context> context);
1430
+
1389
1431
  /* Return same value as async_hooks.triggerAsyncId(); */
1390
1432
  NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);
1391
1433
 
@@ -1529,6 +1571,7 @@ class NODE_EXTERN AsyncResource {
1529
1571
  private:
1530
1572
  Environment* env_;
1531
1573
  v8::Global<v8::Object> resource_;
1574
+ v8::Global<v8::Value> context_frame_;
1532
1575
  async_context async_context_;
1533
1576
  };
1534
1577