libv8-node 16.10.0.0-aarch64-linux → 18.8.0.0-aarch64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/paths.rb +5 -1
  3. data/lib/libv8/node/version.rb +3 -3
  4. data/vendor/v8/aarch64-linux/libv8/obj/libv8_monolith.a +0 -0
  5. data/vendor/v8/include/cppgc/allocation.h +100 -22
  6. data/vendor/v8/include/cppgc/cross-thread-persistent.h +114 -33
  7. data/vendor/v8/include/cppgc/default-platform.h +2 -10
  8. data/vendor/v8/include/cppgc/explicit-management.h +22 -4
  9. data/vendor/v8/include/cppgc/garbage-collected.h +15 -26
  10. data/vendor/v8/include/cppgc/heap-consistency.h +30 -0
  11. data/vendor/v8/include/cppgc/heap-state.h +12 -0
  12. data/vendor/v8/include/cppgc/heap.h +7 -2
  13. data/vendor/v8/include/cppgc/internal/api-constants.h +8 -0
  14. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +25 -14
  15. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +4 -1
  16. data/vendor/v8/include/cppgc/internal/gc-info.h +90 -10
  17. data/vendor/v8/include/cppgc/internal/logging.h +3 -3
  18. data/vendor/v8/include/cppgc/internal/name-trait.h +11 -0
  19. data/vendor/v8/include/cppgc/internal/persistent-node.h +73 -29
  20. data/vendor/v8/include/cppgc/internal/pointer-policies.h +26 -15
  21. data/vendor/v8/include/cppgc/internal/write-barrier.h +62 -23
  22. data/vendor/v8/include/cppgc/liveness-broker.h +4 -1
  23. data/vendor/v8/include/cppgc/member.h +7 -2
  24. data/vendor/v8/include/cppgc/persistent.h +38 -33
  25. data/vendor/v8/include/cppgc/platform.h +4 -1
  26. data/vendor/v8/include/cppgc/prefinalizer.h +35 -12
  27. data/vendor/v8/include/cppgc/testing.h +9 -2
  28. data/vendor/v8/include/cppgc/type-traits.h +6 -13
  29. data/vendor/v8/include/cppgc/visitor.h +9 -7
  30. data/vendor/v8/include/libplatform/libplatform.h +0 -11
  31. data/vendor/v8/include/libplatform/v8-tracing.h +0 -1
  32. data/vendor/v8/include/v8-array-buffer.h +445 -0
  33. data/vendor/v8/include/v8-callbacks.h +397 -0
  34. data/vendor/v8/include/v8-container.h +129 -0
  35. data/vendor/v8/include/v8-context.h +407 -0
  36. data/vendor/v8/include/v8-cppgc.h +21 -128
  37. data/vendor/v8/include/v8-data.h +80 -0
  38. data/vendor/v8/include/v8-date.h +43 -0
  39. data/vendor/v8/include/v8-debug.h +168 -0
  40. data/vendor/v8/include/v8-embedder-heap.h +218 -0
  41. data/vendor/v8/include/v8-embedder-state-scope.h +51 -0
  42. data/vendor/v8/include/v8-exception.h +217 -0
  43. data/vendor/v8/include/v8-extension.h +62 -0
  44. data/vendor/v8/include/v8-external.h +37 -0
  45. data/vendor/v8/include/v8-fast-api-calls.h +172 -24
  46. data/vendor/v8/include/v8-forward.h +81 -0
  47. data/vendor/v8/include/v8-function-callback.h +475 -0
  48. data/vendor/v8/include/v8-function.h +125 -0
  49. data/vendor/v8/include/v8-initialization.h +315 -0
  50. data/vendor/v8/include/v8-inspector.h +56 -28
  51. data/vendor/v8/include/v8-internal.h +217 -55
  52. data/vendor/v8/include/v8-isolate.h +1709 -0
  53. data/vendor/v8/include/v8-json.h +47 -0
  54. data/vendor/v8/include/v8-local-handle.h +455 -0
  55. data/vendor/v8/include/v8-locker.h +149 -0
  56. data/vendor/v8/include/v8-maybe.h +137 -0
  57. data/vendor/v8/include/v8-memory-span.h +43 -0
  58. data/vendor/v8/include/v8-message.h +216 -0
  59. data/vendor/v8/include/v8-metrics.h +69 -16
  60. data/vendor/v8/include/v8-microtask-queue.h +152 -0
  61. data/vendor/v8/include/v8-microtask.h +28 -0
  62. data/vendor/v8/include/v8-object.h +775 -0
  63. data/vendor/v8/include/v8-persistent-handle.h +590 -0
  64. data/vendor/v8/include/v8-platform.h +400 -17
  65. data/vendor/v8/include/v8-primitive-object.h +118 -0
  66. data/vendor/v8/include/v8-primitive.h +866 -0
  67. data/vendor/v8/include/v8-profiler.h +88 -13
  68. data/vendor/v8/include/v8-promise.h +174 -0
  69. data/vendor/v8/include/v8-proxy.h +50 -0
  70. data/vendor/v8/include/v8-regexp.h +105 -0
  71. data/vendor/v8/include/v8-script.h +747 -0
  72. data/vendor/v8/include/v8-snapshot.h +196 -0
  73. data/vendor/v8/include/v8-statistics.h +217 -0
  74. data/vendor/v8/include/v8-template.h +1079 -0
  75. data/vendor/v8/include/v8-traced-handle.h +420 -0
  76. data/vendor/v8/include/v8-typed-array.h +282 -0
  77. data/vendor/v8/include/v8-unwinder-state.h +4 -3
  78. data/vendor/v8/include/v8-unwinder.h +132 -0
  79. data/vendor/v8/include/v8-util.h +7 -1
  80. data/vendor/v8/include/v8-value-serializer-version.h +1 -1
  81. data/vendor/v8/include/v8-value-serializer.h +279 -0
  82. data/vendor/v8/include/v8-value.h +526 -0
  83. data/vendor/v8/include/v8-version.h +4 -4
  84. data/vendor/v8/include/v8-wasm.h +257 -0
  85. data/vendor/v8/include/v8-weak-callback-info.h +87 -0
  86. data/vendor/v8/include/v8.h +41 -12601
  87. data/vendor/v8/include/v8config.h +102 -12
  88. metadata +47 -5
  89. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0279ccf47c72d2103d12a6b36d8cdc283fd3473a564d62f09833459c4fc360b8'
4
- data.tar.gz: a9bf4c0d98f68d326ec09da7fd86778349d840a21f9e7253c165249fdd790dc0
3
+ metadata.gz: 9e130a26656b8d51840afa872a14335494f3a52e88cc92c010de515ff4ea3234
4
+ data.tar.gz: 9330b60f0510d401643389a331de2e45cad667e6c1ba344f7ac510d4f7c074f1
5
5
  SHA512:
6
- metadata.gz: 3ff85cf23f4426b3fb0f12d573bb01de9d61dbe156320369e14d15a6c6e4b5e497d6ddad593bfff78242aee343aa08707e653287942768170c40f77ea4a84c1c
7
- data.tar.gz: 8836f0362c99d8988dcf449c803b85f56bddb6a2e09d24db567a3a8dac3d9f19a6dabecd4cd34ce66c360a83e5ba277825d7061146fb500b8450867d5be0f6df
6
+ metadata.gz: 2ec31a25711298707f2f70722a4ec90a89b042881fe088fe7e40f0ffdc84ff2f337433da997ec36054ccb813d3edbc2e769891a9ff63e709f5b8d4434d45240c
7
+ data.tar.gz: 83fdaa3f0bd3a65bc71372611314499760e1dbf6be102e73fa00f2bb7ff4ba72394375e46c00588182e61d29f279bf245ebec768a194eb7984133f2d4e30f853
@@ -13,12 +13,16 @@ module Libv8::Node
13
13
 
14
14
  def object_paths
15
15
  [Shellwords.escape(File.join(vendored_source_path,
16
- Gem::Platform.local.to_s,
16
+ platform,
17
17
  'libv8',
18
18
  'obj',
19
19
  "libv8_monolith.#{config['LIBEXT']}"))]
20
20
  end
21
21
 
22
+ def platform
23
+ Gem::Platform.local.tap { |p| RUBY_PLATFORM =~ /musl/ && p.version.nil? && p.instance_eval { @version = 'musl' } }.to_s.gsub(/-darwin-?\d+/, '-darwin')
24
+ end
25
+
22
26
  def config
23
27
  RbConfig::MAKEFILE_CONFIG
24
28
  end
@@ -1,7 +1,7 @@
1
1
  module Libv8; end
2
2
 
3
3
  module Libv8::Node
4
- VERSION = '16.10.0.0'.freeze
5
- NODE_VERSION = '16.10.0'.freeze
6
- LIBV8_VERSION = '9.3.345.19'.freeze # from v8/include/v8-version.h
4
+ VERSION = '18.8.0.0'.freeze
5
+ NODE_VERSION = '18.8.0'.freeze
6
+ LIBV8_VERSION = '10.2.154.13'.freeze # from v8/include/v8-version.h
7
7
  end
@@ -10,6 +10,7 @@
10
10
  #include <cstdint>
11
11
  #include <new>
12
12
  #include <type_traits>
13
+ #include <utility>
13
14
 
14
15
  #include "cppgc/custom-space.h"
15
16
  #include "cppgc/internal/api-constants.h"
@@ -17,6 +18,23 @@
17
18
  #include "cppgc/type-traits.h"
18
19
  #include "v8config.h" // NOLINT(build/include_directory)
19
20
 
21
+ #if defined(__has_attribute)
22
+ #if __has_attribute(assume_aligned)
23
+ #define CPPGC_DEFAULT_ALIGNED \
24
+ __attribute__((assume_aligned(api_constants::kDefaultAlignment)))
25
+ #define CPPGC_DOUBLE_WORD_ALIGNED \
26
+ __attribute__((assume_aligned(2 * api_constants::kDefaultAlignment)))
27
+ #endif // __has_attribute(assume_aligned)
28
+ #endif // defined(__has_attribute)
29
+
30
+ #if !defined(CPPGC_DEFAULT_ALIGNED)
31
+ #define CPPGC_DEFAULT_ALIGNED
32
+ #endif
33
+
34
+ #if !defined(CPPGC_DOUBLE_WORD_ALIGNED)
35
+ #define CPPGC_DOUBLE_WORD_ALIGNED
36
+ #endif
37
+
20
38
  namespace cppgc {
21
39
 
22
40
  /**
@@ -26,6 +44,9 @@ class AllocationHandle;
26
44
 
27
45
  namespace internal {
28
46
 
47
+ // Similar to C++17 std::align_val_t;
48
+ enum class AlignVal : size_t {};
49
+
29
50
  class V8_EXPORT MakeGarbageCollectedTraitInternal {
30
51
  protected:
31
52
  static inline void MarkObjectAsFullyConstructed(const void* payload) {
@@ -35,36 +56,81 @@ class V8_EXPORT MakeGarbageCollectedTraitInternal {
35
56
  const_cast<uint16_t*>(reinterpret_cast<const uint16_t*>(
36
57
  reinterpret_cast<const uint8_t*>(payload) -
37
58
  api_constants::kFullyConstructedBitFieldOffsetFromPayload)));
38
- atomic_mutable_bitfield->fetch_or(api_constants::kFullyConstructedBitMask,
39
- std::memory_order_release);
59
+ // It's safe to split use load+store here (instead of a read-modify-write
60
+ // operation), since it's guaranteed that this 16-bit bitfield is only
61
+ // modified by a single thread. This is cheaper in terms of code bloat (on
62
+ // ARM) and performance.
63
+ uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed);
64
+ value |= api_constants::kFullyConstructedBitMask;
65
+ atomic_mutable_bitfield->store(value, std::memory_order_release);
40
66
  }
41
67
 
42
- template <typename U, typename CustomSpace>
43
- struct SpacePolicy {
44
- static void* Allocate(AllocationHandle& handle, size_t size) {
45
- // Custom space.
68
+ // Dispatch based on compile-time information.
69
+ //
70
+ // Default implementation is for a custom space with >`kDefaultAlignment` byte
71
+ // alignment.
72
+ template <typename GCInfoType, typename CustomSpace, size_t alignment>
73
+ struct AllocationDispatcher final {
74
+ static void* Invoke(AllocationHandle& handle, size_t size) {
46
75
  static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
47
76
  "Custom space must inherit from CustomSpaceBase.");
77
+ static_assert(
78
+ !CustomSpace::kSupportsCompaction,
79
+ "Custom spaces that support compaction do not support allocating "
80
+ "objects with non-default (i.e. word-sized) alignment.");
48
81
  return MakeGarbageCollectedTraitInternal::Allocate(
49
- handle, size, internal::GCInfoTrait<U>::Index(),
50
- CustomSpace::kSpaceIndex);
82
+ handle, size, static_cast<AlignVal>(alignment),
83
+ internal::GCInfoTrait<GCInfoType>::Index(), CustomSpace::kSpaceIndex);
84
+ }
85
+ };
86
+
87
+ // Fast path for regular allocations for the default space with
88
+ // `kDefaultAlignment` byte alignment.
89
+ template <typename GCInfoType>
90
+ struct AllocationDispatcher<GCInfoType, void,
91
+ api_constants::kDefaultAlignment>
92
+ final {
93
+ static void* Invoke(AllocationHandle& handle, size_t size) {
94
+ return MakeGarbageCollectedTraitInternal::Allocate(
95
+ handle, size, internal::GCInfoTrait<GCInfoType>::Index());
51
96
  }
52
97
  };
53
98
 
54
- template <typename U>
55
- struct SpacePolicy<U, void> {
56
- static void* Allocate(AllocationHandle& handle, size_t size) {
57
- // Default space.
99
+ // Default space with >`kDefaultAlignment` byte alignment.
100
+ template <typename GCInfoType, size_t alignment>
101
+ struct AllocationDispatcher<GCInfoType, void, alignment> final {
102
+ static void* Invoke(AllocationHandle& handle, size_t size) {
58
103
  return MakeGarbageCollectedTraitInternal::Allocate(
59
- handle, size, internal::GCInfoTrait<U>::Index());
104
+ handle, size, static_cast<AlignVal>(alignment),
105
+ internal::GCInfoTrait<GCInfoType>::Index());
106
+ }
107
+ };
108
+
109
+ // Custom space with `kDefaultAlignment` byte alignment.
110
+ template <typename GCInfoType, typename CustomSpace>
111
+ struct AllocationDispatcher<GCInfoType, CustomSpace,
112
+ api_constants::kDefaultAlignment>
113
+ final {
114
+ static void* Invoke(AllocationHandle& handle, size_t size) {
115
+ static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
116
+ "Custom space must inherit from CustomSpaceBase.");
117
+ return MakeGarbageCollectedTraitInternal::Allocate(
118
+ handle, size, internal::GCInfoTrait<GCInfoType>::Index(),
119
+ CustomSpace::kSpaceIndex);
60
120
  }
61
121
  };
62
122
 
63
123
  private:
64
- static void* Allocate(cppgc::AllocationHandle& handle, size_t size,
65
- GCInfoIndex index);
66
- static void* Allocate(cppgc::AllocationHandle& handle, size_t size,
67
- GCInfoIndex index, CustomSpaceIndex space_index);
124
+ static void* CPPGC_DEFAULT_ALIGNED Allocate(cppgc::AllocationHandle&, size_t,
125
+ GCInfoIndex);
126
+ static void* CPPGC_DOUBLE_WORD_ALIGNED Allocate(cppgc::AllocationHandle&,
127
+ size_t, AlignVal,
128
+ GCInfoIndex);
129
+ static void* CPPGC_DEFAULT_ALIGNED Allocate(cppgc::AllocationHandle&, size_t,
130
+ GCInfoIndex, CustomSpaceIndex);
131
+ static void* CPPGC_DOUBLE_WORD_ALIGNED Allocate(cppgc::AllocationHandle&,
132
+ size_t, AlignVal, GCInfoIndex,
133
+ CustomSpaceIndex);
68
134
 
69
135
  friend class HeapObjectHeader;
70
136
  };
@@ -103,10 +169,18 @@ class MakeGarbageCollectedTraitBase
103
169
  std::is_base_of<typename T::ParentMostGarbageCollectedType, T>::value,
104
170
  "U of GarbageCollected<U> must be a base of T. Check "
105
171
  "GarbageCollected<T> base class inheritance.");
106
- return SpacePolicy<
172
+ static constexpr size_t kWantedAlignment =
173
+ alignof(T) < internal::api_constants::kDefaultAlignment
174
+ ? internal::api_constants::kDefaultAlignment
175
+ : alignof(T);
176
+ static_assert(
177
+ kWantedAlignment <= internal::api_constants::kMaxSupportedAlignment,
178
+ "Requested alignment larger than alignof(std::max_align_t) bytes. "
179
+ "Please file a bug to possibly get this restriction lifted.");
180
+ return AllocationDispatcher<
107
181
  typename internal::GCInfoFolding<
108
182
  T, typename T::ParentMostGarbageCollectedType>::ResultType,
109
- typename SpaceTrait<T>::Space>::Allocate(handle, size);
183
+ typename SpaceTrait<T>::Space, kWantedAlignment>::Invoke(handle, size);
110
184
  }
111
185
 
112
186
  /**
@@ -201,7 +275,7 @@ struct PostConstructionCallbackTrait {
201
275
  * \returns an instance of type T.
202
276
  */
203
277
  template <typename T, typename... Args>
204
- T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) {
278
+ V8_INLINE T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) {
205
279
  T* object =
206
280
  MakeGarbageCollectedTrait<T>::Call(handle, std::forward<Args>(args)...);
207
281
  PostConstructionCallbackTrait<T>::Call(object);
@@ -219,8 +293,9 @@ T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) {
219
293
  * \returns an instance of type T.
220
294
  */
221
295
  template <typename T, typename... Args>
222
- T* MakeGarbageCollected(AllocationHandle& handle,
223
- AdditionalBytes additional_bytes, Args&&... args) {
296
+ V8_INLINE T* MakeGarbageCollected(AllocationHandle& handle,
297
+ AdditionalBytes additional_bytes,
298
+ Args&&... args) {
224
299
  T* object = MakeGarbageCollectedTrait<T>::Call(handle, additional_bytes,
225
300
  std::forward<Args>(args)...);
226
301
  PostConstructionCallbackTrait<T>::Call(object);
@@ -229,4 +304,7 @@ T* MakeGarbageCollected(AllocationHandle& handle,
229
304
 
230
305
  } // namespace cppgc
231
306
 
307
+ #undef CPPGC_DEFAULT_ALIGNED
308
+ #undef CPPGC_DOUBLE_WORD_ALIGNED
309
+
232
310
  #endif // INCLUDE_CPPGC_ALLOCATION_H_
@@ -13,12 +13,62 @@
13
13
  #include "cppgc/visitor.h"
14
14
 
15
15
  namespace cppgc {
16
-
17
16
  namespace internal {
18
17
 
18
+ // Wrapper around PersistentBase that allows accessing poisoned memory when
19
+ // using ASAN. This is needed as the GC of the heap that owns the value
20
+ // of a CTP, may clear it (heap termination, weakness) while the object
21
+ // holding the CTP may be poisoned as itself may be deemed dead.
22
+ class CrossThreadPersistentBase : public PersistentBase {
23
+ public:
24
+ CrossThreadPersistentBase() = default;
25
+ explicit CrossThreadPersistentBase(const void* raw) : PersistentBase(raw) {}
26
+
27
+ V8_CLANG_NO_SANITIZE("address") const void* GetValueFromGC() const {
28
+ return raw_;
29
+ }
30
+
31
+ V8_CLANG_NO_SANITIZE("address")
32
+ PersistentNode* GetNodeFromGC() const { return node_; }
33
+
34
+ V8_CLANG_NO_SANITIZE("address")
35
+ void ClearFromGC() const {
36
+ raw_ = nullptr;
37
+ SetNodeSafe(nullptr);
38
+ }
39
+
40
+ // GetNodeSafe() can be used for a thread-safe IsValid() check in a
41
+ // double-checked locking pattern. See ~BasicCrossThreadPersistent.
42
+ PersistentNode* GetNodeSafe() const {
43
+ return reinterpret_cast<std::atomic<PersistentNode*>*>(&node_)->load(
44
+ std::memory_order_acquire);
45
+ }
46
+
47
+ // The GC writes using SetNodeSafe() while holding the lock.
48
+ V8_CLANG_NO_SANITIZE("address")
49
+ void SetNodeSafe(PersistentNode* value) const {
50
+ #if defined(__has_feature)
51
+ #if __has_feature(address_sanitizer)
52
+ #define V8_IS_ASAN 1
53
+ #endif
54
+ #endif
55
+
56
+ #ifdef V8_IS_ASAN
57
+ __atomic_store(&node_, &value, __ATOMIC_RELEASE);
58
+ #else // !V8_IS_ASAN
59
+ // Non-ASAN builds can use atomics. This also covers MSVC which does not
60
+ // have the __atomic_store intrinsic.
61
+ reinterpret_cast<std::atomic<PersistentNode*>*>(&node_)->store(
62
+ value, std::memory_order_release);
63
+ #endif // !V8_IS_ASAN
64
+
65
+ #undef V8_IS_ASAN
66
+ }
67
+ };
68
+
19
69
  template <typename T, typename WeaknessPolicy, typename LocationPolicy,
20
70
  typename CheckingPolicy>
21
- class BasicCrossThreadPersistent final : public PersistentBase,
71
+ class BasicCrossThreadPersistent final : public CrossThreadPersistentBase,
22
72
  public LocationPolicy,
23
73
  private WeaknessPolicy,
24
74
  private CheckingPolicy {
@@ -26,7 +76,31 @@ class BasicCrossThreadPersistent final : public PersistentBase,
26
76
  using typename WeaknessPolicy::IsStrongPersistent;
27
77
  using PointeeType = T;
28
78
 
29
- ~BasicCrossThreadPersistent() { Clear(); }
79
+ ~BasicCrossThreadPersistent() {
80
+ // This implements fast path for destroying empty/sentinel.
81
+ //
82
+ // Simplified version of `AssignUnsafe()` to allow calling without a
83
+ // complete type `T`. Uses double-checked locking with a simple thread-safe
84
+ // check for a valid handle based on a node.
85
+ if (GetNodeSafe()) {
86
+ PersistentRegionLock guard;
87
+ const void* old_value = GetValue();
88
+ // The fast path check (GetNodeSafe()) does not acquire the lock. Recheck
89
+ // validity while holding the lock to ensure the reference has not been
90
+ // cleared.
91
+ if (IsValid(old_value)) {
92
+ CrossThreadPersistentRegion& region =
93
+ this->GetPersistentRegion(old_value);
94
+ region.FreeNode(GetNode());
95
+ SetNode(nullptr);
96
+ } else {
97
+ CPPGC_DCHECK(!GetNode());
98
+ }
99
+ }
100
+ // No need to call SetValue() as the handle is not used anymore. This can
101
+ // leave behind stale sentinel values but will always destroy the underlying
102
+ // node.
103
+ }
30
104
 
31
105
  BasicCrossThreadPersistent(
32
106
  const SourceLocation& loc = SourceLocation::Current())
@@ -38,11 +112,11 @@ class BasicCrossThreadPersistent final : public PersistentBase,
38
112
 
39
113
  BasicCrossThreadPersistent(
40
114
  SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
41
- : PersistentBase(s), LocationPolicy(loc) {}
115
+ : CrossThreadPersistentBase(s), LocationPolicy(loc) {}
42
116
 
43
117
  BasicCrossThreadPersistent(
44
118
  T* raw, const SourceLocation& loc = SourceLocation::Current())
45
- : PersistentBase(raw), LocationPolicy(loc) {
119
+ : CrossThreadPersistentBase(raw), LocationPolicy(loc) {
46
120
  if (!IsValid(raw)) return;
47
121
  PersistentRegionLock guard;
48
122
  CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
@@ -61,7 +135,7 @@ class BasicCrossThreadPersistent final : public PersistentBase,
61
135
  BasicCrossThreadPersistent(
62
136
  UnsafeCtorTag, T* raw,
63
137
  const SourceLocation& loc = SourceLocation::Current())
64
- : PersistentBase(raw), LocationPolicy(loc) {
138
+ : CrossThreadPersistentBase(raw), LocationPolicy(loc) {
65
139
  if (!IsValid(raw)) return;
66
140
  CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
67
141
  SetNode(region.AllocateNode(this, &Trace));
@@ -113,7 +187,7 @@ class BasicCrossThreadPersistent final : public PersistentBase,
113
187
  BasicCrossThreadPersistent& operator=(
114
188
  const BasicCrossThreadPersistent& other) {
115
189
  PersistentRegionLock guard;
116
- AssignUnsafe(other.Get());
190
+ AssignSafe(guard, other.Get());
117
191
  return *this;
118
192
  }
119
193
 
@@ -125,7 +199,7 @@ class BasicCrossThreadPersistent final : public PersistentBase,
125
199
  OtherLocationPolicy,
126
200
  OtherCheckingPolicy>& other) {
127
201
  PersistentRegionLock guard;
128
- AssignUnsafe(other.Get());
202
+ AssignSafe(guard, other.Get());
129
203
  return *this;
130
204
  }
131
205
 
@@ -143,8 +217,13 @@ class BasicCrossThreadPersistent final : public PersistentBase,
143
217
  return *this;
144
218
  }
145
219
 
220
+ /**
221
+ * Assigns a raw pointer.
222
+ *
223
+ * Note: **Not thread-safe.**
224
+ */
146
225
  BasicCrossThreadPersistent& operator=(T* other) {
147
- Assign(other);
226
+ AssignUnsafe(other);
148
227
  return *this;
149
228
  }
150
229
 
@@ -159,13 +238,24 @@ class BasicCrossThreadPersistent final : public PersistentBase,
159
238
  return operator=(member.Get());
160
239
  }
161
240
 
241
+ /**
242
+ * Assigns a nullptr.
243
+ *
244
+ * \returns the handle.
245
+ */
162
246
  BasicCrossThreadPersistent& operator=(std::nullptr_t) {
163
247
  Clear();
164
248
  return *this;
165
249
  }
166
250
 
251
+ /**
252
+ * Assigns the sentinel pointer.
253
+ *
254
+ * \returns the handle.
255
+ */
167
256
  BasicCrossThreadPersistent& operator=(SentinelPointer s) {
168
- Assign(s);
257
+ PersistentRegionLock guard;
258
+ AssignSafe(guard, s);
169
259
  return *this;
170
260
  }
171
261
 
@@ -187,24 +277,8 @@ class BasicCrossThreadPersistent final : public PersistentBase,
187
277
  * Clears the stored object.
188
278
  */
189
279
  void Clear() {
190
- // Simplified version of `Assign()` to allow calling without a complete type
191
- // `T`.
192
- const void* old_value = GetValue();
193
- if (IsValid(old_value)) {
194
- PersistentRegionLock guard;
195
- old_value = GetValue();
196
- // The fast path check (IsValid()) does not acquire the lock. Reload
197
- // the value to ensure the reference has not been cleared.
198
- if (IsValid(old_value)) {
199
- CrossThreadPersistentRegion& region =
200
- this->GetPersistentRegion(old_value);
201
- region.FreeNode(GetNode());
202
- SetNode(nullptr);
203
- } else {
204
- CPPGC_DCHECK(!GetNode());
205
- }
206
- }
207
- SetValue(nullptr);
280
+ PersistentRegionLock guard;
281
+ AssignSafe(guard, nullptr);
208
282
  }
209
283
 
210
284
  /**
@@ -280,7 +354,7 @@ class BasicCrossThreadPersistent final : public PersistentBase,
280
354
  v->TraceRoot(*handle, handle->Location());
281
355
  }
282
356
 
283
- void Assign(T* ptr) {
357
+ void AssignUnsafe(T* ptr) {
284
358
  const void* old_value = GetValue();
285
359
  if (IsValid(old_value)) {
286
360
  PersistentRegionLock guard;
@@ -308,7 +382,7 @@ class BasicCrossThreadPersistent final : public PersistentBase,
308
382
  this->CheckPointer(ptr);
309
383
  }
310
384
 
311
- void AssignUnsafe(T* ptr) {
385
+ void AssignSafe(PersistentRegionLock&, T* ptr) {
312
386
  PersistentRegionLock::AssertLocked();
313
387
  const void* old_value = GetValue();
314
388
  if (IsValid(old_value)) {
@@ -329,12 +403,19 @@ class BasicCrossThreadPersistent final : public PersistentBase,
329
403
  }
330
404
 
331
405
  void ClearFromGC() const {
332
- if (IsValid(GetValue())) {
333
- WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
334
- PersistentBase::ClearFromGC();
406
+ if (IsValid(GetValueFromGC())) {
407
+ WeaknessPolicy::GetPersistentRegion(GetValueFromGC())
408
+ .FreeNode(GetNodeFromGC());
409
+ CrossThreadPersistentBase::ClearFromGC();
335
410
  }
336
411
  }
337
412
 
413
+ // See Get() for details.
414
+ V8_CLANG_NO_SANITIZE("cfi-unrelated-cast")
415
+ T* GetFromGC() const {
416
+ return static_cast<T*>(const_cast<void*>(GetValueFromGC()));
417
+ }
418
+
338
419
  friend class cppgc::Visitor;
339
420
  };
340
421
 
@@ -6,7 +6,6 @@
6
6
  #define INCLUDE_CPPGC_DEFAULT_PLATFORM_H_
7
7
 
8
8
  #include <memory>
9
- #include <vector>
10
9
 
11
10
  #include "cppgc/platform.h"
12
11
  #include "libplatform/libplatform.h"
@@ -20,15 +19,6 @@ namespace cppgc {
20
19
  */
21
20
  class V8_EXPORT DefaultPlatform : public Platform {
22
21
  public:
23
- /**
24
- * Use this method instead of 'cppgc::InitializeProcess' when using
25
- * 'cppgc::DefaultPlatform'. 'cppgc::DefaultPlatform::InitializeProcess'
26
- * will initialize cppgc and v8 if needed (for non-standalone builds).
27
- *
28
- * \param platform DefaultPlatform instance used to initialize cppgc/v8.
29
- */
30
- static void InitializeProcess(DefaultPlatform* platform);
31
-
32
22
  using IdleTaskSupport = v8::platform::IdleTaskSupport;
33
23
  explicit DefaultPlatform(
34
24
  int thread_pool_size = 0,
@@ -64,6 +54,8 @@ class V8_EXPORT DefaultPlatform : public Platform {
64
54
  return v8_platform_->GetTracingController();
65
55
  }
66
56
 
57
+ v8::Platform* GetV8Platform() const { return v8_platform_.get(); }
58
+
67
59
  protected:
68
60
  static constexpr v8::Isolate* kNoIsolate = nullptr;
69
61
 
@@ -15,11 +15,27 @@ namespace cppgc {
15
15
 
16
16
  class HeapHandle;
17
17
 
18
+ namespace subtle {
19
+
20
+ template <typename T>
21
+ void FreeUnreferencedObject(HeapHandle& heap_handle, T& object);
22
+ template <typename T>
23
+ bool Resize(T& object, AdditionalBytes additional_bytes);
24
+
25
+ } // namespace subtle
26
+
18
27
  namespace internal {
19
28
 
20
- V8_EXPORT void FreeUnreferencedObject(HeapHandle&, void*);
21
- V8_EXPORT bool Resize(void*, size_t);
29
+ class ExplicitManagementImpl final {
30
+ private:
31
+ V8_EXPORT static void FreeUnreferencedObject(HeapHandle&, void*);
32
+ V8_EXPORT static bool Resize(void*, size_t);
22
33
 
34
+ template <typename T>
35
+ friend void subtle::FreeUnreferencedObject(HeapHandle&, T&);
36
+ template <typename T>
37
+ friend bool subtle::Resize(T&, AdditionalBytes);
38
+ };
23
39
  } // namespace internal
24
40
 
25
41
  namespace subtle {
@@ -45,7 +61,8 @@ template <typename T>
45
61
  void FreeUnreferencedObject(HeapHandle& heap_handle, T& object) {
46
62
  static_assert(IsGarbageCollectedTypeV<T>,
47
63
  "Object must be of type GarbageCollected.");
48
- internal::FreeUnreferencedObject(heap_handle, &object);
64
+ internal::ExplicitManagementImpl::FreeUnreferencedObject(heap_handle,
65
+ &object);
49
66
  }
50
67
 
51
68
  /**
@@ -73,7 +90,8 @@ template <typename T>
73
90
  bool Resize(T& object, AdditionalBytes additional_bytes) {
74
91
  static_assert(IsGarbageCollectedTypeV<T>,
75
92
  "Object must be of type GarbageCollected.");
76
- return internal::Resize(&object, sizeof(T) + additional_bytes.value);
93
+ return internal::ExplicitManagementImpl::Resize(
94
+ &object, sizeof(T) + additional_bytes.value);
77
95
  }
78
96
 
79
97
  } // namespace subtle
@@ -5,8 +5,6 @@
5
5
  #ifndef INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
6
6
  #define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
7
7
 
8
- #include <type_traits>
9
-
10
8
  #include "cppgc/internal/api-constants.h"
11
9
  #include "cppgc/platform.h"
12
10
  #include "cppgc/trace-trait.h"
@@ -16,28 +14,6 @@ namespace cppgc {
16
14
 
17
15
  class Visitor;
18
16
 
19
- namespace internal {
20
-
21
- class GarbageCollectedBase {
22
- public:
23
- // Must use MakeGarbageCollected.
24
- void* operator new(size_t) = delete;
25
- void* operator new[](size_t) = delete;
26
- // The garbage collector is taking care of reclaiming the object. Also,
27
- // virtual destructor requires an unambiguous, accessible 'operator delete'.
28
- void operator delete(void*) {
29
- #ifdef V8_ENABLE_CHECKS
30
- internal::Abort();
31
- #endif // V8_ENABLE_CHECKS
32
- }
33
- void operator delete[](void*) = delete;
34
-
35
- protected:
36
- GarbageCollectedBase() = default;
37
- };
38
-
39
- } // namespace internal
40
-
41
17
  /**
42
18
  * Base class for managed objects. Only descendent types of `GarbageCollected`
43
19
  * can be constructed using `MakeGarbageCollected()`. Must be inherited from as
@@ -74,11 +50,24 @@ class GarbageCollectedBase {
74
50
  * \endcode
75
51
  */
76
52
  template <typename T>
77
- class GarbageCollected : public internal::GarbageCollectedBase {
53
+ class GarbageCollected {
78
54
  public:
79
55
  using IsGarbageCollectedTypeMarker = void;
80
56
  using ParentMostGarbageCollectedType = T;
81
57
 
58
+ // Must use MakeGarbageCollected.
59
+ void* operator new(size_t) = delete;
60
+ void* operator new[](size_t) = delete;
61
+ // The garbage collector is taking care of reclaiming the object. Also,
62
+ // virtual destructor requires an unambiguous, accessible 'operator delete'.
63
+ void operator delete(void*) {
64
+ #ifdef V8_ENABLE_CHECKS
65
+ internal::Fatal(
66
+ "Manually deleting a garbage collected object is not allowed");
67
+ #endif // V8_ENABLE_CHECKS
68
+ }
69
+ void operator delete[](void*) = delete;
70
+
82
71
  protected:
83
72
  GarbageCollected() = default;
84
73
  };
@@ -101,7 +90,7 @@ class GarbageCollected : public internal::GarbageCollectedBase {
101
90
  * };
102
91
  * \endcode
103
92
  */
104
- class GarbageCollectedMixin : public internal::GarbageCollectedBase {
93
+ class GarbageCollectedMixin {
105
94
  public:
106
95
  using IsGarbageCollectedMixinTypeMarker = void;
107
96
 
@@ -68,6 +68,23 @@ class HeapConsistency final {
68
68
  return internal::WriteBarrier::GetWriteBarrierType(slot, params, callback);
69
69
  }
70
70
 
71
+ /**
72
+ * Gets the required write barrier type for a specific write.
73
+ * This version is meant to be used in conjunction with with a marking write
74
+ * barrier barrier which doesn't consider the slot.
75
+ *
76
+ * \param value The pointer to the object. May be an interior pointer to an
77
+ * interface of the actual object.
78
+ * \param params Parameters that may be used for actual write barrier calls.
79
+ * Only filled if return value indicates that a write barrier is needed. The
80
+ * contents of the `params` are an implementation detail.
81
+ * \returns whether a write barrier is needed and which barrier to invoke.
82
+ */
83
+ static V8_INLINE WriteBarrierType
84
+ GetWriteBarrierType(const void* value, WriteBarrierParams& params) {
85
+ return internal::WriteBarrier::GetWriteBarrierType(value, params);
86
+ }
87
+
71
88
  /**
72
89
  * Conservative Dijkstra-style write barrier that processes an object if it
73
90
  * has not yet been processed.
@@ -132,6 +149,19 @@ class HeapConsistency final {
132
149
  internal::WriteBarrier::GenerationalBarrier(params, slot);
133
150
  }
134
151
 
152
+ /**
153
+ * Generational barrier for source object that may contain outgoing pointers
154
+ * to objects in young generation.
155
+ *
156
+ * \param params The parameters retrieved from `GetWriteBarrierType()`.
157
+ * \param inner_pointer Pointer to the source object.
158
+ */
159
+ static V8_INLINE void GenerationalBarrierForSourceObject(
160
+ const WriteBarrierParams& params, const void* inner_pointer) {
161
+ internal::WriteBarrier::GenerationalBarrierForSourceObject(params,
162
+ inner_pointer);
163
+ }
164
+
135
165
  private:
136
166
  HeapConsistency() = delete;
137
167
  };