libv8-node 16.10.0.0-x86_64-linux-musl → 18.8.0.0-x86_64-linux-musl

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 (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/include/cppgc/allocation.h +100 -22
  5. data/vendor/v8/include/cppgc/cross-thread-persistent.h +114 -33
  6. data/vendor/v8/include/cppgc/default-platform.h +2 -10
  7. data/vendor/v8/include/cppgc/explicit-management.h +22 -4
  8. data/vendor/v8/include/cppgc/garbage-collected.h +15 -26
  9. data/vendor/v8/include/cppgc/heap-consistency.h +30 -0
  10. data/vendor/v8/include/cppgc/heap-state.h +12 -0
  11. data/vendor/v8/include/cppgc/heap.h +7 -2
  12. data/vendor/v8/include/cppgc/internal/api-constants.h +8 -0
  13. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +25 -14
  14. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +4 -1
  15. data/vendor/v8/include/cppgc/internal/gc-info.h +90 -10
  16. data/vendor/v8/include/cppgc/internal/logging.h +3 -3
  17. data/vendor/v8/include/cppgc/internal/name-trait.h +11 -0
  18. data/vendor/v8/include/cppgc/internal/persistent-node.h +73 -29
  19. data/vendor/v8/include/cppgc/internal/pointer-policies.h +26 -15
  20. data/vendor/v8/include/cppgc/internal/write-barrier.h +62 -23
  21. data/vendor/v8/include/cppgc/liveness-broker.h +4 -1
  22. data/vendor/v8/include/cppgc/member.h +7 -2
  23. data/vendor/v8/include/cppgc/persistent.h +38 -33
  24. data/vendor/v8/include/cppgc/platform.h +4 -1
  25. data/vendor/v8/include/cppgc/prefinalizer.h +35 -12
  26. data/vendor/v8/include/cppgc/testing.h +9 -2
  27. data/vendor/v8/include/cppgc/type-traits.h +6 -13
  28. data/vendor/v8/include/cppgc/visitor.h +9 -7
  29. data/vendor/v8/include/libplatform/libplatform.h +0 -11
  30. data/vendor/v8/include/libplatform/v8-tracing.h +0 -1
  31. data/vendor/v8/include/v8-array-buffer.h +445 -0
  32. data/vendor/v8/include/v8-callbacks.h +397 -0
  33. data/vendor/v8/include/v8-container.h +129 -0
  34. data/vendor/v8/include/v8-context.h +407 -0
  35. data/vendor/v8/include/v8-cppgc.h +21 -128
  36. data/vendor/v8/include/v8-data.h +80 -0
  37. data/vendor/v8/include/v8-date.h +43 -0
  38. data/vendor/v8/include/v8-debug.h +168 -0
  39. data/vendor/v8/include/v8-embedder-heap.h +218 -0
  40. data/vendor/v8/include/v8-embedder-state-scope.h +51 -0
  41. data/vendor/v8/include/v8-exception.h +217 -0
  42. data/vendor/v8/include/v8-extension.h +62 -0
  43. data/vendor/v8/include/v8-external.h +37 -0
  44. data/vendor/v8/include/v8-fast-api-calls.h +172 -24
  45. data/vendor/v8/include/v8-forward.h +81 -0
  46. data/vendor/v8/include/v8-function-callback.h +475 -0
  47. data/vendor/v8/include/v8-function.h +125 -0
  48. data/vendor/v8/include/v8-initialization.h +315 -0
  49. data/vendor/v8/include/v8-inspector.h +56 -28
  50. data/vendor/v8/include/v8-internal.h +217 -55
  51. data/vendor/v8/include/v8-isolate.h +1709 -0
  52. data/vendor/v8/include/v8-json.h +47 -0
  53. data/vendor/v8/include/v8-local-handle.h +455 -0
  54. data/vendor/v8/include/v8-locker.h +149 -0
  55. data/vendor/v8/include/v8-maybe.h +137 -0
  56. data/vendor/v8/include/v8-memory-span.h +43 -0
  57. data/vendor/v8/include/v8-message.h +216 -0
  58. data/vendor/v8/include/v8-metrics.h +69 -16
  59. data/vendor/v8/include/v8-microtask-queue.h +152 -0
  60. data/vendor/v8/include/v8-microtask.h +28 -0
  61. data/vendor/v8/include/v8-object.h +775 -0
  62. data/vendor/v8/include/v8-persistent-handle.h +590 -0
  63. data/vendor/v8/include/v8-platform.h +400 -17
  64. data/vendor/v8/include/v8-primitive-object.h +118 -0
  65. data/vendor/v8/include/v8-primitive.h +866 -0
  66. data/vendor/v8/include/v8-profiler.h +88 -13
  67. data/vendor/v8/include/v8-promise.h +174 -0
  68. data/vendor/v8/include/v8-proxy.h +50 -0
  69. data/vendor/v8/include/v8-regexp.h +105 -0
  70. data/vendor/v8/include/v8-script.h +747 -0
  71. data/vendor/v8/include/v8-snapshot.h +196 -0
  72. data/vendor/v8/include/v8-statistics.h +217 -0
  73. data/vendor/v8/include/v8-template.h +1079 -0
  74. data/vendor/v8/include/v8-traced-handle.h +420 -0
  75. data/vendor/v8/include/v8-typed-array.h +282 -0
  76. data/vendor/v8/include/v8-unwinder-state.h +4 -3
  77. data/vendor/v8/include/v8-unwinder.h +132 -0
  78. data/vendor/v8/include/v8-util.h +7 -1
  79. data/vendor/v8/include/v8-value-serializer-version.h +1 -1
  80. data/vendor/v8/include/v8-value-serializer.h +279 -0
  81. data/vendor/v8/include/v8-value.h +526 -0
  82. data/vendor/v8/include/v8-version.h +4 -4
  83. data/vendor/v8/include/v8-wasm.h +257 -0
  84. data/vendor/v8/include/v8-weak-callback-info.h +87 -0
  85. data/vendor/v8/include/v8.h +41 -12601
  86. data/vendor/v8/include/v8config.h +102 -12
  87. data/vendor/v8/x86_64-linux-musl/libv8/obj/libv8_monolith.a +0 -0
  88. metadata +50 -8
  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: 0cedf064ab80ddde0c0e17fdab78db263c8c7a8dd939073a974939efc2399c88
4
- data.tar.gz: 5acdea59c6e8c3336e66f179dbc69ad0c4cdfb166798734d725716c076f1f914
3
+ metadata.gz: 6ab69b052f1c21394fece08faf35f5a23961297f8a9ec1fe6cc3783f0dee191b
4
+ data.tar.gz: 338a785654b55fd72333a38a9384bca3d82827e95372e958bc6074c173de9bd6
5
5
  SHA512:
6
- metadata.gz: 5324e7cf6d7a8f6ad027885582d184286b0f63b81e4172d1f47dce81240fa652ccfc917efdc45fba385d5617a07c6dce930baf107171b3cf7bf9347c837c9baa
7
- data.tar.gz: f6561007b43cb91839de3ead9e9846f38699616c7812df46fdea40a5d6f5ecb20a678ef5cedeebe9034a792ca99e4848251fb436a02e38a0c0a5ded405cafdb6
6
+ metadata.gz: b5594639a63379038dc8213706b1e72110f4ada7f9ae261d60a95c463c5479745f36a7a05430a511ec67f3b922c546723350073f1b65a9eb03718b20394a1b98
7
+ data.tar.gz: 2cc261d10017bb8b62c32c39b0b275d8cab6a60dbf7c0ad30d12d391ecc1638c5cccd95eac95739529a5eb22a45b3f0308a0a4d2f6c789cdb1f352cec01b72da
@@ -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
  };