libv8-node 15.5.1.0.beta1-x86_64-darwin-19 → 16.10.0.0-x86_64-darwin-19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/.location.yml +0 -1
  3. data/ext/libv8-node/location.rb +23 -38
  4. data/ext/libv8-node/paths.rb +2 -2
  5. data/lib/libv8/node/version.rb +3 -3
  6. data/vendor/v8/include/cppgc/allocation.h +104 -45
  7. data/vendor/v8/include/cppgc/common.h +9 -6
  8. data/vendor/v8/include/cppgc/cross-thread-persistent.h +384 -0
  9. data/vendor/v8/include/cppgc/custom-space.h +37 -2
  10. data/vendor/v8/include/cppgc/default-platform.h +47 -48
  11. data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
  12. data/vendor/v8/include/cppgc/explicit-management.h +82 -0
  13. data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
  14. data/vendor/v8/include/cppgc/heap-consistency.h +236 -0
  15. data/vendor/v8/include/cppgc/heap-state.h +70 -0
  16. data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
  17. data/vendor/v8/include/cppgc/heap.h +68 -6
  18. data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
  19. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +2 -1
  20. data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
  21. data/vendor/v8/include/cppgc/internal/gc-info.h +44 -13
  22. data/vendor/v8/include/cppgc/internal/name-trait.h +111 -0
  23. data/vendor/v8/include/cppgc/internal/persistent-node.h +57 -1
  24. data/vendor/v8/include/cppgc/internal/pointer-policies.h +69 -28
  25. data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
  26. data/vendor/v8/include/cppgc/internal/write-barrier.h +353 -35
  27. data/vendor/v8/include/cppgc/liveness-broker.h +7 -1
  28. data/vendor/v8/include/cppgc/macros.h +2 -0
  29. data/vendor/v8/include/cppgc/member.h +85 -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 +33 -9
  33. data/vendor/v8/include/cppgc/platform.h +48 -25
  34. data/vendor/v8/include/cppgc/prefinalizer.h +1 -1
  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 +187 -23
  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-cppgc.h +258 -159
  45. data/vendor/v8/include/v8-fast-api-calls.h +562 -159
  46. data/vendor/v8/include/v8-inspector.h +23 -2
  47. data/vendor/v8/include/v8-internal.h +99 -27
  48. data/vendor/v8/include/v8-metrics.h +77 -8
  49. data/vendor/v8/include/v8-platform.h +47 -22
  50. data/vendor/v8/include/v8-profiler.h +75 -11
  51. data/vendor/v8/include/v8-unwinder-state.h +30 -0
  52. data/vendor/v8/include/v8-util.h +1 -1
  53. data/vendor/v8/include/v8-version.h +4 -4
  54. data/vendor/v8/include/v8.h +1192 -642
  55. data/vendor/v8/include/v8config.h +40 -9
  56. data/vendor/v8/{out.gn → x86_64-darwin-19}/libv8/obj/libv8_monolith.a +0 -0
  57. metadata +34 -8
  58. data/vendor/v8/include/cppgc/internal/process-heap.h +0 -34
@@ -0,0 +1,384 @@
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
+
17
+ namespace internal {
18
+
19
+ template <typename T, typename WeaknessPolicy, typename LocationPolicy,
20
+ typename CheckingPolicy>
21
+ class BasicCrossThreadPersistent final : public PersistentBase,
22
+ public LocationPolicy,
23
+ private WeaknessPolicy,
24
+ private CheckingPolicy {
25
+ public:
26
+ using typename WeaknessPolicy::IsStrongPersistent;
27
+ using PointeeType = T;
28
+
29
+ ~BasicCrossThreadPersistent() { Clear(); }
30
+
31
+ BasicCrossThreadPersistent(
32
+ const SourceLocation& loc = SourceLocation::Current())
33
+ : LocationPolicy(loc) {}
34
+
35
+ BasicCrossThreadPersistent(
36
+ std::nullptr_t, const SourceLocation& loc = SourceLocation::Current())
37
+ : LocationPolicy(loc) {}
38
+
39
+ BasicCrossThreadPersistent(
40
+ SentinelPointer s, const SourceLocation& loc = SourceLocation::Current())
41
+ : PersistentBase(s), LocationPolicy(loc) {}
42
+
43
+ BasicCrossThreadPersistent(
44
+ T* raw, const SourceLocation& loc = SourceLocation::Current())
45
+ : PersistentBase(raw), LocationPolicy(loc) {
46
+ if (!IsValid(raw)) return;
47
+ PersistentRegionLock guard;
48
+ CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
49
+ SetNode(region.AllocateNode(this, &Trace));
50
+ this->CheckPointer(raw);
51
+ }
52
+
53
+ class UnsafeCtorTag {
54
+ private:
55
+ UnsafeCtorTag() = default;
56
+ template <typename U, typename OtherWeaknessPolicy,
57
+ typename OtherLocationPolicy, typename OtherCheckingPolicy>
58
+ friend class BasicCrossThreadPersistent;
59
+ };
60
+
61
+ BasicCrossThreadPersistent(
62
+ UnsafeCtorTag, T* raw,
63
+ const SourceLocation& loc = SourceLocation::Current())
64
+ : PersistentBase(raw), LocationPolicy(loc) {
65
+ if (!IsValid(raw)) return;
66
+ CrossThreadPersistentRegion& region = this->GetPersistentRegion(raw);
67
+ SetNode(region.AllocateNode(this, &Trace));
68
+ this->CheckPointer(raw);
69
+ }
70
+
71
+ BasicCrossThreadPersistent(
72
+ T& raw, const SourceLocation& loc = SourceLocation::Current())
73
+ : BasicCrossThreadPersistent(&raw, loc) {}
74
+
75
+ template <typename U, typename MemberBarrierPolicy,
76
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
77
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
78
+ BasicCrossThreadPersistent(
79
+ internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
80
+ MemberCheckingPolicy>
81
+ member,
82
+ const SourceLocation& loc = SourceLocation::Current())
83
+ : BasicCrossThreadPersistent(member.Get(), loc) {}
84
+
85
+ BasicCrossThreadPersistent(
86
+ const BasicCrossThreadPersistent& other,
87
+ const SourceLocation& loc = SourceLocation::Current())
88
+ : BasicCrossThreadPersistent(loc) {
89
+ // Invoke operator=.
90
+ *this = other;
91
+ }
92
+
93
+ // Heterogeneous ctor.
94
+ template <typename U, typename OtherWeaknessPolicy,
95
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
96
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
97
+ BasicCrossThreadPersistent(
98
+ const BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
99
+ OtherLocationPolicy,
100
+ OtherCheckingPolicy>& other,
101
+ const SourceLocation& loc = SourceLocation::Current())
102
+ : BasicCrossThreadPersistent(loc) {
103
+ *this = other;
104
+ }
105
+
106
+ BasicCrossThreadPersistent(
107
+ BasicCrossThreadPersistent&& other,
108
+ const SourceLocation& loc = SourceLocation::Current()) noexcept {
109
+ // Invoke operator=.
110
+ *this = std::move(other);
111
+ }
112
+
113
+ BasicCrossThreadPersistent& operator=(
114
+ const BasicCrossThreadPersistent& other) {
115
+ PersistentRegionLock guard;
116
+ AssignUnsafe(other.Get());
117
+ return *this;
118
+ }
119
+
120
+ template <typename U, typename OtherWeaknessPolicy,
121
+ typename OtherLocationPolicy, typename OtherCheckingPolicy,
122
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
123
+ BasicCrossThreadPersistent& operator=(
124
+ const BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
125
+ OtherLocationPolicy,
126
+ OtherCheckingPolicy>& other) {
127
+ PersistentRegionLock guard;
128
+ AssignUnsafe(other.Get());
129
+ return *this;
130
+ }
131
+
132
+ BasicCrossThreadPersistent& operator=(BasicCrossThreadPersistent&& other) {
133
+ if (this == &other) return *this;
134
+ Clear();
135
+ PersistentRegionLock guard;
136
+ PersistentBase::operator=(std::move(other));
137
+ LocationPolicy::operator=(std::move(other));
138
+ if (!IsValid(GetValue())) return *this;
139
+ GetNode()->UpdateOwner(this);
140
+ other.SetValue(nullptr);
141
+ other.SetNode(nullptr);
142
+ this->CheckPointer(Get());
143
+ return *this;
144
+ }
145
+
146
+ BasicCrossThreadPersistent& operator=(T* other) {
147
+ Assign(other);
148
+ return *this;
149
+ }
150
+
151
+ // Assignment from member.
152
+ template <typename U, typename MemberBarrierPolicy,
153
+ typename MemberWeaknessTag, typename MemberCheckingPolicy,
154
+ typename = std::enable_if_t<std::is_base_of<T, U>::value>>
155
+ BasicCrossThreadPersistent& operator=(
156
+ internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
157
+ MemberCheckingPolicy>
158
+ member) {
159
+ return operator=(member.Get());
160
+ }
161
+
162
+ BasicCrossThreadPersistent& operator=(std::nullptr_t) {
163
+ Clear();
164
+ return *this;
165
+ }
166
+
167
+ BasicCrossThreadPersistent& operator=(SentinelPointer s) {
168
+ Assign(s);
169
+ return *this;
170
+ }
171
+
172
+ /**
173
+ * Returns a pointer to the stored object.
174
+ *
175
+ * Note: **Not thread-safe.**
176
+ *
177
+ * \returns a pointer to the stored object.
178
+ */
179
+ // CFI cast exemption to allow passing SentinelPointer through T* and support
180
+ // heterogeneous assignments between different Member and Persistent handles
181
+ // based on their actual types.
182
+ V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
183
+ return static_cast<T*>(const_cast<void*>(GetValue()));
184
+ }
185
+
186
+ /**
187
+ * Clears the stored object.
188
+ */
189
+ 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);
208
+ }
209
+
210
+ /**
211
+ * Returns a pointer to the stored object and releases it.
212
+ *
213
+ * Note: **Not thread-safe.**
214
+ *
215
+ * \returns a pointer to the stored object.
216
+ */
217
+ T* Release() {
218
+ T* result = Get();
219
+ Clear();
220
+ return result;
221
+ }
222
+
223
+ /**
224
+ * Conversio to boolean.
225
+ *
226
+ * Note: **Not thread-safe.**
227
+ *
228
+ * \returns true if an actual object has been stored and false otherwise.
229
+ */
230
+ explicit operator bool() const { return Get(); }
231
+
232
+ /**
233
+ * Conversion to object of type T.
234
+ *
235
+ * Note: **Not thread-safe.**
236
+ *
237
+ * \returns the object.
238
+ */
239
+ operator T*() const { return Get(); }
240
+
241
+ /**
242
+ * Dereferences the stored object.
243
+ *
244
+ * Note: **Not thread-safe.**
245
+ */
246
+ T* operator->() const { return Get(); }
247
+ T& operator*() const { return *Get(); }
248
+
249
+ template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy,
250
+ typename OtherLocationPolicy = LocationPolicy,
251
+ typename OtherCheckingPolicy = CheckingPolicy>
252
+ BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
253
+ OtherCheckingPolicy>
254
+ To() const {
255
+ using OtherBasicCrossThreadPersistent =
256
+ BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
257
+ OtherCheckingPolicy>;
258
+ PersistentRegionLock guard;
259
+ return OtherBasicCrossThreadPersistent(
260
+ typename OtherBasicCrossThreadPersistent::UnsafeCtorTag(),
261
+ static_cast<U*>(Get()));
262
+ }
263
+
264
+ template <typename U = T,
265
+ typename = typename std::enable_if<!BasicCrossThreadPersistent<
266
+ U, WeaknessPolicy>::IsStrongPersistent::value>::type>
267
+ BasicCrossThreadPersistent<U, internal::StrongCrossThreadPersistentPolicy>
268
+ Lock() const {
269
+ return BasicCrossThreadPersistent<
270
+ U, internal::StrongCrossThreadPersistentPolicy>(*this);
271
+ }
272
+
273
+ private:
274
+ static bool IsValid(const void* ptr) {
275
+ return ptr && ptr != kSentinelPointer;
276
+ }
277
+
278
+ static void Trace(Visitor* v, const void* ptr) {
279
+ const auto* handle = static_cast<const BasicCrossThreadPersistent*>(ptr);
280
+ v->TraceRoot(*handle, handle->Location());
281
+ }
282
+
283
+ void Assign(T* ptr) {
284
+ const void* old_value = GetValue();
285
+ if (IsValid(old_value)) {
286
+ PersistentRegionLock guard;
287
+ old_value = GetValue();
288
+ // The fast path check (IsValid()) does not acquire the lock. Reload
289
+ // the value to ensure the reference has not been cleared.
290
+ if (IsValid(old_value)) {
291
+ CrossThreadPersistentRegion& region =
292
+ this->GetPersistentRegion(old_value);
293
+ if (IsValid(ptr) && (&region == &this->GetPersistentRegion(ptr))) {
294
+ SetValue(ptr);
295
+ this->CheckPointer(ptr);
296
+ return;
297
+ }
298
+ region.FreeNode(GetNode());
299
+ SetNode(nullptr);
300
+ } else {
301
+ CPPGC_DCHECK(!GetNode());
302
+ }
303
+ }
304
+ SetValue(ptr);
305
+ if (!IsValid(ptr)) return;
306
+ PersistentRegionLock guard;
307
+ SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &Trace));
308
+ this->CheckPointer(ptr);
309
+ }
310
+
311
+ void AssignUnsafe(T* ptr) {
312
+ PersistentRegionLock::AssertLocked();
313
+ const void* old_value = GetValue();
314
+ if (IsValid(old_value)) {
315
+ CrossThreadPersistentRegion& region =
316
+ this->GetPersistentRegion(old_value);
317
+ if (IsValid(ptr) && (&region == &this->GetPersistentRegion(ptr))) {
318
+ SetValue(ptr);
319
+ this->CheckPointer(ptr);
320
+ return;
321
+ }
322
+ region.FreeNode(GetNode());
323
+ SetNode(nullptr);
324
+ }
325
+ SetValue(ptr);
326
+ if (!IsValid(ptr)) return;
327
+ SetNode(this->GetPersistentRegion(ptr).AllocateNode(this, &Trace));
328
+ this->CheckPointer(ptr);
329
+ }
330
+
331
+ void ClearFromGC() const {
332
+ if (IsValid(GetValue())) {
333
+ WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode());
334
+ PersistentBase::ClearFromGC();
335
+ }
336
+ }
337
+
338
+ friend class cppgc::Visitor;
339
+ };
340
+
341
+ template <typename T, typename LocationPolicy, typename CheckingPolicy>
342
+ struct IsWeak<
343
+ BasicCrossThreadPersistent<T, internal::WeakCrossThreadPersistentPolicy,
344
+ LocationPolicy, CheckingPolicy>>
345
+ : std::true_type {};
346
+
347
+ } // namespace internal
348
+
349
+ namespace subtle {
350
+
351
+ /**
352
+ * **DO NOT USE: Has known caveats, see below.**
353
+ *
354
+ * CrossThreadPersistent allows retaining objects from threads other than the
355
+ * thread the owning heap is operating on.
356
+ *
357
+ * Known caveats:
358
+ * - Does not protect the heap owning an object from terminating.
359
+ * - Reaching transitively through the graph is unsupported as objects may be
360
+ * moved concurrently on the thread owning the object.
361
+ */
362
+ template <typename T>
363
+ using CrossThreadPersistent = internal::BasicCrossThreadPersistent<
364
+ T, internal::StrongCrossThreadPersistentPolicy>;
365
+
366
+ /**
367
+ * **DO NOT USE: Has known caveats, see below.**
368
+ *
369
+ * CrossThreadPersistent allows weakly retaining objects from threads other than
370
+ * the thread the owning heap is operating on.
371
+ *
372
+ * Known caveats:
373
+ * - Does not protect the heap owning an object from terminating.
374
+ * - Reaching transitively through the graph is unsupported as objects may be
375
+ * moved concurrently on the thread owning the object.
376
+ */
377
+ template <typename T>
378
+ using WeakCrossThreadPersistent = internal::BasicCrossThreadPersistent<
379
+ T, internal::WeakCrossThreadPersistentPolicy>;
380
+
381
+ } // namespace subtle
382
+ } // namespace cppgc
383
+
384
+ #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_
@@ -0,0 +1,82 @@
1
+ // Copyright 2021 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_EXPLICIT_MANAGEMENT_H_
6
+ #define INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_
7
+
8
+ #include <cstddef>
9
+
10
+ #include "cppgc/allocation.h"
11
+ #include "cppgc/internal/logging.h"
12
+ #include "cppgc/type-traits.h"
13
+
14
+ namespace cppgc {
15
+
16
+ class HeapHandle;
17
+
18
+ namespace internal {
19
+
20
+ V8_EXPORT void FreeUnreferencedObject(HeapHandle&, void*);
21
+ V8_EXPORT bool Resize(void*, size_t);
22
+
23
+ } // namespace internal
24
+
25
+ namespace subtle {
26
+
27
+ /**
28
+ * Informs the garbage collector that `object` can be immediately reclaimed. The
29
+ * destructor may not be invoked immediately but only on next garbage
30
+ * collection.
31
+ *
32
+ * It is up to the embedder to guarantee that no other object holds a reference
33
+ * to `object` after calling `FreeUnreferencedObject()`. In case such a
34
+ * reference exists, it's use results in a use-after-free.
35
+ *
36
+ * To aid in using the API, `FreeUnreferencedObject()` may be called from
37
+ * destructors on objects that would be reclaimed in the same garbage collection
38
+ * cycle.
39
+ *
40
+ * \param heap_handle The corresponding heap.
41
+ * \param object Reference to an object that is of type `GarbageCollected` and
42
+ * should be immediately reclaimed.
43
+ */
44
+ template <typename T>
45
+ void FreeUnreferencedObject(HeapHandle& heap_handle, T& object) {
46
+ static_assert(IsGarbageCollectedTypeV<T>,
47
+ "Object must be of type GarbageCollected.");
48
+ internal::FreeUnreferencedObject(heap_handle, &object);
49
+ }
50
+
51
+ /**
52
+ * Tries to resize `object` of type `T` with additional bytes on top of
53
+ * sizeof(T). Resizing is only useful with trailing inlined storage, see e.g.
54
+ * `MakeGarbageCollected(AllocationHandle&, AdditionalBytes)`.
55
+ *
56
+ * `Resize()` performs growing or shrinking as needed and may skip the operation
57
+ * for internal reasons, see return value.
58
+ *
59
+ * It is up to the embedder to guarantee that in case of shrinking a larger
60
+ * object down, the reclaimed area is not used anymore. Any subsequent use
61
+ * results in a use-after-free.
62
+ *
63
+ * The `object` must be live when calling `Resize()`.
64
+ *
65
+ * \param object Reference to an object that is of type `GarbageCollected` and
66
+ * should be resized.
67
+ * \param additional_bytes Bytes in addition to sizeof(T) that the object should
68
+ * provide.
69
+ * \returns true when the operation was successful and the result can be relied
70
+ * on, and false otherwise.
71
+ */
72
+ template <typename T>
73
+ bool Resize(T& object, AdditionalBytes additional_bytes) {
74
+ static_assert(IsGarbageCollectedTypeV<T>,
75
+ "Object must be of type GarbageCollected.");
76
+ return internal::Resize(&object, sizeof(T) + additional_bytes.value);
77
+ }
78
+
79
+ } // namespace subtle
80
+ } // namespace cppgc
81
+
82
+ #endif // INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_