libv8-node 15.14.0.1-x86_64-linux-musl → 17.9.1.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.rb +1 -1
- data/ext/libv8-node/paths.rb +5 -1
- data/lib/libv8/node/version.rb +3 -3
- data/vendor/v8/include/cppgc/allocation.h +110 -44
- data/vendor/v8/include/cppgc/common.h +9 -6
- data/vendor/v8/include/cppgc/cross-thread-persistent.h +465 -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 +253 -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 +4 -3
- data/vendor/v8/include/cppgc/internal/compiler-specific.h +2 -2
- data/vendor/v8/include/cppgc/internal/finalizer-trait.h +2 -0
- data/vendor/v8/include/cppgc/internal/gc-info.h +124 -13
- data/vendor/v8/include/cppgc/internal/name-trait.h +122 -0
- data/vendor/v8/include/cppgc/internal/persistent-node.h +94 -6
- data/vendor/v8/include/cppgc/internal/pointer-policies.h +81 -29
- data/vendor/v8/include/cppgc/internal/prefinalizer-handler.h +1 -1
- data/vendor/v8/include/cppgc/internal/write-barrier.h +398 -35
- data/vendor/v8/include/cppgc/liveness-broker.h +11 -2
- data/vendor/v8/include/cppgc/macros.h +2 -0
- data/vendor/v8/include/cppgc/member.h +87 -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 +41 -11
- data/vendor/v8/include/cppgc/platform.h +49 -25
- data/vendor/v8/include/cppgc/prefinalizer.h +2 -2
- 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 +194 -28
- data/vendor/v8/include/libplatform/libplatform.h +11 -0
- data/vendor/v8/include/libplatform/v8-tracing.h +2 -0
- data/vendor/v8/include/v8-array-buffer.h +433 -0
- data/vendor/v8/include/v8-callbacks.h +377 -0
- data/vendor/v8/include/v8-container.h +129 -0
- data/vendor/v8/include/v8-context.h +418 -0
- data/vendor/v8/include/v8-cppgc.h +261 -159
- data/vendor/v8/include/v8-data.h +65 -0
- data/vendor/v8/include/v8-date.h +43 -0
- data/vendor/v8/include/v8-debug.h +151 -0
- data/vendor/v8/include/v8-embedder-heap.h +238 -0
- data/vendor/v8/include/v8-exception.h +224 -0
- data/vendor/v8/include/v8-extension.h +62 -0
- data/vendor/v8/include/v8-external.h +37 -0
- data/vendor/v8/include/v8-fast-api-calls.h +652 -152
- data/vendor/v8/include/v8-forward.h +81 -0
- data/vendor/v8/include/v8-function-callback.h +475 -0
- data/vendor/v8/include/v8-function.h +122 -0
- data/vendor/v8/include/v8-initialization.h +282 -0
- data/vendor/v8/include/v8-inspector.h +33 -25
- data/vendor/v8/include/v8-internal.h +178 -31
- data/vendor/v8/include/v8-isolate.h +1662 -0
- data/vendor/v8/include/v8-json.h +47 -0
- data/vendor/v8/include/v8-local-handle.h +459 -0
- data/vendor/v8/include/v8-locker.h +148 -0
- data/vendor/v8/include/v8-maybe.h +137 -0
- data/vendor/v8/include/v8-memory-span.h +43 -0
- data/vendor/v8/include/v8-message.h +241 -0
- data/vendor/v8/include/v8-metrics.h +114 -9
- data/vendor/v8/include/v8-microtask-queue.h +152 -0
- data/vendor/v8/include/v8-microtask.h +28 -0
- data/vendor/v8/include/v8-object.h +770 -0
- data/vendor/v8/include/v8-persistent-handle.h +590 -0
- data/vendor/v8/include/v8-platform.h +74 -25
- data/vendor/v8/include/v8-primitive-object.h +118 -0
- data/vendor/v8/include/v8-primitive.h +858 -0
- data/vendor/v8/include/v8-profiler.h +72 -9
- data/vendor/v8/include/v8-promise.h +174 -0
- data/vendor/v8/include/v8-proxy.h +50 -0
- data/vendor/v8/include/v8-regexp.h +105 -0
- data/vendor/v8/include/v8-script.h +771 -0
- data/vendor/v8/include/v8-snapshot.h +198 -0
- data/vendor/v8/include/v8-statistics.h +215 -0
- data/vendor/v8/include/v8-template.h +1052 -0
- data/vendor/v8/include/v8-traced-handle.h +605 -0
- data/vendor/v8/include/v8-typed-array.h +282 -0
- data/vendor/v8/include/v8-unwinder-state.h +31 -0
- data/vendor/v8/include/v8-unwinder.h +129 -0
- data/vendor/v8/include/v8-util.h +8 -2
- data/vendor/v8/include/v8-value-serializer.h +249 -0
- data/vendor/v8/include/v8-value.h +526 -0
- data/vendor/v8/include/v8-version.h +3 -3
- data/vendor/v8/include/v8-wasm.h +245 -0
- data/vendor/v8/include/v8-weak-callback-info.h +73 -0
- data/vendor/v8/include/v8.h +41 -12050
- data/vendor/v8/include/v8config.h +87 -11
- data/vendor/v8/{out.gn → x86_64-linux-musl}/libv8/obj/libv8_monolith.a +0 -0
- metadata +63 -9
- 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) && (®ion == &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) && (®ion == &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
|
-
*
|
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_
|