node-linux-s390x 20.8.1 → 21.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 (50) hide show
  1. package/CHANGELOG.md +237 -1639
  2. package/README.md +3 -3
  3. package/bin/node +0 -0
  4. package/include/node/common.gypi +3 -3
  5. package/include/node/config.gypi +5 -3
  6. package/include/node/cppgc/internal/api-constants.h +23 -4
  7. package/include/node/cppgc/internal/caged-heap-local-data.h +16 -6
  8. package/include/node/cppgc/internal/caged-heap.h +12 -5
  9. package/include/node/cppgc/internal/gc-info.h +82 -91
  10. package/include/node/cppgc/internal/member-storage.h +16 -8
  11. package/include/node/cppgc/member.h +25 -0
  12. package/include/node/cppgc/persistent.h +4 -0
  13. package/include/node/cppgc/platform.h +6 -1
  14. package/include/node/cppgc/sentinel-pointer.h +7 -0
  15. package/include/node/cppgc/source-location.h +2 -78
  16. package/include/node/cppgc/trace-trait.h +8 -0
  17. package/include/node/cppgc/visitor.h +82 -4
  18. package/include/node/js_native_api.h +11 -1
  19. package/include/node/libplatform/libplatform.h +7 -1
  20. package/include/node/node.h +2 -0
  21. package/include/node/node_api.h +8 -7
  22. package/include/node/node_version.h +8 -7
  23. package/include/node/v8-callbacks.h +52 -8
  24. package/include/node/v8-context.h +10 -13
  25. package/include/node/v8-embedder-heap.h +12 -0
  26. package/include/node/v8-function-callback.h +11 -15
  27. package/include/node/v8-function.h +6 -0
  28. package/include/node/v8-handle-base.h +185 -0
  29. package/include/node/v8-internal.h +109 -77
  30. package/include/node/v8-isolate.h +130 -89
  31. package/include/node/v8-local-handle.h +134 -89
  32. package/include/node/v8-object.h +71 -69
  33. package/include/node/v8-persistent-handle.h +65 -89
  34. package/include/node/v8-platform.h +140 -9
  35. package/include/node/v8-primitive.h +12 -8
  36. package/include/node/v8-profiler.h +16 -2
  37. package/include/node/v8-script.h +9 -7
  38. package/include/node/v8-snapshot.h +4 -1
  39. package/include/node/v8-source-location.h +92 -0
  40. package/include/node/v8-statistics.h +36 -1
  41. package/include/node/v8-traced-handle.h +37 -54
  42. package/include/node/v8-unwinder.h +1 -1
  43. package/include/node/v8-value-serializer.h +14 -0
  44. package/include/node/v8-value.h +14 -0
  45. package/include/node/v8-version.h +3 -3
  46. package/include/node/v8config.h +19 -10
  47. package/package.json +1 -1
  48. package/share/doc/node/gdbinit +60 -6
  49. package/share/doc/node/lldb_commands.py +73 -10
  50. package/share/man/man1/node.1 +12 -0
package/README.md CHANGED
@@ -174,8 +174,6 @@ For information about the governance of the Node.js project, see
174
174
  **Ruben Bridgewater** <<ruben@bridgewater.de>> (he/him)
175
175
  * [cjihrig](https://github.com/cjihrig) -
176
176
  **Colin Ihrig** <<cjihrig@gmail.com>> (he/him)
177
- * [danielleadams](https://github.com/danielleadams) -
178
- **Danielle Adams** <<adamzdanielle@gmail.com>> (she/her)
179
177
  * [GeoffreyBooth](https://github.com/geoffreybooth) -
180
178
  **Geoffrey Booth** <<webadmin@geoffreybooth.com>> (he/him)
181
179
  * [gireeshpunathil](https://github.com/gireeshpunathil) -
@@ -221,6 +219,8 @@ For information about the governance of the Node.js project, see
221
219
  **Shelley Vohr** <<shelley.vohr@gmail.com>> (she/her)
222
220
  * [danbev](https://github.com/danbev) -
223
221
  **Daniel Bevenius** <<daniel.bevenius@gmail.com>> (he/him)
222
+ * [danielleadams](https://github.com/danielleadams) -
223
+ **Danielle Adams** <<adamzdanielle@gmail.com>> (she/her)
224
224
  * [fhinkel](https://github.com/fhinkel) -
225
225
  **Franziska Hinkelmann** <<franziska.hinkelmann@gmail.com>> (she/her)
226
226
  * [gabrielschulhof](https://github.com/gabrielschulhof) -
@@ -308,7 +308,7 @@ For information about the governance of the Node.js project, see
308
308
  * [bmeck](https://github.com/bmeck) -
309
309
  **Bradley Farias** <<bradley.meck@gmail.com>>
310
310
  * [bnb](https://github.com/bnb) -
311
- **Tierney Cyren** <<hello@bnb.im>> (they/he)
311
+ **Tierney Cyren** <<hello@bnb.im>> (they/them)
312
312
  * [bnoordhuis](https://github.com/bnoordhuis) -
313
313
  **Ben Noordhuis** <<info@bnoordhuis.nl>>
314
314
  * [BridgeAR](https://github.com/BridgeAR) -
package/bin/node CHANGED
Binary file
@@ -36,7 +36,7 @@
36
36
 
37
37
  # Reset this number to 0 on major V8 upgrades.
38
38
  # Increment by one for each non-official patch applied to deps/v8.
39
- 'v8_embedder_string': '-node.16',
39
+ 'v8_embedder_string': '-node.12',
40
40
 
41
41
  ##### V8 defaults for Node.js #####
42
42
 
@@ -230,7 +230,7 @@
230
230
  ],
231
231
  },],
232
232
  ['OS == "android"', {
233
- 'cflags': [ '-fPIC' ],
233
+ 'cflags': [ '-fPIC', '-I<(android_ndk_path)/sources/android/cpufeatures' ],
234
234
  'ldflags': [ '-fPIC' ]
235
235
  }],
236
236
  ],
@@ -528,7 +528,7 @@
528
528
  'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
529
529
  'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
530
530
  'PREBINDING': 'NO', # No -Wl,-prebind
531
- 'MACOSX_DEPLOYMENT_TARGET': '10.15', # -mmacosx-version-min=10.15
531
+ 'MACOSX_DEPLOYMENT_TARGET': '11.0', # -mmacosx-version-min=11.0
532
532
  'USE_HEADERMAP': 'NO',
533
533
  'OTHER_CFLAGS': [
534
534
  '-fno-strict-aliasing',
@@ -134,12 +134,12 @@
134
134
  'lib/internal/fs/cp/cp-sync.js',
135
135
  'lib/internal/fs/cp/cp.js',
136
136
  'lib/internal/fs/dir.js',
137
+ 'lib/internal/fs/glob.js',
137
138
  'lib/internal/fs/promises.js',
138
139
  'lib/internal/fs/read/context.js',
139
140
  'lib/internal/fs/recursive_watch.js',
140
141
  'lib/internal/fs/rimraf.js',
141
142
  'lib/internal/fs/streams.js',
142
- 'lib/internal/fs/sync.js',
143
143
  'lib/internal/fs/sync_write_stream.js',
144
144
  'lib/internal/fs/utils.js',
145
145
  'lib/internal/fs/watchers.js',
@@ -190,6 +190,7 @@
190
190
  'lib/internal/modules/helpers.js',
191
191
  'lib/internal/modules/package_json_reader.js',
192
192
  'lib/internal/modules/run_main.js',
193
+ 'lib/internal/navigator.js',
193
194
  'lib/internal/net.js',
194
195
  'lib/internal/options.js',
195
196
  'lib/internal/per_context/domexception.js',
@@ -344,7 +345,7 @@
344
345
  'lib/wasi.js',
345
346
  'lib/worker_threads.js',
346
347
  'lib/zlib.js'],
347
- 'node_module_version': 115,
348
+ 'node_module_version': 120,
348
349
  'node_no_browser_globals': 'false',
349
350
  'node_prefix': '/',
350
351
  'node_release_urlbase': 'https://nodejs.org/download/release/',
@@ -372,10 +373,11 @@
372
373
  'openssl_is_fips': 'false',
373
374
  'openssl_quic': 'true',
374
375
  'ossfuzz': 'false',
375
- 'shlib_suffix': 'so.115',
376
+ 'shlib_suffix': 'so.120',
376
377
  'single_executable_application': 'true',
377
378
  'target_arch': 's390x',
378
379
  'v8_enable_31bit_smis_on_64bit_arch': 0,
380
+ 'v8_enable_extensible_ro_snapshot': 0,
379
381
  'v8_enable_gdbjit': 0,
380
382
  'v8_enable_hugepage': 0,
381
383
  'v8_enable_i18n_support': 1,
@@ -40,13 +40,32 @@ constexpr size_t kGuardPageSize = 4096;
40
40
 
41
41
  static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2;
42
42
 
43
+ #if defined(CPPGC_POINTER_COMPRESSION)
44
+ #if defined(CPPGC_ENABLE_LARGER_CAGE)
45
+ constexpr unsigned kPointerCompressionShift = 3;
46
+ #else // !defined(CPPGC_ENABLE_LARGER_CAGE)
47
+ constexpr unsigned kPointerCompressionShift = 1;
48
+ #endif // !defined(CPPGC_ENABLE_LARGER_CAGE)
49
+ #endif // !defined(CPPGC_POINTER_COMPRESSION)
50
+
43
51
  #if defined(CPPGC_CAGED_HEAP)
44
52
  #if defined(CPPGC_2GB_CAGE)
45
- constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(2) * kGB;
46
- #else // !defined(CPPGC_2GB_CAGE)
47
- constexpr size_t kCagedHeapReservationSize = static_cast<size_t>(4) * kGB;
53
+ constexpr size_t kCagedHeapDefaultReservationSize =
54
+ static_cast<size_t>(2) * kGB;
55
+ constexpr size_t kCagedHeapMaxReservationSize =
56
+ kCagedHeapDefaultReservationSize;
57
+ #else // !defined(CPPGC_2GB_CAGE)
58
+ constexpr size_t kCagedHeapDefaultReservationSize =
59
+ static_cast<size_t>(4) * kGB;
60
+ #if defined(CPPGC_POINTER_COMPRESSION)
61
+ constexpr size_t kCagedHeapMaxReservationSize =
62
+ size_t{1} << (31 + kPointerCompressionShift);
63
+ #else // !defined(CPPGC_POINTER_COMPRESSION)
64
+ constexpr size_t kCagedHeapMaxReservationSize =
65
+ kCagedHeapDefaultReservationSize;
66
+ #endif // !defined(CPPGC_POINTER_COMPRESSION)
48
67
  #endif // !defined(CPPGC_2GB_CAGE)
49
- constexpr size_t kCagedHeapReservationAlignment = kCagedHeapReservationSize;
68
+ constexpr size_t kCagedHeapReservationAlignment = kCagedHeapMaxReservationSize;
50
69
  #endif // defined(CPPGC_CAGED_HEAP)
51
70
 
52
71
  static constexpr size_t kDefaultAlignment = sizeof(void*);
@@ -46,7 +46,11 @@ class V8_EXPORT AgeTable final {
46
46
  enum class AdjacentCardsPolicy : uint8_t { kConsider, kIgnore };
47
47
 
48
48
  static constexpr size_t kCardSizeInBytes =
49
- api_constants::kCagedHeapReservationSize / kRequiredSize;
49
+ api_constants::kCagedHeapDefaultReservationSize / kRequiredSize;
50
+
51
+ static constexpr size_t CalculateAgeTableSizeForHeapSize(size_t heap_size) {
52
+ return heap_size / kCardSizeInBytes;
53
+ }
50
54
 
51
55
  void SetAge(uintptr_t cage_offset, Age age) {
52
56
  table_[card(cage_offset)] = age;
@@ -81,16 +85,18 @@ class V8_EXPORT AgeTable final {
81
85
  #endif // !V8_HAS_BUILTIN_CTZ
82
86
  static_assert((1 << kGranularityBits) == kCardSizeInBytes);
83
87
  const size_t entry = offset >> kGranularityBits;
84
- CPPGC_DCHECK(table_.size() > entry);
88
+ CPPGC_DCHECK(CagedHeapBase::GetAgeTableSize() > entry);
85
89
  return entry;
86
90
  }
87
91
 
88
- std::array<Age, kRequiredSize> table_;
92
+ #if defined(V8_CC_GNU)
93
+ // gcc disallows flexible arrays in otherwise empty classes.
94
+ Age table_[0];
95
+ #else // !defined(V8_CC_GNU)
96
+ Age table_[];
97
+ #endif // !defined(V8_CC_GNU)
89
98
  };
90
99
 
91
- static_assert(sizeof(AgeTable) == 1 * api_constants::kMB,
92
- "Size of AgeTable is 1MB");
93
-
94
100
  #endif // CPPGC_YOUNG_GENERATION
95
101
 
96
102
  struct CagedHeapLocalData final {
@@ -98,6 +104,10 @@ struct CagedHeapLocalData final {
98
104
  return *reinterpret_cast<CagedHeapLocalData*>(CagedHeapBase::GetBase());
99
105
  }
100
106
 
107
+ static constexpr size_t CalculateLocalDataSizeForHeapSize(size_t heap_size) {
108
+ return AgeTable::CalculateAgeTableSizeForHeapSize(heap_size);
109
+ }
110
+
101
111
  #if defined(CPPGC_YOUNG_GENERATION)
102
112
  AgeTable age_table;
103
113
  #endif
@@ -33,24 +33,31 @@ class V8_EXPORT CagedHeapBase {
33
33
 
34
34
  V8_INLINE static bool AreWithinCage(const void* addr1, const void* addr2) {
35
35
  #if defined(CPPGC_2GB_CAGE)
36
- static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT - 1;
36
+ static constexpr size_t kHeapBaseShift = sizeof(uint32_t) * CHAR_BIT - 1;
37
37
  #else //! defined(CPPGC_2GB_CAGE)
38
- static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT;
38
+ #if defined(CPPGC_POINTER_COMPRESSION)
39
+ static constexpr size_t kHeapBaseShift =
40
+ 31 + api_constants::kPointerCompressionShift;
41
+ #else // !defined(CPPGC_POINTER_COMPRESSION)
42
+ static constexpr size_t kHeapBaseShift = sizeof(uint32_t) * CHAR_BIT;
43
+ #endif // !defined(CPPGC_POINTER_COMPRESSION)
39
44
  #endif //! defined(CPPGC_2GB_CAGE)
40
- static_assert((static_cast<size_t>(1) << kHalfWordShift) ==
41
- api_constants::kCagedHeapReservationSize);
45
+ static_assert((static_cast<size_t>(1) << kHeapBaseShift) ==
46
+ api_constants::kCagedHeapMaxReservationSize);
42
47
  CPPGC_DCHECK(g_heap_base_);
43
48
  return !(((reinterpret_cast<uintptr_t>(addr1) ^ g_heap_base_) |
44
49
  (reinterpret_cast<uintptr_t>(addr2) ^ g_heap_base_)) >>
45
- kHalfWordShift);
50
+ kHeapBaseShift);
46
51
  }
47
52
 
48
53
  V8_INLINE static uintptr_t GetBase() { return g_heap_base_; }
54
+ V8_INLINE static size_t GetAgeTableSize() { return g_age_table_size_; }
49
55
 
50
56
  private:
51
57
  friend class CagedHeap;
52
58
 
53
59
  static uintptr_t g_heap_base_;
60
+ static size_t g_age_table_size_;
54
61
  };
55
62
 
56
63
  } // namespace internal
@@ -24,89 +24,90 @@ struct V8_EXPORT EnsureGCInfoIndexTrait final {
24
24
  // Acquires a new GC info object and updates `registered_index` with the index
25
25
  // that identifies that new info accordingly.
26
26
  template <typename T>
27
- V8_INLINE static void EnsureIndex(
27
+ V8_INLINE static GCInfoIndex EnsureIndex(
28
28
  std::atomic<GCInfoIndex>& registered_index) {
29
- EnsureGCInfoIndexTraitDispatch<T>{}(registered_index);
29
+ return EnsureGCInfoIndexTraitDispatch<T>{}(registered_index);
30
30
  }
31
31
 
32
32
  private:
33
- template <typename T, bool = std::is_polymorphic<T>::value,
34
- bool = FinalizerTrait<T>::HasFinalizer(),
33
+ template <typename T, bool = FinalizerTrait<T>::HasFinalizer(),
35
34
  bool = NameTrait<T>::HasNonHiddenName()>
36
35
  struct EnsureGCInfoIndexTraitDispatch;
37
36
 
38
- static void V8_PRESERVE_MOST
39
- EnsureGCInfoIndexPolymorphic(std::atomic<GCInfoIndex>&, TraceCallback,
40
- FinalizationCallback, NameCallback);
41
- static void V8_PRESERVE_MOST EnsureGCInfoIndexPolymorphic(
37
+ static GCInfoIndex V8_PRESERVE_MOST
38
+ EnsureGCInfoIndex(std::atomic<GCInfoIndex>&, TraceCallback,
39
+ FinalizationCallback, NameCallback);
40
+ static GCInfoIndex V8_PRESERVE_MOST EnsureGCInfoIndex(
42
41
  std::atomic<GCInfoIndex>&, TraceCallback, FinalizationCallback);
43
- static void V8_PRESERVE_MOST EnsureGCInfoIndexPolymorphic(
44
- std::atomic<GCInfoIndex>&, TraceCallback, NameCallback);
45
- static void V8_PRESERVE_MOST
46
- EnsureGCInfoIndexPolymorphic(std::atomic<GCInfoIndex>&, TraceCallback);
47
- static void V8_PRESERVE_MOST
48
- EnsureGCInfoIndexNonPolymorphic(std::atomic<GCInfoIndex>&, TraceCallback,
49
- FinalizationCallback, NameCallback);
50
- static void V8_PRESERVE_MOST EnsureGCInfoIndexNonPolymorphic(
51
- std::atomic<GCInfoIndex>&, TraceCallback, FinalizationCallback);
52
- static void V8_PRESERVE_MOST EnsureGCInfoIndexNonPolymorphic(
53
- std::atomic<GCInfoIndex>&, TraceCallback, NameCallback);
54
- static void V8_PRESERVE_MOST
55
- EnsureGCInfoIndexNonPolymorphic(std::atomic<GCInfoIndex>&, TraceCallback);
42
+ static GCInfoIndex V8_PRESERVE_MOST
43
+ EnsureGCInfoIndex(std::atomic<GCInfoIndex>&, TraceCallback, NameCallback);
44
+ static GCInfoIndex V8_PRESERVE_MOST
45
+ EnsureGCInfoIndex(std::atomic<GCInfoIndex>&, TraceCallback);
56
46
  };
57
47
 
58
- #define DISPATCH(is_polymorphic, has_finalizer, has_non_hidden_name, function) \
59
- template <typename T> \
60
- struct EnsureGCInfoIndexTrait::EnsureGCInfoIndexTraitDispatch< \
61
- T, is_polymorphic, has_finalizer, has_non_hidden_name> { \
62
- V8_INLINE void operator()(std::atomic<GCInfoIndex>& registered_index) { \
63
- function; \
64
- } \
48
+ #define DISPATCH(has_finalizer, has_non_hidden_name, function) \
49
+ template <typename T> \
50
+ struct EnsureGCInfoIndexTrait::EnsureGCInfoIndexTraitDispatch< \
51
+ T, has_finalizer, has_non_hidden_name> { \
52
+ V8_INLINE GCInfoIndex \
53
+ operator()(std::atomic<GCInfoIndex>& registered_index) { \
54
+ return function; \
55
+ } \
65
56
  };
66
57
 
67
- // --------------------------------------------------------------------- //
68
- // DISPATCH(is_polymorphic, has_finalizer, has_non_hidden_name, function)
69
- // --------------------------------------------------------------------- //
70
- DISPATCH(true, true, true, //
71
- EnsureGCInfoIndexPolymorphic(registered_index, //
72
- TraceTrait<T>::Trace, //
73
- FinalizerTrait<T>::kCallback, //
74
- NameTrait<T>::GetName)) //
75
- DISPATCH(true, true, false, //
76
- EnsureGCInfoIndexPolymorphic(registered_index, //
77
- TraceTrait<T>::Trace, //
78
- FinalizerTrait<T>::kCallback)) //
79
- DISPATCH(true, false, true, //
80
- EnsureGCInfoIndexPolymorphic(registered_index, //
81
- TraceTrait<T>::Trace, //
82
- NameTrait<T>::GetName)) //
83
- DISPATCH(true, false, false, //
84
- EnsureGCInfoIndexPolymorphic(registered_index, //
85
- TraceTrait<T>::Trace)) //
86
- DISPATCH(false, true, true, //
87
- EnsureGCInfoIndexNonPolymorphic(registered_index, //
88
- TraceTrait<T>::Trace, //
89
- FinalizerTrait<T>::kCallback, //
90
- NameTrait<T>::GetName)) //
91
- DISPATCH(false, true, false, //
92
- EnsureGCInfoIndexNonPolymorphic(registered_index, //
93
- TraceTrait<T>::Trace, //
94
- FinalizerTrait<T>::kCallback)) //
95
- DISPATCH(false, false, true, //
96
- EnsureGCInfoIndexNonPolymorphic(registered_index, //
97
- TraceTrait<T>::Trace, //
98
- NameTrait<T>::GetName)) //
99
- DISPATCH(false, false, false, //
100
- EnsureGCInfoIndexNonPolymorphic(registered_index, //
101
- TraceTrait<T>::Trace)) //
58
+ // ------------------------------------------------------- //
59
+ // DISPATCH(has_finalizer, has_non_hidden_name, function) //
60
+ // ------------------------------------------------------- //
61
+ DISPATCH(true, true, //
62
+ EnsureGCInfoIndex(registered_index, //
63
+ TraceTrait<T>::Trace, //
64
+ FinalizerTrait<T>::kCallback, //
65
+ NameTrait<T>::GetName)) //
66
+ DISPATCH(true, false, //
67
+ EnsureGCInfoIndex(registered_index, //
68
+ TraceTrait<T>::Trace, //
69
+ FinalizerTrait<T>::kCallback)) //
70
+ DISPATCH(false, true, //
71
+ EnsureGCInfoIndex(registered_index, //
72
+ TraceTrait<T>::Trace, //
73
+ NameTrait<T>::GetName)) //
74
+ DISPATCH(false, false, //
75
+ EnsureGCInfoIndex(registered_index, //
76
+ TraceTrait<T>::Trace)) //
102
77
 
103
78
  #undef DISPATCH
104
79
 
80
+ // Trait determines how the garbage collector treats objects wrt. to traversing,
81
+ // finalization, and naming.
82
+ template <typename T>
83
+ struct GCInfoTrait final {
84
+ V8_INLINE static GCInfoIndex Index() {
85
+ static_assert(sizeof(T), "T must be fully defined");
86
+ static std::atomic<GCInfoIndex>
87
+ registered_index; // Uses zero initialization.
88
+ GCInfoIndex index = registered_index.load(std::memory_order_acquire);
89
+ if (V8_UNLIKELY(!index)) {
90
+ index = EnsureGCInfoIndexTrait::EnsureIndex<T>(registered_index);
91
+ CPPGC_DCHECK(index != 0);
92
+ CPPGC_DCHECK(index == registered_index.load(std::memory_order_acquire));
93
+ }
94
+ return index;
95
+ }
96
+
97
+ static constexpr bool CheckCallbacksAreDefined() {
98
+ // No USE() macro available.
99
+ (void)static_cast<TraceCallback>(TraceTrait<T>::Trace);
100
+ (void)static_cast<FinalizationCallback>(FinalizerTrait<T>::kCallback);
101
+ (void)static_cast<NameCallback>(NameTrait<T>::GetName);
102
+ return true;
103
+ }
104
+ };
105
+
105
106
  // Fold types based on finalizer behavior. Note that finalizer characteristics
106
107
  // align with trace behavior, i.e., destructors are virtual when trace methods
107
108
  // are and vice versa.
108
109
  template <typename T, typename ParentMostGarbageCollectedType>
109
- struct GCInfoFolding {
110
+ struct GCInfoFolding final {
110
111
  static constexpr bool kHasVirtualDestructorAtBase =
111
112
  std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
112
113
  static constexpr bool kBothTypesAreTriviallyDestructible =
@@ -121,34 +122,24 @@ struct GCInfoFolding {
121
122
  static constexpr bool kWantsDetailedObjectNames = false;
122
123
  #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
123
124
 
124
- // Folding would regresses name resolution when deriving names from C++
125
- // class names as it would just folds a name to the base class name.
126
- using ResultType = std::conditional_t<(kHasVirtualDestructorAtBase ||
127
- kBothTypesAreTriviallyDestructible ||
128
- kHasCustomFinalizerDispatchAtBase) &&
129
- !kWantsDetailedObjectNames,
130
- ParentMostGarbageCollectedType, T>;
131
- };
125
+ // Always true. Forces the compiler to resolve callbacks which ensures that
126
+ // both modes don't break without requiring compiling a separate
127
+ // configuration. Only a single GCInfo (for `ResultType` below) will actually
128
+ // be instantiated but existence (and well-formedness) of all callbacks is
129
+ // checked.
130
+ static constexpr bool kCheckTypeGuardAlwaysTrue =
131
+ GCInfoTrait<T>::CheckCallbacksAreDefined() &&
132
+ GCInfoTrait<ParentMostGarbageCollectedType>::CheckCallbacksAreDefined();
132
133
 
133
- // Trait determines how the garbage collector treats objects wrt. to traversing,
134
- // finalization, and naming.
135
- template <typename T>
136
- struct GCInfoTrait final {
137
- V8_INLINE static GCInfoIndex Index() {
138
- static_assert(sizeof(T), "T must be fully defined");
139
- static std::atomic<GCInfoIndex>
140
- registered_index; // Uses zero initialization.
141
- GCInfoIndex index = registered_index.load(std::memory_order_acquire);
142
- if (V8_UNLIKELY(!index)) {
143
- EnsureGCInfoIndexTrait::EnsureIndex<T>(registered_index);
144
- // Slow path call uses V8_PRESERVE_MOST which does not support return
145
- // values (also preserves RAX). Avoid out parameter by just reloading the
146
- // value here which at this point is guaranteed to be set.
147
- index = registered_index.load(std::memory_order_acquire);
148
- CPPGC_DCHECK(index != 0);
149
- }
150
- return index;
151
- }
134
+ // Folding would regress name resolution when deriving names from C++
135
+ // class names as it would just folds a name to the base class name.
136
+ using ResultType =
137
+ std::conditional_t<kCheckTypeGuardAlwaysTrue &&
138
+ (kHasVirtualDestructorAtBase ||
139
+ kBothTypesAreTriviallyDestructible ||
140
+ kHasCustomFinalizerDispatchAtBase) &&
141
+ !kWantsDetailedObjectNames,
142
+ ParentMostGarbageCollectedType, T>;
152
143
  };
153
144
 
154
145
  } // namespace internal
@@ -122,17 +122,22 @@ class V8_TRIVIAL_ABI CompressedPointer final {
122
122
  }
123
123
 
124
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");
125
+ static_assert(SentinelPointer::kSentinelValue ==
126
+ 1 << api_constants::kPointerCompressionShift,
127
+ "The compression scheme relies on the sentinel encoded as 1 "
128
+ "<< kPointerCompressionShift");
128
129
  static constexpr size_t kGigaCageMask =
129
130
  ~(api_constants::kCagedHeapReservationAlignment - 1);
131
+ static constexpr size_t kPointerCompressionShiftMask =
132
+ (1 << api_constants::kPointerCompressionShift) - 1;
130
133
 
131
134
  CPPGC_DCHECK(CageBaseGlobal::IsSet());
132
135
  const uintptr_t base = CageBaseGlobal::Get();
133
136
  CPPGC_DCHECK(!ptr || ptr == kSentinelPointer ||
134
137
  (base & kGigaCageMask) ==
135
138
  (reinterpret_cast<uintptr_t>(ptr) & kGigaCageMask));
139
+ CPPGC_DCHECK(
140
+ (reinterpret_cast<uintptr_t>(ptr) & kPointerCompressionShiftMask) == 0);
136
141
 
137
142
  #if defined(CPPGC_2GB_CAGE)
138
143
  // Truncate the pointer.
@@ -140,8 +145,9 @@ class V8_TRIVIAL_ABI CompressedPointer final {
140
145
  static_cast<IntegralType>(reinterpret_cast<uintptr_t>(ptr));
141
146
  #else // !defined(CPPGC_2GB_CAGE)
142
147
  const auto uptr = reinterpret_cast<uintptr_t>(ptr);
143
- // Shift the pointer by one and truncate.
144
- auto compressed = static_cast<IntegralType>(uptr >> 1);
148
+ // Shift the pointer and truncate.
149
+ auto compressed = static_cast<IntegralType>(
150
+ uptr >> api_constants::kPointerCompressionShift);
145
151
  #endif // !defined(CPPGC_2GB_CAGE)
146
152
  // Normal compressed pointers must have the MSB set.
147
153
  CPPGC_DCHECK((!compressed || compressed == kCompressedSentinel) ||
@@ -157,9 +163,10 @@ class V8_TRIVIAL_ABI CompressedPointer final {
157
163
  #if defined(CPPGC_2GB_CAGE)
158
164
  const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr));
159
165
  #else // !defined(CPPGC_2GB_CAGE)
160
- // Then, shift the result by one. It's important to shift the unsigned
166
+ // Then, shift the result. It's important to shift the unsigned
161
167
  // value, as otherwise it would result in undefined behavior.
162
- const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr)) << 1;
168
+ const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr))
169
+ << api_constants::kPointerCompressionShift;
163
170
  #endif // !defined(CPPGC_2GB_CAGE)
164
171
  return reinterpret_cast<void*>(mask & base);
165
172
  }
@@ -170,7 +177,8 @@ class V8_TRIVIAL_ABI CompressedPointer final {
170
177
  SentinelPointer::kSentinelValue;
171
178
  #else // !defined(CPPGC_2GB_CAGE)
172
179
  static constexpr IntegralType kCompressedSentinel =
173
- SentinelPointer::kSentinelValue >> 1;
180
+ SentinelPointer::kSentinelValue >>
181
+ api_constants::kPointerCompressionShift;
174
182
  #endif // !defined(CPPGC_2GB_CAGE)
175
183
  // All constructors initialize `value_`. Do not add a default value here as it
176
184
  // results in a non-atomic write on some builds, even when the atomic version
@@ -597,8 +597,33 @@ using UncompressedMember = internal::BasicMember<
597
597
  T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
598
598
  internal::DefaultMemberCheckingPolicy, internal::RawPointer>;
599
599
 
600
+ #if defined(CPPGC_POINTER_COMPRESSION)
601
+ /**
602
+ * CompressedMember. Default implementation of cppgc::Member on builds with
603
+ * pointer compression.
604
+ */
605
+ template <typename T>
606
+ using CompressedMember = internal::BasicMember<
607
+ T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
608
+ internal::DefaultMemberCheckingPolicy, internal::CompressedPointer>;
609
+ #endif // defined(CPPGC_POINTER_COMPRESSION)
610
+
600
611
  } // namespace subtle
601
612
 
613
+ namespace internal {
614
+
615
+ struct Dummy;
616
+
617
+ static constexpr size_t kSizeOfMember = sizeof(Member<Dummy>);
618
+ static constexpr size_t kSizeOfUncompressedMember =
619
+ sizeof(subtle::UncompressedMember<Dummy>);
620
+ #if defined(CPPGC_POINTER_COMPRESSION)
621
+ static constexpr size_t kSizeofCompressedMember =
622
+ sizeof(subtle::CompressedMember<Dummy>);
623
+ #endif // defined(CPPGC_POINTER_COMPRESSION)
624
+
625
+ } // namespace internal
626
+
602
627
  } // namespace cppgc
603
628
 
604
629
  #endif // INCLUDE_CPPGC_MEMBER_H_
@@ -92,6 +92,7 @@ class BasicPersistent final : public PersistentBase,
92
92
  template <typename U, typename OtherWeaknessPolicy,
93
93
  typename OtherLocationPolicy, typename OtherCheckingPolicy,
94
94
  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
95
+ // NOLINTNEXTLINE
95
96
  BasicPersistent(
96
97
  const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
97
98
  OtherCheckingPolicy>& other,
@@ -116,6 +117,7 @@ class BasicPersistent final : public PersistentBase,
116
117
  typename MemberWeaknessTag, typename MemberCheckingPolicy,
117
118
  typename MemberStorageType,
118
119
  typename = std::enable_if_t<std::is_base_of<T, U>::value>>
120
+ // NOLINTNEXTLINE
119
121
  BasicPersistent(const internal::BasicMember<
120
122
  U, MemberBarrierPolicy, MemberWeaknessTag,
121
123
  MemberCheckingPolicy, MemberStorageType>& member,
@@ -180,6 +182,8 @@ class BasicPersistent final : public PersistentBase,
180
182
  }
181
183
 
182
184
  explicit operator bool() const { return Get(); }
185
+ // Historically we allow implicit conversions to T*.
186
+ // NOLINTNEXTLINE
183
187
  operator T*() const { return Get(); }
184
188
  T* operator->() const { return Get(); }
185
189
  T& operator*() const { return *Get(); }
@@ -136,8 +136,13 @@ class V8_EXPORT Platform {
136
136
  * \param page_allocator The allocator used for maintaining meta data. Must stay
137
137
  * always alive and not change between multiple calls to InitializeProcess. If
138
138
  * no allocator is provided, a default internal version will be used.
139
+ * \param desired_heap_size Desired amount of virtual address space to reserve
140
+ * for the heap, in bytes. Actual size will be clamped to minimum and maximum
141
+ * values based on compile-time settings and may be rounded up. If this
142
+ * parameter is zero, a default value will be used.
139
143
  */
140
- V8_EXPORT void InitializeProcess(PageAllocator* page_allocator = nullptr);
144
+ V8_EXPORT void InitializeProcess(PageAllocator* page_allocator = nullptr,
145
+ size_t desired_heap_size = 0);
141
146
 
142
147
  /**
143
148
  * Must be called after destroying the last used heap. Some process-global
@@ -7,13 +7,20 @@
7
7
 
8
8
  #include <cstdint>
9
9
 
10
+ #include "cppgc/internal/api-constants.h"
11
+
10
12
  namespace cppgc {
11
13
  namespace internal {
12
14
 
13
15
  // Special tag type used to denote some sentinel member. The semantics of the
14
16
  // sentinel is defined by the embedder.
15
17
  struct SentinelPointer {
18
+ #if defined(CPPGC_POINTER_COMPRESSION)
19
+ static constexpr intptr_t kSentinelValue =
20
+ 1 << api_constants::kPointerCompressionShift;
21
+ #else // !defined(CPPGC_POINTER_COMPRESSION)
16
22
  static constexpr intptr_t kSentinelValue = 0b10;
23
+ #endif // !defined(CPPGC_POINTER_COMPRESSION)
17
24
  template <typename T>
18
25
  operator T*() const {
19
26
  return reinterpret_cast<T*>(kSentinelValue);