libv8-node 15.14.0.1-x86_64-linux-musl → 17.9.1.0-x86_64-linux-musl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/location.rb +1 -1
  3. data/ext/libv8-node/paths.rb +5 -1
  4. data/lib/libv8/node/version.rb +3 -3
  5. data/vendor/v8/include/cppgc/allocation.h +110 -44
  6. data/vendor/v8/include/cppgc/common.h +9 -6
  7. data/vendor/v8/include/cppgc/cross-thread-persistent.h +465 -0
  8. data/vendor/v8/include/cppgc/custom-space.h +37 -2
  9. data/vendor/v8/include/cppgc/default-platform.h +47 -48
  10. data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
  11. data/vendor/v8/include/cppgc/explicit-management.h +82 -0
  12. data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
  13. data/vendor/v8/include/cppgc/heap-consistency.h +253 -0
  14. data/vendor/v8/include/cppgc/heap-state.h +70 -0
  15. data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
  16. data/vendor/v8/include/cppgc/heap.h +68 -6
  17. data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
  18. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +4 -3
  19. data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
  20. data/vendor/v8/include/cppgc/internal/finalizer-trait.h +2 -0
  21. data/vendor/v8/include/cppgc/internal/gc-info.h +124 -13
  22. data/vendor/v8/include/cppgc/internal/name-trait.h +122 -0
  23. data/vendor/v8/include/cppgc/internal/persistent-node.h +94 -6
  24. data/vendor/v8/include/cppgc/internal/pointer-policies.h +81 -29
  25. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
  26. data/vendor/v8/include/cppgc/internal/write-barrier.h +398 -35
  27. data/vendor/v8/include/cppgc/liveness-broker.h +11 -2
  28. data/vendor/v8/include/cppgc/macros.h +2 -0
  29. data/vendor/v8/include/cppgc/member.h +87 -25
  30. data/vendor/v8/include/cppgc/name-provider.h +65 -0
  31. data/vendor/v8/include/cppgc/object-size-trait.h +58 -0
  32. data/vendor/v8/include/cppgc/persistent.h +41 -11
  33. data/vendor/v8/include/cppgc/platform.h +49 -25
  34. data/vendor/v8/include/cppgc/prefinalizer.h +2 -2
  35. data/vendor/v8/include/cppgc/process-heap-statistics.h +36 -0
  36. data/vendor/v8/include/cppgc/sentinel-pointer.h +32 -0
  37. data/vendor/v8/include/cppgc/source-location.h +2 -1
  38. data/vendor/v8/include/cppgc/testing.h +99 -0
  39. data/vendor/v8/include/cppgc/trace-trait.h +8 -3
  40. data/vendor/v8/include/cppgc/type-traits.h +157 -19
  41. data/vendor/v8/include/cppgc/visitor.h +194 -28
  42. data/vendor/v8/include/libplatform/libplatform.h +11 -0
  43. data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
  44. data/vendor/v8/include/v8-array-buffer.h +433 -0
  45. data/vendor/v8/include/v8-callbacks.h +377 -0
  46. data/vendor/v8/include/v8-container.h +129 -0
  47. data/vendor/v8/include/v8-context.h +418 -0
  48. data/vendor/v8/include/v8-cppgc.h +261 -159
  49. data/vendor/v8/include/v8-data.h +65 -0
  50. data/vendor/v8/include/v8-date.h +43 -0
  51. data/vendor/v8/include/v8-debug.h +151 -0
  52. data/vendor/v8/include/v8-embedder-heap.h +238 -0
  53. data/vendor/v8/include/v8-exception.h +224 -0
  54. data/vendor/v8/include/v8-extension.h +62 -0
  55. data/vendor/v8/include/v8-external.h +37 -0
  56. data/vendor/v8/include/v8-fast-api-calls.h +652 -152
  57. data/vendor/v8/include/v8-forward.h +81 -0
  58. data/vendor/v8/include/v8-function-callback.h +475 -0
  59. data/vendor/v8/include/v8-function.h +122 -0
  60. data/vendor/v8/include/v8-initialization.h +282 -0
  61. data/vendor/v8/include/v8-inspector.h +33 -25
  62. data/vendor/v8/include/v8-internal.h +178 -31
  63. data/vendor/v8/include/v8-isolate.h +1662 -0
  64. data/vendor/v8/include/v8-json.h +47 -0
  65. data/vendor/v8/include/v8-local-handle.h +459 -0
  66. data/vendor/v8/include/v8-locker.h +148 -0
  67. data/vendor/v8/include/v8-maybe.h +137 -0
  68. data/vendor/v8/include/v8-memory-span.h +43 -0
  69. data/vendor/v8/include/v8-message.h +241 -0
  70. data/vendor/v8/include/v8-metrics.h +114 -9
  71. data/vendor/v8/include/v8-microtask-queue.h +152 -0
  72. data/vendor/v8/include/v8-microtask.h +28 -0
  73. data/vendor/v8/include/v8-object.h +770 -0
  74. data/vendor/v8/include/v8-persistent-handle.h +590 -0
  75. data/vendor/v8/include/v8-platform.h +74 -25
  76. data/vendor/v8/include/v8-primitive-object.h +118 -0
  77. data/vendor/v8/include/v8-primitive.h +858 -0
  78. data/vendor/v8/include/v8-profiler.h +72 -9
  79. data/vendor/v8/include/v8-promise.h +174 -0
  80. data/vendor/v8/include/v8-proxy.h +50 -0
  81. data/vendor/v8/include/v8-regexp.h +105 -0
  82. data/vendor/v8/include/v8-script.h +771 -0
  83. data/vendor/v8/include/v8-snapshot.h +198 -0
  84. data/vendor/v8/include/v8-statistics.h +215 -0
  85. data/vendor/v8/include/v8-template.h +1052 -0
  86. data/vendor/v8/include/v8-traced-handle.h +605 -0
  87. data/vendor/v8/include/v8-typed-array.h +282 -0
  88. data/vendor/v8/include/v8-unwinder-state.h +31 -0
  89. data/vendor/v8/include/v8-unwinder.h +129 -0
  90. data/vendor/v8/include/v8-util.h +8 -2
  91. data/vendor/v8/include/v8-value-serializer.h +249 -0
  92. data/vendor/v8/include/v8-value.h +526 -0
  93. data/vendor/v8/include/v8-version.h +3 -3
  94. data/vendor/v8/include/v8-wasm.h +245 -0
  95. data/vendor/v8/include/v8-weak-callback-info.h +73 -0
  96. data/vendor/v8/include/v8.h +41 -12050
  97. data/vendor/v8/include/v8config.h +87 -11
  98. data/vendor/v8/{out.gn → x86_64-linux-musl}/libv8/obj/libv8_monolith.a +0 -0
  99. metadata +63 -9
  100. data/vendor/v8/include/cppgc/internal/process-heap.h +0 -34
@@ -0,0 +1,465 @@
1
+ // Copyright 2020 the V8 project authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ #ifndef INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
6
+ #define INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
7
+
8
+ #include <atomic>
9
+
10
+ #include "cppgc/internal/persistent-node.h"
11
+ #include "cppgc/internal/pointer-policies.h"
12
+ #include "cppgc/persistent.h"
13
+ #include "cppgc/visitor.h"
14
+
15
+ namespace cppgc {
16
+ namespace internal {
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
+
69
+ template <typename T, typename WeaknessPolicy, typename LocationPolicy,
70
+ typename CheckingPolicy>
71
+ class BasicCrossThreadPersistent final : public CrossThreadPersistentBase,
72
+ public LocationPolicy,
73
+ private WeaknessPolicy,
74
+ private CheckingPolicy {
75
+ public:
76
+ using typename WeaknessPolicy::IsStrongPersistent;
77
+ using PointeeType = T;
78
+
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
+ }
104
+
105
+ BasicCrossThreadPersistent(
106
+ const SourceLocation& loc = SourceLocation::Current())
107
+ : LocationPolicy(loc) {}
108
+
109
+ BasicCrossThreadPersistent(
110
+ std::nullptr_t, const SourceLocation& loc = SourceLocation::Current())
111
+ : LocationPolicy(loc) {}
112
+
113
+ BasicCrossThreadPersistent(
114
+ SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
115
+ : CrossThreadPersistentBase(s), LocationPolicy(loc) {}
116
+
117
+ BasicCrossThreadPersistent(
118
+ T* raw, const SourceLocation& loc = SourceLocation::Current())
119
+ : CrossThreadPersistentBase(raw), LocationPolicy(loc) {
120
+ if (!IsValid(raw)) return;
121
+ PersistentRegionLock guard;
122
+ CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
123
+ SetNode(region.AllocateNode(this, &Trace));
124
+ this->CheckPointer(raw);
125
+ }
126
+
127
+ class UnsafeCtorTag {
128
+ private:
129
+ UnsafeCtorTag() = default;
130
+ template <typename U, typename OtherWeaknessPolicy,
131
+ typename OtherLocationPolicy, typename OtherCheckingPolicy>
132
+ friend class BasicCrossThreadPersistent;
133
+ };
134
+
135
+ BasicCrossThreadPersistent(
136
+ UnsafeCtorTag, T* raw,
137
+ const SourceLocation& loc = SourceLocation::Current())
138
+ : CrossThreadPersistentBase(raw), LocationPolicy(loc) {
139
+ if (!IsValid(raw)) return;
140
+ CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
141
+ SetNode(region.AllocateNode(this, &Trace));
142
+ this->CheckPointer(raw);
143
+ }
144
+
145
+ BasicCrossThreadPersistent(
146
+ T& raw, const SourceLocation& loc = SourceLocation::Current())
147
+ : BasicCrossThreadPersistent(&raw, loc) {}
148
+
149
+ template <typename U, typename MemberBarrierPolicy,
150
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
151
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
152
+ BasicCrossThreadPersistent(
153
+ internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
154
+ MemberCheckingPolicy>
155
+ member,
156
+ const SourceLocation& loc = SourceLocation::Current())
157
+ : BasicCrossThreadPersistent(member.Get(), loc) {}
158
+
159
+ BasicCrossThreadPersistent(
160
+ const BasicCrossThreadPersistent& other,
161
+ const SourceLocation& loc = SourceLocation::Current())
162
+ : BasicCrossThreadPersistent(loc) {
163
+ // Invoke operator=.
164
+ *this = other;
165
+ }
166
+
167
+ // Heterogeneous ctor.
168
+ template <typename U, typename OtherWeaknessPolicy,
169
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
170
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
171
+ BasicCrossThreadPersistent(
172
+ const BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
173
+ OtherLocationPolicy,
174
+ OtherCheckingPolicy>& other,
175
+ const SourceLocation& loc = SourceLocation::Current())
176
+ : BasicCrossThreadPersistent(loc) {
177
+ *this = other;
178
+ }
179
+
180
+ BasicCrossThreadPersistent(
181
+ BasicCrossThreadPersistent&& other,
182
+ const SourceLocation& loc = SourceLocation::Current()) noexcept {
183
+ // Invoke operator=.
184
+ *this = std::move(other);
185
+ }
186
+
187
+ BasicCrossThreadPersistent& operator=(
188
+ const BasicCrossThreadPersistent& other) {
189
+ PersistentRegionLock guard;
190
+ AssignSafe(guard, other.Get());
191
+ return *this;
192
+ }
193
+
194
+ template <typename U, typename OtherWeaknessPolicy,
195
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
196
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
197
+ BasicCrossThreadPersistent& operator=(
198
+ const BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
199
+ OtherLocationPolicy,
200
+ OtherCheckingPolicy>& other) {
201
+ PersistentRegionLock guard;
202
+ AssignSafe(guard, other.Get());
203
+ return *this;
204
+ }
205
+
206
+ BasicCrossThreadPersistent& operator=(BasicCrossThreadPersistent&& other) {
207
+ if (this == &other) return *this;
208
+ Clear();
209
+ PersistentRegionLock guard;
210
+ PersistentBase::operator=(std::move(other));
211
+ LocationPolicy::operator=(std::move(other));
212
+ if (!IsValid(GetValue())) return *this;
213
+ GetNode()->UpdateOwner(this);
214
+ other.SetValue(nullptr);
215
+ other.SetNode(nullptr);
216
+ this->CheckPointer(Get());
217
+ return *this;
218
+ }
219
+
220
+ /**
221
+ * Assigns a raw pointer.
222
+ *
223
+ * Note: **Not thread-safe.**
224
+ */
225
+ BasicCrossThreadPersistent& operator=(T* other) {
226
+ AssignUnsafe(other);
227
+ return *this;
228
+ }
229
+
230
+ // Assignment from member.
231
+ template <typename U, typename MemberBarrierPolicy,
232
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
233
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
234
+ BasicCrossThreadPersistent& operator=(
235
+ internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
236
+ MemberCheckingPolicy>
237
+ member) {
238
+ return operator=(member.Get());
239
+ }
240
+
241
+ /**
242
+ * Assigns a nullptr.
243
+ *
244
+ * \returns the handle.
245
+ */
246
+ BasicCrossThreadPersistent& operator=(std::nullptr_t) {
247
+ Clear();
248
+ return *this;
249
+ }
250
+
251
+ /**
252
+ * Assigns the sentinel pointer.
253
+ *
254
+ * \returns the handle.
255
+ */
256
+ BasicCrossThreadPersistent& operator=(SentinelPointer s) {
257
+ PersistentRegionLock guard;
258
+ AssignSafe(guard, s);
259
+ return *this;
260
+ }
261
+
262
+ /**
263
+ * Returns a pointer to the stored object.
264
+ *
265
+ * Note: **Not thread-safe.**
266
+ *
267
+ * \returns a pointer to the stored object.
268
+ */
269
+ // CFI cast exemption to allow passing SentinelPointer through T* and support
270
+ // heterogeneous assignments between different Member and Persistent handles
271
+ // based on their actual types.
272
+ V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
273
+ return static_cast<T*>(const_cast<void*>(GetValue()));
274
+ }
275
+
276
+ /**
277
+ * Clears the stored object.
278
+ */
279
+ void Clear() {
280
+ PersistentRegionLock guard;
281
+ AssignSafe(guard, nullptr);
282
+ }
283
+
284
+ /**
285
+ * Returns a pointer to the stored object and releases it.
286
+ *
287
+ * Note: **Not thread-safe.**
288
+ *
289
+ * \returns a pointer to the stored object.
290
+ */
291
+ T* Release() {
292
+ T* result = Get();
293
+ Clear();
294
+ return result;
295
+ }
296
+
297
+ /**
298
+ * Conversio to boolean.
299
+ *
300
+ * Note: **Not thread-safe.**
301
+ *
302
+ * \returns true if an actual object has been stored and false otherwise.
303
+ */
304
+ explicit operator bool() const { return Get(); }
305
+
306
+ /**
307
+ * Conversion to object of type T.
308
+ *
309
+ * Note: **Not thread-safe.**
310
+ *
311
+ * \returns the object.
312
+ */
313
+ operator T*() const { return Get(); }
314
+
315
+ /**
316
+ * Dereferences the stored object.
317
+ *
318
+ * Note: **Not thread-safe.**
319
+ */
320
+ T* operator->() const { return Get(); }
321
+ T& operator*() const { return *Get(); }
322
+
323
+ template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy,
324
+ typename OtherLocationPolicy = LocationPolicy,
325
+ typename OtherCheckingPolicy = CheckingPolicy>
326
+ BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
327
+ OtherCheckingPolicy>
328
+ To() const {
329
+ using OtherBasicCrossThreadPersistent =
330
+ BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
331
+ OtherCheckingPolicy>;
332
+ PersistentRegionLock guard;
333
+ return OtherBasicCrossThreadPersistent(
334
+ typename OtherBasicCrossThreadPersistent::UnsafeCtorTag(),
335
+ static_cast<U*>(Get()));
336
+ }
337
+
338
+ template <typename U = T,
339
+ typename = typename std::enable_if<!BasicCrossThreadPersistent<
340
+ U, WeaknessPolicy>::IsStrongPersistent::value>::type>
341
+ BasicCrossThreadPersistent<U, internal::StrongCrossThreadPersistentPolicy>
342
+ Lock() const {
343
+ return BasicCrossThreadPersistent<
344
+ U, internal::StrongCrossThreadPersistentPolicy>(*this);
345
+ }
346
+
347
+ private:
348
+ static bool IsValid(const void* ptr) {
349
+ return ptr && ptr != kSentinelPointer;
350
+ }
351
+
352
+ static void Trace(Visitor* v, const void* ptr) {
353
+ const auto* handle = static_cast<const BasicCrossThreadPersistent*>(ptr);
354
+ v->TraceRoot(*handle, handle->Location());
355
+ }
356
+
357
+ void AssignUnsafe(T* ptr) {
358
+ const void* old_value = GetValue();
359
+ if (IsValid(old_value)) {
360
+ PersistentRegionLock guard;
361
+ old_value = GetValue();
362
+ // The fast path check (IsValid()) does not acquire the lock. Reload
363
+ // the value to ensure the reference has not been cleared.
364
+ if (IsValid(old_value)) {
365
+ CrossThreadPersistentRegion& region =
366
+ this->GetPersistentRegion(old_value);
367
+ if (IsValid(ptr) && (&region == &this->GetPersistentRegion(ptr))) {
368
+ SetValue(ptr);
369
+ this->CheckPointer(ptr);
370
+ return;
371
+ }
372
+ region.FreeNode(GetNode());
373
+ SetNode(nullptr);
374
+ } else {
375
+ CPPGC_DCHECK(!GetNode());
376
+ }
377
+ }
378
+ SetValue(ptr);
379
+ if (!IsValid(ptr)) return;
380
+ PersistentRegionLock guard;
381
+ SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &Trace));
382
+ this->CheckPointer(ptr);
383
+ }
384
+
385
+ void AssignSafe(PersistentRegionLock&, T* ptr) {
386
+ PersistentRegionLock::AssertLocked();
387
+ const void* old_value = GetValue();
388
+ if (IsValid(old_value)) {
389
+ CrossThreadPersistentRegion& region =
390
+ this->GetPersistentRegion(old_value);
391
+ if (IsValid(ptr) && (&region == &this->GetPersistentRegion(ptr))) {
392
+ SetValue(ptr);
393
+ this->CheckPointer(ptr);
394
+ return;
395
+ }
396
+ region.FreeNode(GetNode());
397
+ SetNode(nullptr);
398
+ }
399
+ SetValue(ptr);
400
+ if (!IsValid(ptr)) return;
401
+ SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &Trace));
402
+ this->CheckPointer(ptr);
403
+ }
404
+
405
+ void ClearFromGC() const {
406
+ if (IsValid(GetValueFromGC())) {
407
+ WeaknessPolicy::GetPersistentRegion(GetValueFromGC())
408
+ .FreeNode(GetNodeFromGC());
409
+ CrossThreadPersistentBase::ClearFromGC();
410
+ }
411
+ }
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
+
419
+ friend class cppgc::Visitor;
420
+ };
421
+
422
+ template <typename T, typename LocationPolicy, typename CheckingPolicy>
423
+ struct IsWeak<
424
+ BasicCrossThreadPersistent<T, internal::WeakCrossThreadPersistentPolicy,
425
+ LocationPolicy, CheckingPolicy>>
426
+ : std::true_type {};
427
+
428
+ } // namespace internal
429
+
430
+ namespace subtle {
431
+
432
+ /**
433
+ * **DO NOT USE: Has known caveats, see below.**
434
+ *
435
+ * CrossThreadPersistent allows retaining objects from threads other than the
436
+ * thread the owning heap is operating on.
437
+ *
438
+ * Known caveats:
439
+ * - Does not protect the heap owning an object from terminating.
440
+ * - Reaching transitively through the graph is unsupported as objects may be
441
+ * moved concurrently on the thread owning the object.
442
+ */
443
+ template <typename T>
444
+ using CrossThreadPersistent = internal::BasicCrossThreadPersistent<
445
+ T, internal::StrongCrossThreadPersistentPolicy>;
446
+
447
+ /**
448
+ * **DO NOT USE: Has known caveats, see below.**
449
+ *
450
+ * CrossThreadPersistent allows weakly retaining objects from threads other than
451
+ * the thread the owning heap is operating on.
452
+ *
453
+ * Known caveats:
454
+ * - Does not protect the heap owning an object from terminating.
455
+ * - Reaching transitively through the graph is unsupported as objects may be
456
+ * moved concurrently on the thread owning the object.
457
+ */
458
+ template <typename T>
459
+ using WeakCrossThreadPersistent = internal::BasicCrossThreadPersistent<
460
+ T, internal::WeakCrossThreadPersistentPolicy>;
461
+
462
+ } // namespace subtle
463
+ } // namespace cppgc
464
+
465
+ #endif // INCLUDE_CPPGC_CROSS_THREAD_PERSISTENT_H_
@@ -9,8 +9,11 @@
9
9
 
10
10
  namespace cppgc {
11
11
 
12
+ /**
13
+ * Index identifying a custom space.
14
+ */
12
15
  struct CustomSpaceIndex {
13
- CustomSpaceIndex(size_t value) : value(value) {} // NOLINT
16
+ constexpr CustomSpaceIndex(size_t value) : value(value) {} // NOLINT
14
17
  size_t value;
15
18
  };
16
19
 
@@ -22,11 +25,12 @@ class CustomSpaceBase {
22
25
  public:
23
26
  virtual ~CustomSpaceBase() = default;
24
27
  virtual CustomSpaceIndex GetCustomSpaceIndex() const = 0;
28
+ virtual bool IsCompactable() const = 0;
25
29
  };
26
30
 
27
31
  /**
28
32
  * Base class custom spaces should directly inherit from. The class inheriting
29
- * from CustomSpace must define kSpaceIndex as unique space index. These
33
+ * from `CustomSpace` must define `kSpaceIndex` as unique space index. These
30
34
  * indices need for form a sequence starting at 0.
31
35
  *
32
36
  * Example:
@@ -44,9 +48,18 @@ class CustomSpaceBase {
44
48
  template <typename ConcreteCustomSpace>
45
49
  class CustomSpace : public CustomSpaceBase {
46
50
  public:
51
+ /**
52
+ * Compaction is only supported on spaces that manually manage slots
53
+ * recording.
54
+ */
55
+ static constexpr bool kSupportsCompaction = false;
56
+
47
57
  CustomSpaceIndex GetCustomSpaceIndex() const final {
48
58
  return ConcreteCustomSpace::kSpaceIndex;
49
59
  }
60
+ bool IsCompactable() const final {
61
+ return ConcreteCustomSpace::kSupportsCompaction;
62
+ }
50
63
  };
51
64
 
52
65
  /**
@@ -57,6 +70,28 @@ struct SpaceTrait {
57
70
  using Space = void;
58
71
  };
59
72
 
73
+ namespace internal {
74
+
75
+ template <typename CustomSpace>
76
+ struct IsAllocatedOnCompactableSpaceImpl {
77
+ static constexpr bool value = CustomSpace::kSupportsCompaction;
78
+ };
79
+
80
+ template <>
81
+ struct IsAllocatedOnCompactableSpaceImpl<void> {
82
+ // Non-custom spaces are by default not compactable.
83
+ static constexpr bool value = false;
84
+ };
85
+
86
+ template <typename T>
87
+ struct IsAllocatedOnCompactableSpace {
88
+ public:
89
+ static constexpr bool value =
90
+ IsAllocatedOnCompactableSpaceImpl<typename SpaceTrait<T>::Space>::value;
91
+ };
92
+
93
+ } // namespace internal
94
+
60
95
  } // namespace cppgc
61
96
 
62
97
  #endif // INCLUDE_CPPGC_CUSTOM_SPACE_H_
@@ -6,69 +6,68 @@
6
6
  #define INCLUDE_CPPGC_DEFAULT_PLATFORM_H_
7
7
 
8
8
  #include <memory>
9
- #include <thread> // NOLINT(build/c++11)
10
9
  #include <vector>
11
10
 
12
11
  #include "cppgc/platform.h"
12
+ #include "libplatform/libplatform.h"
13
13
  #include "v8config.h" // NOLINT(build/include_directory)
14
14
 
15
15
  namespace cppgc {
16
16
 
17
17
  /**
18
- * Default task runner implementation. Keep posted tasks in a list that can be
19
- * processed by calling RunSingleTask() or RunUntilIdle().
18
+ * Platform provided by cppgc. Uses V8's DefaultPlatform provided by
19
+ * libplatform internally. Exception: `GetForegroundTaskRunner()`, see below.
20
20
  */
21
- class V8_EXPORT DefaultTaskRunner final : public cppgc::TaskRunner {
21
+ class V8_EXPORT DefaultPlatform : public Platform {
22
22
  public:
23
- DefaultTaskRunner() = default;
24
-
25
- DefaultTaskRunner(const DefaultTaskRunner&) = delete;
26
- DefaultTaskRunner& operator=(const DefaultTaskRunner&) = delete;
27
-
28
- void PostTask(std::unique_ptr<cppgc::Task> task) override;
29
- void PostNonNestableTask(std::unique_ptr<cppgc::Task> task) override;
30
- void PostDelayedTask(std::unique_ptr<cppgc::Task> task, double) override;
31
- void PostNonNestableDelayedTask(std::unique_ptr<cppgc::Task> task,
32
- double) override;
33
-
34
- void PostIdleTask(std::unique_ptr<cppgc::IdleTask> task) override;
35
- bool IdleTasksEnabled() override { return true; }
36
-
37
- bool RunSingleTask();
38
- bool RunSingleIdleTask(double duration_in_seconds);
39
-
40
- void RunUntilIdle();
41
-
42
- private:
43
- std::vector<std::unique_ptr<cppgc::Task>> tasks_;
44
- std::vector<std::unique_ptr<cppgc::IdleTask>> idle_tasks_;
45
- };
46
-
47
- /**
48
- * Default platform implementation that uses std::thread for spawning job tasks.
49
- */
50
- class V8_EXPORT DefaultPlatform final : public Platform {
51
- public:
52
- DefaultPlatform();
53
- ~DefaultPlatform() noexcept override;
54
-
55
- cppgc::PageAllocator* GetPageAllocator() final;
56
-
57
- double MonotonicallyIncreasingTime() final;
58
-
59
- std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner() final;
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
+ using IdleTaskSupport = v8::platform::IdleTaskSupport;
33
+ explicit DefaultPlatform(
34
+ int thread_pool_size = 0,
35
+ IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
36
+ std::unique_ptr<TracingController> tracing_controller = {})
37
+ : v8_platform_(v8::platform::NewDefaultPlatform(
38
+ thread_pool_size, idle_task_support,
39
+ v8::platform::InProcessStackDumping::kDisabled,
40
+ std::move(tracing_controller))) {}
41
+
42
+ cppgc::PageAllocator* GetPageAllocator() override {
43
+ return v8_platform_->GetPageAllocator();
44
+ }
45
+
46
+ double MonotonicallyIncreasingTime() override {
47
+ return v8_platform_->MonotonicallyIncreasingTime();
48
+ }
49
+
50
+ std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner() override {
51
+ // V8's default platform creates a new task runner when passed the
52
+ // `v8::Isolate` pointer the first time. For non-default platforms this will
53
+ // require getting the appropriate task runner.
54
+ return v8_platform_->GetForegroundTaskRunner(kNoIsolate);
55
+ }
60
56
 
61
57
  std::unique_ptr<cppgc::JobHandle> PostJob(
62
58
  cppgc::TaskPriority priority,
63
- std::unique_ptr<cppgc::JobTask> job_task) final;
59
+ std::unique_ptr<cppgc::JobTask> job_task) override {
60
+ return v8_platform_->PostJob(priority, std::move(job_task));
61
+ }
62
+
63
+ TracingController* GetTracingController() override {
64
+ return v8_platform_->GetTracingController();
65
+ }
64
66
 
65
- void WaitAllForegroundTasks();
66
- void WaitAllBackgroundTasks();
67
+ protected:
68
+ static constexpr v8::Isolate* kNoIsolate = nullptr;
67
69
 
68
- private:
69
- std::unique_ptr<PageAllocator> page_allocator_;
70
- std::shared_ptr<DefaultTaskRunner> foreground_task_runner_;
71
- std::vector<std::shared_ptr<std::thread>> job_threads_;
70
+ std::unique_ptr<v8::Platform> v8_platform_;
72
71
  };
73
72
 
74
73
  } // namespace cppgc
@@ -0,0 +1,30 @@
1
+ // Copyright 2020 the V8 project authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ #ifndef INCLUDE_CPPGC_EPHEMERON_PAIR_H_
6
+ #define INCLUDE_CPPGC_EPHEMERON_PAIR_H_
7
+
8
+ #include "cppgc/liveness-broker.h"
9
+ #include "cppgc/member.h"
10
+
11
+ namespace cppgc {
12
+
13
+ /**
14
+ * An ephemeron pair is used to conditionally retain an object.
15
+ * The `value` will be kept alive only if the `key` is alive.
16
+ */
17
+ template <typename K, typename V>
18
+ struct EphemeronPair {
19
+ EphemeronPair(K* k, V* v) : key(k), value(v) {}
20
+ WeakMember<K> key;
21
+ Member<V> value;
22
+
23
+ void ClearValueIfKeyIsDead(const LivenessBroker& broker) {
24
+ if (!broker.IsHeapObjectAlive(key)) value = nullptr;
25
+ }
26
+ };
27
+
28
+ } // namespace cppgc
29
+
30
+ #endif // INCLUDE_CPPGC_EPHEMERON_PAIR_H_