libv8-node 15.5.1.0.beta1-x86_64-linux-musl → 16.10.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.
- checksums.yaml +4 -4
- data/ext/libv8-node/.location.yml +0 -1
- data/ext/libv8-node/location.rb +23 -38
- data/ext/libv8-node/paths.rb +2 -2
- data/lib/libv8/node/version.rb +3 -3
- data/vendor/v8/include/cppgc/allocation.h +104 -45
- data/vendor/v8/include/cppgc/common.h +9 -6
- data/vendor/v8/include/cppgc/cross-thread-persistent.h +384 -0
- data/vendor/v8/include/cppgc/custom-space.h +37 -2
- data/vendor/v8/include/cppgc/default-platform.h +47 -48
- data/vendor/v8/include/cppgc/ephemeron-pair.h +30 -0
- data/vendor/v8/include/cppgc/explicit-management.h +82 -0
- data/vendor/v8/include/cppgc/garbage-collected.h +4 -3
- data/vendor/v8/include/cppgc/heap-consistency.h +236 -0
- data/vendor/v8/include/cppgc/heap-state.h +70 -0
- data/vendor/v8/include/cppgc/heap-statistics.h +120 -0
- data/vendor/v8/include/cppgc/heap.h +68 -6
- data/vendor/v8/include/cppgc/internal/api-constants.h +3 -3
- data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +2 -1
- data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
- data/vendor/v8/include/cppgc/internal/gc-info.h +44 -13
- data/vendor/v8/include/cppgc/internal/name-trait.h +111 -0
- data/vendor/v8/include/cppgc/internal/persistent-node.h +57 -1
- data/vendor/v8/include/cppgc/internal/pointer-policies.h +69 -28
- data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
- data/vendor/v8/include/cppgc/internal/write-barrier.h +353 -35
- data/vendor/v8/include/cppgc/liveness-broker.h +7 -1
- data/vendor/v8/include/cppgc/macros.h +2 -0
- data/vendor/v8/include/cppgc/member.h +85 -25
- data/vendor/v8/include/cppgc/name-provider.h +65 -0
- data/vendor/v8/include/cppgc/object-size-trait.h +58 -0
- data/vendor/v8/include/cppgc/persistent.h +33 -9
- data/vendor/v8/include/cppgc/platform.h +48 -25
- data/vendor/v8/include/cppgc/prefinalizer.h +1 -1
- data/vendor/v8/include/cppgc/process-heap-statistics.h +36 -0
- data/vendor/v8/include/cppgc/sentinel-pointer.h +32 -0
- data/vendor/v8/include/cppgc/source-location.h +2 -1
- data/vendor/v8/include/cppgc/testing.h +99 -0
- data/vendor/v8/include/cppgc/trace-trait.h +8 -3
- data/vendor/v8/include/cppgc/type-traits.h +157 -19
- data/vendor/v8/include/cppgc/visitor.h +187 -23
- data/vendor/v8/include/libplatform/libplatform.h +11 -0
- data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
- data/vendor/v8/include/v8-cppgc.h +258 -159
- data/vendor/v8/include/v8-fast-api-calls.h +562 -159
- data/vendor/v8/include/v8-inspector.h +23 -2
- data/vendor/v8/include/v8-internal.h +99 -27
- data/vendor/v8/include/v8-metrics.h +77 -8
- data/vendor/v8/include/v8-platform.h +47 -22
- data/vendor/v8/include/v8-profiler.h +75 -11
- data/vendor/v8/include/v8-unwinder-state.h +30 -0
- data/vendor/v8/include/v8-util.h +1 -1
- data/vendor/v8/include/v8-version.h +4 -4
- data/vendor/v8/include/v8.h +1192 -642
- data/vendor/v8/include/v8config.h +40 -9
- data/vendor/v8/{out.gn → x86_64-linux-musl}/libv8/obj/libv8_monolith.a +0 -0
- metadata +33 -7
- 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) && (®ion == &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) && (®ion == &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
|
-
*
|
19
|
-
*
|
18
|
+
* Platform provided by cppgc. Uses V8's DefaultPlatform provided by
|
19
|
+
* libplatform internally. Exception: `GetForegroundTaskRunner()`, see below.
|
20
20
|
*/
|
21
|
-
class V8_EXPORT
|
21
|
+
class V8_EXPORT DefaultPlatform : public Platform {
|
22
22
|
public:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
void
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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)
|
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
|
-
|
66
|
-
|
67
|
+
protected:
|
68
|
+
static constexpr v8::Isolate* kNoIsolate = nullptr;
|
67
69
|
|
68
|
-
|
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_
|