libv8-node 20.2.0.0-x86_64-darwin → 21.7.2.0-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/libv8/node/version.rb +3 -3
- data/vendor/v8/include/cppgc/internal/api-constants.h +23 -4
- data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +16 -6
- data/vendor/v8/include/cppgc/internal/caged-heap.h +12 -5
- data/vendor/v8/include/cppgc/internal/gc-info.h +82 -91
- data/vendor/v8/include/cppgc/internal/member-storage.h +16 -8
- data/vendor/v8/include/cppgc/member.h +25 -0
- data/vendor/v8/include/cppgc/persistent.h +4 -0
- data/vendor/v8/include/cppgc/platform.h +6 -1
- data/vendor/v8/include/cppgc/sentinel-pointer.h +7 -0
- data/vendor/v8/include/cppgc/source-location.h +2 -78
- data/vendor/v8/include/cppgc/trace-trait.h +8 -0
- data/vendor/v8/include/cppgc/visitor.h +82 -4
- data/vendor/v8/include/libplatform/libplatform.h +7 -1
- data/vendor/v8/include/v8-callbacks.h +52 -8
- data/vendor/v8/include/v8-context.h +10 -13
- data/vendor/v8/include/v8-cppgc.h +5 -0
- data/vendor/v8/include/v8-embedder-heap.h +12 -0
- data/vendor/v8/include/v8-fast-api-calls.h +23 -5
- data/vendor/v8/include/v8-function-callback.h +11 -15
- data/vendor/v8/include/v8-function.h +6 -0
- data/vendor/v8/include/v8-handle-base.h +185 -0
- data/vendor/v8/include/v8-inspector.h +31 -1
- data/vendor/v8/include/v8-internal.h +109 -77
- data/vendor/v8/include/v8-isolate.h +130 -89
- data/vendor/v8/include/v8-local-handle.h +134 -89
- data/vendor/v8/include/v8-object.h +71 -52
- data/vendor/v8/include/v8-persistent-handle.h +65 -89
- data/vendor/v8/include/v8-platform.h +140 -9
- data/vendor/v8/include/v8-primitive.h +12 -8
- data/vendor/v8/include/v8-profiler.h +26 -2
- data/vendor/v8/include/v8-script.h +30 -7
- data/vendor/v8/include/v8-snapshot.h +4 -1
- data/vendor/v8/include/v8-source-location.h +92 -0
- data/vendor/v8/include/v8-statistics.h +36 -1
- data/vendor/v8/include/v8-traced-handle.h +37 -54
- data/vendor/v8/include/v8-unwinder.h +1 -1
- data/vendor/v8/include/v8-util.h +15 -13
- data/vendor/v8/include/v8-value-serializer.h +14 -0
- data/vendor/v8/include/v8-value.h +14 -0
- data/vendor/v8/include/v8-version.h +3 -3
- data/vendor/v8/include/v8config.h +19 -10
- data/vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a +0 -0
- metadata +5 -3
@@ -0,0 +1,185 @@
|
|
1
|
+
// Copyright 2023 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_V8_HANDLE_BASE_H_
|
6
|
+
#define INCLUDE_V8_HANDLE_BASE_H_
|
7
|
+
|
8
|
+
#include "v8-internal.h" // NOLINT(build/include_directory)
|
9
|
+
|
10
|
+
namespace v8 {
|
11
|
+
|
12
|
+
namespace internal {
|
13
|
+
|
14
|
+
// Helper functions about values contained in handles.
|
15
|
+
// A value is either an indirect pointer or a direct pointer, depending on
|
16
|
+
// whether direct local support is enabled.
|
17
|
+
class ValueHelper final {
|
18
|
+
public:
|
19
|
+
#ifdef V8_ENABLE_DIRECT_LOCAL
|
20
|
+
static constexpr Address kTaggedNullAddress = 1;
|
21
|
+
static constexpr Address kEmpty = kTaggedNullAddress;
|
22
|
+
#else
|
23
|
+
static constexpr Address kEmpty = kNullAddress;
|
24
|
+
#endif // V8_ENABLE_DIRECT_LOCAL
|
25
|
+
|
26
|
+
template <typename T>
|
27
|
+
V8_INLINE static bool IsEmpty(T* value) {
|
28
|
+
return reinterpret_cast<Address>(value) == kEmpty;
|
29
|
+
}
|
30
|
+
|
31
|
+
// Returns a handle's "value" for all kinds of abstract handles. For Local,
|
32
|
+
// it is equivalent to `*handle`. The variadic parameters support handle
|
33
|
+
// types with extra type parameters, like `Persistent<T, M>`.
|
34
|
+
template <template <typename T, typename... Ms> typename H, typename T,
|
35
|
+
typename... Ms>
|
36
|
+
V8_INLINE static T* HandleAsValue(const H<T, Ms...>& handle) {
|
37
|
+
return handle.template value<T>();
|
38
|
+
}
|
39
|
+
|
40
|
+
#ifdef V8_ENABLE_DIRECT_LOCAL
|
41
|
+
|
42
|
+
template <typename T>
|
43
|
+
V8_INLINE static Address ValueAsAddress(const T* value) {
|
44
|
+
return reinterpret_cast<Address>(value);
|
45
|
+
}
|
46
|
+
|
47
|
+
template <typename T, bool check_null = true, typename S>
|
48
|
+
V8_INLINE static T* SlotAsValue(S* slot) {
|
49
|
+
if (check_null && slot == nullptr) {
|
50
|
+
return reinterpret_cast<T*>(kTaggedNullAddress);
|
51
|
+
}
|
52
|
+
return *reinterpret_cast<T**>(slot);
|
53
|
+
}
|
54
|
+
|
55
|
+
#else // !V8_ENABLE_DIRECT_LOCAL
|
56
|
+
|
57
|
+
template <typename T>
|
58
|
+
V8_INLINE static Address ValueAsAddress(const T* value) {
|
59
|
+
return *reinterpret_cast<const Address*>(value);
|
60
|
+
}
|
61
|
+
|
62
|
+
template <typename T, bool check_null = true, typename S>
|
63
|
+
V8_INLINE static T* SlotAsValue(S* slot) {
|
64
|
+
return reinterpret_cast<T*>(slot);
|
65
|
+
}
|
66
|
+
|
67
|
+
#endif // V8_ENABLE_DIRECT_LOCAL
|
68
|
+
};
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Helper functions about handles.
|
72
|
+
*/
|
73
|
+
class HandleHelper final {
|
74
|
+
public:
|
75
|
+
/**
|
76
|
+
* Checks whether two handles are equal.
|
77
|
+
* They are equal iff they are both empty or they are both non-empty and the
|
78
|
+
* objects to which they refer are physically equal.
|
79
|
+
*
|
80
|
+
* If both handles refer to JS objects, this is the same as strict equality.
|
81
|
+
* For primitives, such as numbers or strings, a `false` return value does not
|
82
|
+
* indicate that the values aren't equal in the JavaScript sense.
|
83
|
+
* Use `Value::StrictEquals()` to check primitives for equality.
|
84
|
+
*/
|
85
|
+
template <typename T1, typename T2>
|
86
|
+
V8_INLINE static bool EqualHandles(const T1& lhs, const T2& rhs) {
|
87
|
+
if (lhs.IsEmpty()) return rhs.IsEmpty();
|
88
|
+
if (rhs.IsEmpty()) return false;
|
89
|
+
return lhs.ptr() == rhs.ptr();
|
90
|
+
}
|
91
|
+
|
92
|
+
static V8_EXPORT void VerifyOnStack(const void* ptr);
|
93
|
+
};
|
94
|
+
|
95
|
+
} // namespace internal
|
96
|
+
|
97
|
+
/**
|
98
|
+
* A base class for abstract handles containing indirect pointers.
|
99
|
+
* These are useful regardless of whether direct local support is enabled.
|
100
|
+
*/
|
101
|
+
class IndirectHandleBase {
|
102
|
+
public:
|
103
|
+
// Returns true if the handle is empty.
|
104
|
+
V8_INLINE bool IsEmpty() const { return location_ == nullptr; }
|
105
|
+
|
106
|
+
// Sets the handle to be empty. IsEmpty() will then return true.
|
107
|
+
V8_INLINE void Clear() { location_ = nullptr; }
|
108
|
+
|
109
|
+
protected:
|
110
|
+
friend class internal::ValueHelper;
|
111
|
+
friend class internal::HandleHelper;
|
112
|
+
|
113
|
+
V8_INLINE IndirectHandleBase() = default;
|
114
|
+
V8_INLINE IndirectHandleBase(const IndirectHandleBase& other) = default;
|
115
|
+
V8_INLINE IndirectHandleBase& operator=(const IndirectHandleBase& that) =
|
116
|
+
default;
|
117
|
+
|
118
|
+
V8_INLINE explicit IndirectHandleBase(internal::Address* location)
|
119
|
+
: location_(location) {}
|
120
|
+
|
121
|
+
// Returns the address of the actual heap object (tagged).
|
122
|
+
// This method must be called only if the handle is not empty, otherwise it
|
123
|
+
// will crash.
|
124
|
+
V8_INLINE internal::Address ptr() const { return *location_; }
|
125
|
+
|
126
|
+
// Returns a reference to the slot (indirect pointer).
|
127
|
+
V8_INLINE internal::Address* const& slot() const { return location_; }
|
128
|
+
V8_INLINE internal::Address*& slot() { return location_; }
|
129
|
+
|
130
|
+
// Returns the handler's "value" (direct or indirect pointer, depending on
|
131
|
+
// whether direct local support is enabled).
|
132
|
+
template <typename T>
|
133
|
+
V8_INLINE T* value() const {
|
134
|
+
return internal::ValueHelper::SlotAsValue<T, false>(slot());
|
135
|
+
}
|
136
|
+
|
137
|
+
private:
|
138
|
+
internal::Address* location_ = nullptr;
|
139
|
+
};
|
140
|
+
|
141
|
+
#ifdef V8_ENABLE_DIRECT_LOCAL
|
142
|
+
|
143
|
+
/**
|
144
|
+
* A base class for abstract handles containing direct pointers.
|
145
|
+
* These are only possible when conservative stack scanning is enabled.
|
146
|
+
*/
|
147
|
+
class DirectHandleBase {
|
148
|
+
public:
|
149
|
+
// Returns true if the handle is empty.
|
150
|
+
V8_INLINE bool IsEmpty() const {
|
151
|
+
return ptr_ == internal::ValueHelper::kEmpty;
|
152
|
+
}
|
153
|
+
|
154
|
+
// Sets the handle to be empty. IsEmpty() will then return true.
|
155
|
+
V8_INLINE void Clear() { ptr_ = internal::ValueHelper::kEmpty; }
|
156
|
+
|
157
|
+
protected:
|
158
|
+
friend class internal::ValueHelper;
|
159
|
+
friend class internal::HandleHelper;
|
160
|
+
|
161
|
+
V8_INLINE DirectHandleBase() = default;
|
162
|
+
V8_INLINE DirectHandleBase(const DirectHandleBase& other) = default;
|
163
|
+
V8_INLINE DirectHandleBase& operator=(const DirectHandleBase& that) = default;
|
164
|
+
|
165
|
+
V8_INLINE explicit DirectHandleBase(internal::Address ptr) : ptr_(ptr) {}
|
166
|
+
|
167
|
+
// Returns the address of the referenced object.
|
168
|
+
V8_INLINE internal::Address ptr() const { return ptr_; }
|
169
|
+
|
170
|
+
// Returns the handler's "value" (direct pointer, as direct local support
|
171
|
+
// is guaranteed to be enabled here).
|
172
|
+
template <typename T>
|
173
|
+
V8_INLINE T* value() const {
|
174
|
+
return reinterpret_cast<T*>(ptr_);
|
175
|
+
}
|
176
|
+
|
177
|
+
private:
|
178
|
+
internal::Address ptr_ = internal::ValueHelper::kEmpty;
|
179
|
+
};
|
180
|
+
|
181
|
+
#endif // V8_ENABLE_DIRECT_LOCAL
|
182
|
+
|
183
|
+
} // namespace v8
|
184
|
+
|
185
|
+
#endif // INCLUDE_V8_HANDLE_BASE_H_
|
@@ -217,6 +217,8 @@ class V8_EXPORT V8InspectorSession {
|
|
217
217
|
virtual void stop() = 0;
|
218
218
|
};
|
219
219
|
|
220
|
+
// Deprecated.
|
221
|
+
// TODO(crbug.com/1420968): remove.
|
220
222
|
class V8_EXPORT WebDriverValue {
|
221
223
|
public:
|
222
224
|
explicit WebDriverValue(std::unique_ptr<StringBuffer> type,
|
@@ -226,6 +228,27 @@ class V8_EXPORT WebDriverValue {
|
|
226
228
|
v8::MaybeLocal<v8::Value> value;
|
227
229
|
};
|
228
230
|
|
231
|
+
struct V8_EXPORT DeepSerializedValue {
|
232
|
+
explicit DeepSerializedValue(std::unique_ptr<StringBuffer> type,
|
233
|
+
v8::MaybeLocal<v8::Value> value = {})
|
234
|
+
: type(std::move(type)), value(value) {}
|
235
|
+
std::unique_ptr<StringBuffer> type;
|
236
|
+
v8::MaybeLocal<v8::Value> value;
|
237
|
+
};
|
238
|
+
|
239
|
+
struct V8_EXPORT DeepSerializationResult {
|
240
|
+
explicit DeepSerializationResult(
|
241
|
+
std::unique_ptr<DeepSerializedValue> serializedValue)
|
242
|
+
: serializedValue(std::move(serializedValue)), isSuccess(true) {}
|
243
|
+
explicit DeepSerializationResult(std::unique_ptr<StringBuffer> errorMessage)
|
244
|
+
: errorMessage(std::move(errorMessage)), isSuccess(false) {}
|
245
|
+
|
246
|
+
// Use std::variant when available.
|
247
|
+
std::unique_ptr<DeepSerializedValue> serializedValue;
|
248
|
+
std::unique_ptr<StringBuffer> errorMessage;
|
249
|
+
bool isSuccess;
|
250
|
+
};
|
251
|
+
|
229
252
|
class V8_EXPORT V8InspectorClient {
|
230
253
|
public:
|
231
254
|
virtual ~V8InspectorClient() = default;
|
@@ -243,8 +266,15 @@ class V8_EXPORT V8InspectorClient {
|
|
243
266
|
virtual void beginUserGesture() {}
|
244
267
|
virtual void endUserGesture() {}
|
245
268
|
|
269
|
+
// Deprecated. Use `deepSerialize` instead.
|
270
|
+
// TODO(crbug.com/1420968): remove.
|
246
271
|
virtual std::unique_ptr<WebDriverValue> serializeToWebDriverValue(
|
247
|
-
v8::Local<v8::Value>
|
272
|
+
v8::Local<v8::Value> v8Value, int maxDepth) {
|
273
|
+
return nullptr;
|
274
|
+
}
|
275
|
+
virtual std::unique_ptr<DeepSerializationResult> deepSerialize(
|
276
|
+
v8::Local<v8::Value> v8Value, int maxDepth,
|
277
|
+
v8::Local<v8::Object> additionalParameters) {
|
248
278
|
return nullptr;
|
249
279
|
}
|
250
280
|
virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) {
|
@@ -12,7 +12,6 @@
|
|
12
12
|
#include <atomic>
|
13
13
|
#include <type_traits>
|
14
14
|
|
15
|
-
#include "v8-version.h" // NOLINT(build/include_directory)
|
16
15
|
#include "v8config.h" // NOLINT(build/include_directory)
|
17
16
|
|
18
17
|
namespace v8 {
|
@@ -80,7 +79,7 @@ struct SmiTagging<4> {
|
|
80
79
|
static_cast<intptr_t>(kUintptrAllBitsSet << (kSmiValueSize - 1));
|
81
80
|
static constexpr intptr_t kSmiMaxValue = -(kSmiMinValue + 1);
|
82
81
|
|
83
|
-
V8_INLINE static int SmiToInt(Address value) {
|
82
|
+
V8_INLINE static constexpr int SmiToInt(Address value) {
|
84
83
|
int shift_bits = kSmiTagSize + kSmiShiftSize;
|
85
84
|
// Truncate and shift down (requires >> to be sign extending).
|
86
85
|
return static_cast<int32_t>(static_cast<uint32_t>(value)) >> shift_bits;
|
@@ -105,7 +104,7 @@ struct SmiTagging<8> {
|
|
105
104
|
static_cast<intptr_t>(kUintptrAllBitsSet << (kSmiValueSize - 1));
|
106
105
|
static constexpr intptr_t kSmiMaxValue = -(kSmiMinValue + 1);
|
107
106
|
|
108
|
-
V8_INLINE static int SmiToInt(Address value) {
|
107
|
+
V8_INLINE static constexpr int SmiToInt(Address value) {
|
109
108
|
int shift_bits = kSmiTagSize + kSmiShiftSize;
|
110
109
|
// Shift down and throw away top 32 bits.
|
111
110
|
return static_cast<int>(static_cast<intptr_t>(value) >> shift_bits);
|
@@ -247,20 +246,22 @@ static_assert(1ULL << (64 - kBoundedSizeShift) ==
|
|
247
246
|
// size allows omitting bounds checks on table accesses if the indices are
|
248
247
|
// guaranteed (e.g. through shifting) to be below the maximum index. This
|
249
248
|
// value must be a power of two.
|
250
|
-
|
249
|
+
constexpr size_t kExternalPointerTableReservationSize = 512 * MB;
|
251
250
|
|
252
251
|
// The external pointer table indices stored in HeapObjects as external
|
253
252
|
// pointers are shifted to the left by this amount to guarantee that they are
|
254
253
|
// smaller than the maximum table size.
|
255
|
-
|
254
|
+
constexpr uint32_t kExternalPointerIndexShift = 6;
|
256
255
|
#else
|
257
|
-
|
258
|
-
|
256
|
+
constexpr size_t kExternalPointerTableReservationSize = 1024 * MB;
|
257
|
+
constexpr uint32_t kExternalPointerIndexShift = 5;
|
259
258
|
#endif // V8_TARGET_OS_ANDROID
|
260
259
|
|
261
260
|
// The maximum number of entries in an external pointer table.
|
262
|
-
|
263
|
-
|
261
|
+
constexpr int kExternalPointerTableEntrySize = 8;
|
262
|
+
constexpr int kExternalPointerTableEntrySizeLog2 = 3;
|
263
|
+
constexpr size_t kMaxExternalPointers =
|
264
|
+
kExternalPointerTableReservationSize / kExternalPointerTableEntrySize;
|
264
265
|
static_assert((1 << (32 - kExternalPointerIndexShift)) == kMaxExternalPointers,
|
265
266
|
"kExternalPointerTableReservationSize and "
|
266
267
|
"kExternalPointerIndexShift don't match");
|
@@ -268,7 +269,7 @@ static_assert((1 << (32 - kExternalPointerIndexShift)) == kMaxExternalPointers,
|
|
268
269
|
#else // !V8_COMPRESS_POINTERS
|
269
270
|
|
270
271
|
// Needed for the V8.SandboxedExternalPointersCount histogram.
|
271
|
-
|
272
|
+
constexpr size_t kMaxExternalPointers = 0;
|
272
273
|
|
273
274
|
#endif // V8_COMPRESS_POINTERS
|
274
275
|
|
@@ -281,15 +282,21 @@ static const size_t kMaxExternalPointers = 0;
|
|
281
282
|
// that it is smaller than the size of the table.
|
282
283
|
using ExternalPointerHandle = uint32_t;
|
283
284
|
|
284
|
-
// ExternalPointers point to objects located outside the sandbox. When
|
285
|
-
//
|
286
|
-
//
|
285
|
+
// ExternalPointers point to objects located outside the sandbox. When the V8
|
286
|
+
// sandbox is enabled, these are stored on heap as ExternalPointerHandles,
|
287
|
+
// otherwise they are simply raw pointers.
|
287
288
|
#ifdef V8_ENABLE_SANDBOX
|
288
289
|
using ExternalPointer_t = ExternalPointerHandle;
|
289
290
|
#else
|
290
291
|
using ExternalPointer_t = Address;
|
291
292
|
#endif
|
292
293
|
|
294
|
+
constexpr ExternalPointer_t kNullExternalPointer = 0;
|
295
|
+
constexpr ExternalPointerHandle kNullExternalPointerHandle = 0;
|
296
|
+
|
297
|
+
//
|
298
|
+
// External Pointers.
|
299
|
+
//
|
293
300
|
// When the sandbox is enabled, external pointers are stored in an external
|
294
301
|
// pointer table and are referenced from HeapObjects through an index (a
|
295
302
|
// "handle"). When stored in the table, the pointers are tagged with per-type
|
@@ -359,6 +366,7 @@ using ExternalPointer_t = Address;
|
|
359
366
|
// ExternalPointerTable.
|
360
367
|
constexpr uint64_t kExternalPointerMarkBit = 1ULL << 62;
|
361
368
|
constexpr uint64_t kExternalPointerTagMask = 0x40ff000000000000;
|
369
|
+
constexpr uint64_t kExternalPointerTagMaskWithoutMarkBit = 0xff000000000000;
|
362
370
|
constexpr uint64_t kExternalPointerTagShift = 48;
|
363
371
|
|
364
372
|
// All possible 8-bit type tags.
|
@@ -417,7 +425,8 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
|
|
417
425
|
V(kWasmTypeInfoNativeTypeTag, TAG(18)) \
|
418
426
|
V(kWasmExportedFunctionDataSignatureTag, TAG(19)) \
|
419
427
|
V(kWasmContinuationJmpbufTag, TAG(20)) \
|
420
|
-
V(
|
428
|
+
V(kWasmIndirectFunctionTargetTag, TAG(21)) \
|
429
|
+
V(kArrayBufferExtensionTag, TAG(22))
|
421
430
|
|
422
431
|
// All external pointer tags.
|
423
432
|
#define ALL_EXTERNAL_POINTER_TAGS(V) \
|
@@ -430,7 +439,7 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
|
|
430
439
|
(HasMarkBit ? kExternalPointerMarkBit : 0))
|
431
440
|
enum ExternalPointerTag : uint64_t {
|
432
441
|
// Empty tag value. Mostly used as placeholder.
|
433
|
-
kExternalPointerNullTag = MAKE_TAG(
|
442
|
+
kExternalPointerNullTag = MAKE_TAG(1, 0b00000000),
|
434
443
|
// External pointer tag that will match any external pointer. Use with care!
|
435
444
|
kAnyExternalPointerTag = MAKE_TAG(1, 0b11111111),
|
436
445
|
// The free entry tag has all type bits set so every type check with a
|
@@ -471,6 +480,74 @@ PER_ISOLATE_EXTERNAL_POINTER_TAGS(CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS)
|
|
471
480
|
#undef SHARED_EXTERNAL_POINTER_TAGS
|
472
481
|
#undef EXTERNAL_POINTER_TAGS
|
473
482
|
|
483
|
+
//
|
484
|
+
// Indirect Pointers.
|
485
|
+
//
|
486
|
+
// When the sandbox is enabled, indirect pointers are used to reference
|
487
|
+
// HeapObjects that live outside of the sandbox (but are still managed through
|
488
|
+
// the GC). When object A references an object B through an indirect pointer,
|
489
|
+
// object A will contain a IndirectPointerHandle, i.e. a shifted 32-bit index,
|
490
|
+
// which identifies an entry in a pointer table (such as the CodePointerTable).
|
491
|
+
// This table entry then contains the actual pointer to object B. Further,
|
492
|
+
// object B owns this pointer table entry, and it is responsible for updating
|
493
|
+
// the "self-pointer" in the entry when it is relocated in memory. This way, in
|
494
|
+
// contrast to "normal" pointers, indirect pointers never need to be tracked by
|
495
|
+
// the GC (i.e. there is no remembered set for them).
|
496
|
+
// Currently there is only one type of object referenced through indirect
|
497
|
+
// pointers (Code objects), but once there are different types of such objects,
|
498
|
+
// the pointer table entry would probably also contain the type of the target
|
499
|
+
// object (e.g. by XORing the instance type into the top bits of the pointer).
|
500
|
+
|
501
|
+
// An IndirectPointerHandle represents a 32-bit index into a pointer table.
|
502
|
+
using IndirectPointerHandle = uint32_t;
|
503
|
+
|
504
|
+
// The indirect pointer handles are stores shifted to the left by this amount
|
505
|
+
// to guarantee that they are smaller than the maximum table size.
|
506
|
+
constexpr uint32_t kIndirectPointerHandleShift = 6;
|
507
|
+
|
508
|
+
// A null handle always references an entry that contains nullptr.
|
509
|
+
constexpr IndirectPointerHandle kNullIndirectPointerHandle = 0;
|
510
|
+
|
511
|
+
// Currently only Code objects can be referenced through indirect pointers and
|
512
|
+
// various places rely on that assumption. They will all static_assert against
|
513
|
+
// this constant to make them easy to find and fix once we reference other types
|
514
|
+
// of objects indirectly.
|
515
|
+
constexpr bool kAllIndirectPointerObjectsAreCode = true;
|
516
|
+
|
517
|
+
//
|
518
|
+
// Code Pointers.
|
519
|
+
//
|
520
|
+
// When the sandbox is enabled, Code objects are referenced from inside the
|
521
|
+
// sandbox through indirect pointers that reference entries in the code pointer
|
522
|
+
// table (CPT). Each entry in the CPT contains both a pointer to a Code object
|
523
|
+
// as well as a pointer to the Code's entrypoint. This allows calling/jumping
|
524
|
+
// into Code with one fewer memory access (compared to the case where the
|
525
|
+
// entrypoint pointer needs to be loaded from the Code object).
|
526
|
+
// As such, a CodePointerHandle can be used both to obtain the referenced Code
|
527
|
+
// object and to directly load its entrypoint pointer.
|
528
|
+
using CodePointerHandle = IndirectPointerHandle;
|
529
|
+
constexpr uint32_t kCodePointerHandleShift = kIndirectPointerHandleShift;
|
530
|
+
constexpr CodePointerHandle kNullCodePointerHandle = 0;
|
531
|
+
|
532
|
+
// The size of the virtual memory reservation for code pointer table.
|
533
|
+
// This determines the maximum number of entries in a table. Using a maximum
|
534
|
+
// size allows omitting bounds checks on table accesses if the indices are
|
535
|
+
// guaranteed (e.g. through shifting) to be below the maximum index. This
|
536
|
+
// value must be a power of two.
|
537
|
+
constexpr size_t kCodePointerTableReservationSize = 1 * GB;
|
538
|
+
|
539
|
+
// The maximum number of entries in an external pointer table.
|
540
|
+
constexpr int kCodePointerTableEntrySize = 16;
|
541
|
+
constexpr int kCodePointerTableEntrySizeLog2 = 4;
|
542
|
+
constexpr size_t kMaxCodePointers =
|
543
|
+
kCodePointerTableReservationSize / kCodePointerTableEntrySize;
|
544
|
+
static_assert(
|
545
|
+
(1 << (32 - kIndirectPointerHandleShift)) == kMaxCodePointers,
|
546
|
+
"kCodePointerTableReservationSize and kCodePointerHandleShift don't match");
|
547
|
+
|
548
|
+
constexpr int kCodePointerTableEntryEntrypointOffset = 0;
|
549
|
+
constexpr int kCodePointerTableEntryCodeObjectOffset = 8;
|
550
|
+
|
474
551
|
// {obj} must be the raw tagged pointer representation of a HeapObject
|
475
552
|
// that's guaranteed to never be in ReadOnlySpace.
|
476
553
|
V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject(Address obj);
|
@@ -517,15 +594,17 @@ class Internals {
|
|
517
594
|
static const int kExternalOneByteRepresentationTag = 0x0a;
|
518
595
|
|
519
596
|
static const uint32_t kNumIsolateDataSlots = 4;
|
520
|
-
static const int kStackGuardSize =
|
597
|
+
static const int kStackGuardSize = 8 * kApiSystemPointerSize;
|
521
598
|
static const int kBuiltinTier0EntryTableSize = 7 * kApiSystemPointerSize;
|
522
599
|
static const int kBuiltinTier0TableSize = 7 * kApiSystemPointerSize;
|
523
600
|
static const int kLinearAllocationAreaSize = 3 * kApiSystemPointerSize;
|
524
|
-
static const int kThreadLocalTopSize =
|
601
|
+
static const int kThreadLocalTopSize = 30 * kApiSystemPointerSize;
|
602
|
+
static const int kHandleScopeDataSize =
|
603
|
+
2 * kApiSystemPointerSize + 2 * kApiInt32Size;
|
525
604
|
|
526
605
|
// ExternalPointerTable layout guarantees.
|
527
|
-
static const int
|
528
|
-
static const int kExternalPointerTableSize =
|
606
|
+
static const int kExternalPointerTableBasePointerOffset = 0;
|
607
|
+
static const int kExternalPointerTableSize = 2 * kApiSystemPointerSize;
|
529
608
|
|
530
609
|
// IsolateData layout guarantees.
|
531
610
|
static const int kIsolateCageBaseOffset = 0;
|
@@ -551,19 +630,23 @@ class Internals {
|
|
551
630
|
kIsolateFastApiCallTargetOffset + kApiSystemPointerSize;
|
552
631
|
static const int kIsolateThreadLocalTopOffset =
|
553
632
|
kIsolateLongTaskStatsCounterOffset + kApiSizetSize;
|
554
|
-
static const int
|
633
|
+
static const int kIsolateHandleScopeDataOffset =
|
555
634
|
kIsolateThreadLocalTopOffset + kThreadLocalTopSize;
|
635
|
+
static const int kIsolateEmbedderDataOffset =
|
636
|
+
kIsolateHandleScopeDataOffset + kHandleScopeDataSize;
|
556
637
|
#ifdef V8_COMPRESS_POINTERS
|
557
638
|
static const int kIsolateExternalPointerTableOffset =
|
558
639
|
kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize;
|
559
640
|
static const int kIsolateSharedExternalPointerTableAddressOffset =
|
560
641
|
kIsolateExternalPointerTableOffset + kExternalPointerTableSize;
|
561
|
-
static const int
|
642
|
+
static const int kIsolateApiCallbackThunkArgumentOffset =
|
562
643
|
kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
|
563
644
|
#else
|
564
|
-
static const int
|
645
|
+
static const int kIsolateApiCallbackThunkArgumentOffset =
|
565
646
|
kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize;
|
566
647
|
#endif
|
648
|
+
static const int kIsolateRootsOffset =
|
649
|
+
kIsolateApiCallbackThunkArgumentOffset + kApiSystemPointerSize;
|
567
650
|
|
568
651
|
#if V8_STATIC_ROOTS_BOOL
|
569
652
|
|
@@ -641,11 +724,11 @@ class Internals {
|
|
641
724
|
#endif
|
642
725
|
}
|
643
726
|
|
644
|
-
V8_INLINE static bool HasHeapObjectTag(Address value) {
|
727
|
+
V8_INLINE static constexpr bool HasHeapObjectTag(Address value) {
|
645
728
|
return (value & kHeapObjectTagMask) == static_cast<Address>(kHeapObjectTag);
|
646
729
|
}
|
647
730
|
|
648
|
-
V8_INLINE static int SmiValue(Address value) {
|
731
|
+
V8_INLINE static constexpr int SmiValue(Address value) {
|
649
732
|
return PlatformSmiTagging::SmiToInt(value);
|
650
733
|
}
|
651
734
|
|
@@ -770,7 +853,7 @@ class Internals {
|
|
770
853
|
V8_INLINE static Address* GetExternalPointerTableBase(v8::Isolate* isolate) {
|
771
854
|
Address addr = reinterpret_cast<Address>(isolate) +
|
772
855
|
kIsolateExternalPointerTableOffset +
|
773
|
-
|
856
|
+
kExternalPointerTableBasePointerOffset;
|
774
857
|
return *reinterpret_cast<Address**>(addr);
|
775
858
|
}
|
776
859
|
|
@@ -779,7 +862,7 @@ class Internals {
|
|
779
862
|
Address addr = reinterpret_cast<Address>(isolate) +
|
780
863
|
kIsolateSharedExternalPointerTableAddressOffset;
|
781
864
|
addr = *reinterpret_cast<Address*>(addr);
|
782
|
-
addr +=
|
865
|
+
addr += kExternalPointerTableBasePointerOffset;
|
783
866
|
return *reinterpret_cast<Address**>(addr);
|
784
867
|
}
|
785
868
|
#endif
|
@@ -901,57 +984,6 @@ class BackingStoreBase {};
|
|
901
984
|
// This is needed for histograms sampling garbage collection reasons.
|
902
985
|
constexpr int kGarbageCollectionReasonMaxValue = 27;
|
903
986
|
|
904
|
-
// Helper functions about values contained in handles.
|
905
|
-
class ValueHelper final {
|
906
|
-
public:
|
907
|
-
#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
|
908
|
-
static constexpr Address kLocalTaggedNullAddress = 1;
|
909
|
-
|
910
|
-
template <typename T>
|
911
|
-
static constexpr T* EmptyValue() {
|
912
|
-
return reinterpret_cast<T*>(kLocalTaggedNullAddress);
|
913
|
-
}
|
914
|
-
|
915
|
-
template <typename T>
|
916
|
-
V8_INLINE static Address ValueAsAddress(const T* value) {
|
917
|
-
return reinterpret_cast<Address>(value);
|
918
|
-
}
|
919
|
-
|
920
|
-
template <typename T, typename S>
|
921
|
-
V8_INLINE static T* SlotAsValue(S* slot) {
|
922
|
-
return *reinterpret_cast<T**>(slot);
|
923
|
-
}
|
924
|
-
|
925
|
-
template <typename T>
|
926
|
-
V8_INLINE static T* ValueAsSlot(T* const& value) {
|
927
|
-
return reinterpret_cast<T*>(const_cast<T**>(&value));
|
928
|
-
}
|
929
|
-
|
930
|
-
#else // !V8_ENABLE_CONSERVATIVE_STACK_SCANNING
|
931
|
-
|
932
|
-
template <typename T>
|
933
|
-
static constexpr T* EmptyValue() {
|
934
|
-
return nullptr;
|
935
|
-
}
|
936
|
-
|
937
|
-
template <typename T>
|
938
|
-
V8_INLINE static Address ValueAsAddress(const T* value) {
|
939
|
-
return *reinterpret_cast<const Address*>(value);
|
940
|
-
}
|
941
|
-
|
942
|
-
template <typename T, typename S>
|
943
|
-
V8_INLINE static T* SlotAsValue(S* slot) {
|
944
|
-
return reinterpret_cast<T*>(slot);
|
945
|
-
}
|
946
|
-
|
947
|
-
template <typename T>
|
948
|
-
V8_INLINE static T* ValueAsSlot(T* const& value) {
|
949
|
-
return value;
|
950
|
-
}
|
951
|
-
|
952
|
-
#endif // V8_ENABLE_CONSERVATIVE_STACK_SCANNING
|
953
|
-
};
|
954
|
-
|
955
987
|
} // namespace internal
|
956
988
|
} // namespace v8
|
957
989
|
|