Loading...
Searching...
No Matches
v8-internal.h
Go to the documentation of this file.
1// Copyright 2018 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_INTERNAL_H_
6#define INCLUDE_V8_INTERNAL_H_
7
8#include <stddef.h>
9#include <stdint.h>
10#include <string.h>
11
12#include <atomic>
13#include <iterator>
14#include <memory>
15#include <type_traits>
16
17#include "v8config.h" // NOLINT(build/include_directory)
18
19namespace v8 {
20
21class Array;
22class Context;
23class Data;
24class Isolate;
25
26namespace internal {
27
28class Heap;
29class Isolate;
30
31typedef uintptr_t Address;
32static constexpr Address kNullAddress = 0;
33
34constexpr int KB = 1024;
35constexpr int MB = KB * 1024;
36constexpr int GB = MB * 1024;
37#ifdef V8_TARGET_ARCH_X64
38constexpr size_t TB = size_t{GB} * 1024;
39#endif
40
44const int kApiSystemPointerSize = sizeof(void*);
45const int kApiDoubleSize = sizeof(double);
46const int kApiInt32Size = sizeof(int32_t);
47const int kApiInt64Size = sizeof(int64_t);
48const int kApiSizetSize = sizeof(size_t);
49
50// Tag information for HeapObject.
51const int kHeapObjectTag = 1;
52const int kWeakHeapObjectTag = 3;
53const int kHeapObjectTagSize = 2;
54const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1;
56
57// Tag information for fowarding pointers stored in object headers.
58// 0b00 at the lowest 2 bits in the header indicates that the map word is a
59// forwarding pointer.
60const int kForwardingTag = 0;
61const int kForwardingTagSize = 2;
62const intptr_t kForwardingTagMask = (1 << kForwardingTagSize) - 1;
63
64// Tag information for Smi.
65const int kSmiTag = 0;
66const int kSmiTagSize = 1;
67const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1;
68
69template <size_t tagged_ptr_size>
71
72constexpr intptr_t kIntptrAllBitsSet = intptr_t{-1};
73constexpr uintptr_t kUintptrAllBitsSet =
74 static_cast<uintptr_t>(kIntptrAllBitsSet);
75
76// Smi constants for systems where tagged pointer is a 32-bit value.
77template <>
78struct SmiTagging<4> {
79 enum { kSmiShiftSize = 0, kSmiValueSize = 31 };
80
81 static constexpr intptr_t kSmiMinValue =
82 static_cast<intptr_t>(kUintptrAllBitsSet << (kSmiValueSize - 1));
83 static constexpr intptr_t kSmiMaxValue = -(kSmiMinValue + 1);
84
85 V8_INLINE static constexpr int SmiToInt(Address value) {
86 int shift_bits = kSmiTagSize + kSmiShiftSize;
87 // Truncate and shift down (requires >> to be sign extending).
88 return static_cast<int32_t>(static_cast<uint32_t>(value)) >> shift_bits;
89 }
90 V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
91 // Is value in range [kSmiMinValue, kSmiMaxValue].
92 // Use unsigned operations in order to avoid undefined behaviour in case of
93 // signed integer overflow.
94 return (static_cast<uintptr_t>(value) -
95 static_cast<uintptr_t>(kSmiMinValue)) <=
96 (static_cast<uintptr_t>(kSmiMaxValue) -
97 static_cast<uintptr_t>(kSmiMinValue));
98 }
99};
100
101// Smi constants for systems where tagged pointer is a 64-bit value.
102template <>
103struct SmiTagging<8> {
104 enum { kSmiShiftSize = 31, kSmiValueSize = 32 };
105
106 static constexpr intptr_t kSmiMinValue =
107 static_cast<intptr_t>(kUintptrAllBitsSet << (kSmiValueSize - 1));
108 static constexpr intptr_t kSmiMaxValue = -(kSmiMinValue + 1);
109
110 V8_INLINE static constexpr int SmiToInt(Address value) {
111 int shift_bits = kSmiTagSize + kSmiShiftSize;
112 // Shift down and throw away top 32 bits.
113 return static_cast<int>(static_cast<intptr_t>(value) >> shift_bits);
114 }
115 V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
116 // To be representable as a long smi, the value must be a 32-bit integer.
117 return (value == static_cast<int32_t>(value));
118 }
119};
120
121#ifdef V8_COMPRESS_POINTERS
122// See v8:7703 or src/common/ptr-compr-inl.h for details about pointer
123// compression.
124constexpr size_t kPtrComprCageReservationSize = size_t{1} << 32;
125constexpr size_t kPtrComprCageBaseAlignment = size_t{1} << 32;
126
127static_assert(
129 "Pointer compression can be enabled only for 64-bit architectures");
130const int kApiTaggedSize = kApiInt32Size;
131#else
133#endif
134
137}
138
139#ifdef V8_31BIT_SMIS_ON_64BIT_ARCH
140using PlatformSmiTagging = SmiTagging<kApiInt32Size>;
141#else
143#endif
144
145// TODO(ishell): Consinder adding kSmiShiftBits = kSmiShiftSize + kSmiTagSize
146// since it's used much more often than the inividual constants.
147const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize;
148const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize;
149const int kSmiMinValue = static_cast<int>(PlatformSmiTagging::kSmiMinValue);
150const int kSmiMaxValue = static_cast<int>(PlatformSmiTagging::kSmiMaxValue);
151constexpr bool SmiValuesAre31Bits() { return kSmiValueSize == 31; }
152constexpr bool SmiValuesAre32Bits() { return kSmiValueSize == 32; }
153constexpr bool Is64() { return kApiSystemPointerSize == sizeof(int64_t); }
154
155V8_INLINE static constexpr Address IntToSmi(int value) {
156 return (static_cast<Address>(value) << (kSmiTagSize + kSmiShiftSize)) |
157 kSmiTag;
158}
159
160/*
161 * Sandbox related types, constants, and functions.
162 */
163constexpr bool SandboxIsEnabled() {
164#ifdef V8_ENABLE_SANDBOX
165 return true;
166#else
167 return false;
168#endif
169}
170
171// SandboxedPointers are guaranteed to point into the sandbox. This is achieved
172// for example by storing them as offset rather than as raw pointers.
174
175#ifdef V8_ENABLE_SANDBOX
176
177// Size of the sandbox, excluding the guard regions surrounding it.
178#if defined(V8_TARGET_OS_ANDROID)
179// On Android, most 64-bit devices seem to be configured with only 39 bits of
180// virtual address space for userspace. As such, limit the sandbox to 128GB (a
181// quarter of the total available address space).
182constexpr size_t kSandboxSizeLog2 = 37; // 128 GB
183#elif defined(V8_TARGET_ARCH_LOONG64)
184// Some Linux distros on LoongArch64 configured with only 40 bits of virtual
185// address space for userspace. Limit the sandbox to 256GB here.
186constexpr size_t kSandboxSizeLog2 = 38; // 256 GB
187#else
188// Everywhere else use a 1TB sandbox.
189constexpr size_t kSandboxSizeLog2 = 40; // 1 TB
190#endif // V8_TARGET_OS_ANDROID
191constexpr size_t kSandboxSize = 1ULL << kSandboxSizeLog2;
192
193// Required alignment of the sandbox. For simplicity, we require the
194// size of the guard regions to be a multiple of this, so that this specifies
195// the alignment of the sandbox including and excluding surrounding guard
196// regions. The alignment requirement is due to the pointer compression cage
197// being located at the start of the sandbox.
198constexpr size_t kSandboxAlignment = kPtrComprCageBaseAlignment;
199
200// Sandboxed pointers are stored inside the heap as offset from the sandbox
201// base shifted to the left. This way, it is guaranteed that the offset is
202// smaller than the sandbox size after shifting it to the right again. This
203// constant specifies the shift amount.
204constexpr uint64_t kSandboxedPointerShift = 64 - kSandboxSizeLog2;
205
206// Size of the guard regions surrounding the sandbox. This assumes a worst-case
207// scenario of a 32-bit unsigned index used to access an array of 64-bit
208// values.
209constexpr size_t kSandboxGuardRegionSize = 32ULL * GB;
210
211static_assert((kSandboxGuardRegionSize % kSandboxAlignment) == 0,
212 "The size of the guard regions around the sandbox must be a "
213 "multiple of its required alignment.");
214
215// On OSes where reserving virtual memory is too expensive to reserve the
216// entire address space backing the sandbox, notably Windows pre 8.1, we create
217// a partially reserved sandbox that doesn't actually reserve most of the
218// memory, and so doesn't have the desired security properties as unrelated
219// memory allocations could end up inside of it, but which still ensures that
220// objects that should be located inside the sandbox are allocated within
221// kSandboxSize bytes from the start of the sandbox. The minimum size of the
222// region that is actually reserved for such a sandbox is specified by this
223// constant and should be big enough to contain the pointer compression cage as
224// well as the ArrayBuffer partition.
225constexpr size_t kSandboxMinimumReservationSize = 8ULL * GB;
226
227static_assert(kSandboxMinimumReservationSize > kPtrComprCageReservationSize,
228 "The minimum reservation size for a sandbox must be larger than "
229 "the pointer compression cage contained within it.");
230
231// The maximum buffer size allowed inside the sandbox. This is mostly dependent
232// on the size of the guard regions around the sandbox: an attacker must not be
233// able to construct a buffer that appears larger than the guard regions and
234// thereby "reach out of" the sandbox.
235constexpr size_t kMaxSafeBufferSizeForSandbox = 32ULL * GB - 1;
236static_assert(kMaxSafeBufferSizeForSandbox <= kSandboxGuardRegionSize,
237 "The maximum allowed buffer size must not be larger than the "
238 "sandbox's guard regions");
239
240constexpr size_t kBoundedSizeShift = 29;
241static_assert(1ULL << (64 - kBoundedSizeShift) ==
242 kMaxSafeBufferSizeForSandbox + 1,
243 "The maximum size of a BoundedSize must be synchronized with the "
244 "kMaxSafeBufferSizeForSandbox");
245
246#endif // V8_ENABLE_SANDBOX
247
248#ifdef V8_COMPRESS_POINTERS
249
250#ifdef V8_TARGET_OS_ANDROID
251// The size of the virtual memory reservation for an external pointer table.
252// This determines the maximum number of entries in a table. Using a maximum
253// size allows omitting bounds checks on table accesses if the indices are
254// guaranteed (e.g. through shifting) to be below the maximum index. This
255// value must be a power of two.
256constexpr size_t kExternalPointerTableReservationSize = 256 * MB;
257
258// The external pointer table indices stored in HeapObjects as external
259// pointers are shifted to the left by this amount to guarantee that they are
260// smaller than the maximum table size.
261constexpr uint32_t kExternalPointerIndexShift = 7;
262#else
263constexpr size_t kExternalPointerTableReservationSize = 512 * MB;
264constexpr uint32_t kExternalPointerIndexShift = 6;
265#endif // V8_TARGET_OS_ANDROID
266
267// The maximum number of entries in an external pointer table.
268constexpr int kExternalPointerTableEntrySize = 8;
269constexpr int kExternalPointerTableEntrySizeLog2 = 3;
270constexpr size_t kMaxExternalPointers =
271 kExternalPointerTableReservationSize / kExternalPointerTableEntrySize;
272static_assert((1 << (32 - kExternalPointerIndexShift)) == kMaxExternalPointers,
273 "kExternalPointerTableReservationSize and "
274 "kExternalPointerIndexShift don't match");
275
276#else // !V8_COMPRESS_POINTERS
277
278// Needed for the V8.SandboxedExternalPointersCount histogram.
279constexpr size_t kMaxExternalPointers = 0;
280
281#endif // V8_COMPRESS_POINTERS
282
283// A ExternalPointerHandle represents a (opaque) reference to an external
284// pointer that can be stored inside the sandbox. A ExternalPointerHandle has
285// meaning only in combination with an (active) Isolate as it references an
286// external pointer stored in the currently active Isolate's
287// ExternalPointerTable. Internally, an ExternalPointerHandles is simply an
288// index into an ExternalPointerTable that is shifted to the left to guarantee
289// that it is smaller than the size of the table.
290using ExternalPointerHandle = uint32_t;
291
292// ExternalPointers point to objects located outside the sandbox. When the V8
293// sandbox is enabled, these are stored on heap as ExternalPointerHandles,
294// otherwise they are simply raw pointers.
295#ifdef V8_ENABLE_SANDBOX
297#else
299#endif
300
303
304// See `ExternalPointerHandle` for the main documentation. The difference to
305// `ExternalPointerHandle` is that the handle does not represent an arbitrary
306// external pointer but always refers to an object managed by `CppHeap`. The
307// handles are using in combination with a dedicated table for `CppHeap`
308// references.
309using CppHeapPointerHandle = uint32_t;
310
311// The actual pointer to objects located on the `CppHeap`. When pointer
312// compression is enabled these pointers are stored as `CppHeapPointerHandle`.
313// In non-compressed configurations the pointers are simply stored as raw
314// pointers.
315#ifdef V8_COMPRESS_POINTERS
317#else
319#endif
320
323
324// See `ExternalPointerHandle` for the main documentation. The difference to
325// `ExternalPointerHandle` is that the handle always refers to a
326// (external pointer, size) tuple. The handles are used in combination with a
327// dedicated external buffer table (EBT).
328using ExternalBufferHandle = uint32_t;
329
330// ExternalBuffer point to buffer located outside the sandbox. When the V8
331// sandbox is enabled, these are stored on heap as ExternalBufferHandles,
332// otherwise they are simply raw pointers.
333#ifdef V8_ENABLE_SANDBOX
335#else
337#endif
338
339#ifdef V8_TARGET_OS_ANDROID
340// The size of the virtual memory reservation for the external buffer table.
341// As with the external pointer table, a maximum table size in combination with
342// shifted indices allows omitting bounds checks.
343constexpr size_t kExternalBufferTableReservationSize = 64 * MB;
344
345// The external buffer handles are stores shifted to the left by this amount
346// to guarantee that they are smaller than the maximum table size.
347constexpr uint32_t kExternalBufferHandleShift = 10;
348#else
350constexpr uint32_t kExternalBufferHandleShift = 9;
351#endif // V8_TARGET_OS_ANDROID
352
353// A null handle always references an entry that contains nullptr.
355
356// The maximum number of entries in an external buffer table.
361static_assert((1 << (32 - kExternalBufferHandleShift)) ==
363 "kExternalBufferTableReservationSize and "
364 "kExternalBufferHandleShift don't match");
365
366//
367// External Pointers.
368//
369// When the sandbox is enabled, external pointers are stored in an external
370// pointer table and are referenced from HeapObjects through an index (a
371// "handle"). When stored in the table, the pointers are tagged with per-type
372// tags to prevent type confusion attacks between different external objects.
373// Besides type information bits, these tags also contain the GC marking bit
374// which indicates whether the pointer table entry is currently alive. When a
375// pointer is written into the table, the tag is ORed into the top bits. When
376// that pointer is later loaded from the table, it is ANDed with the inverse of
377// the expected tag. If the expected and actual type differ, this will leave
378// some of the top bits of the pointer set, rendering the pointer inaccessible.
379// The AND operation also removes the GC marking bit from the pointer.
380//
381// The tags are constructed such that UNTAG(TAG(0, T1), T2) != 0 for any two
382// (distinct) tags T1 and T2. In practice, this is achieved by generating tags
383// that all have the same number of zeroes and ones but different bit patterns.
384// With N type tag bits, this allows for (N choose N/2) possible type tags.
385// Besides the type tag bits, the tags also have the GC marking bit set so that
386// the marking bit is automatically set when a pointer is written into the
387// external pointer table (in which case it is clearly alive) and is cleared
388// when the pointer is loaded. The exception to this is the free entry tag,
389// which doesn't have the mark bit set, as the entry is not alive. This
390// construction allows performing the type check and removing GC marking bits
391// from the pointer in one efficient operation (bitwise AND). The number of
392// available bits is limited in the following way: on x64, bits [47, 64) are
393// generally available for tagging (userspace has 47 address bits available).
394// On Arm64, userspace typically has a 40 or 48 bit address space. However, due
395// to top-byte ignore (TBI) and memory tagging (MTE), the top byte is unusable
396// for type checks as type-check failures would go unnoticed or collide with
397// MTE bits. Some bits of the top byte can, however, still be used for the GC
398// marking bit. The bits available for the type tags are therefore limited to
399// [48, 56), i.e. (8 choose 4) = 70 different types.
400// The following options exist to increase the number of possible types:
401// - Using multiple ExternalPointerTables since tags can safely be reused
402// across different tables
403// - Using "extended" type checks, where additional type information is stored
404// either in an adjacent pointer table entry or at the pointed-to location
405// - Using a different tagging scheme, for example based on XOR which would
406// allow for 2**8 different tags but require a separate operation to remove
407// the marking bit
408//
409// The external pointer sandboxing mechanism ensures that every access to an
410// external pointer field will result in a valid pointer of the expected type
411// even in the presence of an attacker able to corrupt memory inside the
412// sandbox. However, if any data related to the external object is stored
413// inside the sandbox it may still be corrupted and so must be validated before
414// use or moved into the external object. Further, an attacker will always be
415// able to substitute different external pointers of the same type for each
416// other. Therefore, code using external pointers must be written in a
417// "substitution-safe" way, i.e. it must always be possible to substitute
418// external pointers of the same type without causing memory corruption outside
419// of the sandbox. Generally this is achieved by referencing any group of
420// related external objects through a single external pointer.
421//
422// Currently we use bit 62 for the marking bit which should always be unused as
423// it's part of the non-canonical address range. When Arm's top-byte ignore
424// (TBI) is enabled, this bit will be part of the ignored byte, and we assume
425// that the Embedder is not using this byte (really only this one bit) for any
426// other purpose. This bit also does not collide with the memory tagging
427// extension (MTE) which would use bits [56, 60).
428//
429// External pointer tables are also available even when the sandbox is off but
430// pointer compression is on. In that case, the mechanism can be used to easy
431// alignment requirements as it turns unaligned 64-bit raw pointers into
432// aligned 32-bit indices. To "opt-in" to the external pointer table mechanism
433// for this purpose, instead of using the ExternalPointer accessors one needs to
434// use ExternalPointerHandles directly and use them to access the pointers in an
435// ExternalPointerTable.
436constexpr uint64_t kExternalPointerMarkBit = 1ULL << 62;
437constexpr uint64_t kExternalPointerTagMask = 0x40ff000000000000;
438constexpr uint64_t kExternalPointerTagMaskWithoutMarkBit = 0xff000000000000;
439constexpr uint64_t kExternalPointerTagShift = 48;
440
441// All possible 8-bit type tags.
442// These are sorted so that tags can be grouped together and it can efficiently
443// be checked if a tag belongs to a given group. See for example the
444// IsSharedExternalPointerType routine.
445constexpr uint64_t kAllExternalPointerTypeTags[] = {
446 0b00001111, 0b00010111, 0b00011011, 0b00011101, 0b00011110, 0b00100111,
447 0b00101011, 0b00101101, 0b00101110, 0b00110011, 0b00110101, 0b00110110,
448 0b00111001, 0b00111010, 0b00111100, 0b01000111, 0b01001011, 0b01001101,
449 0b01001110, 0b01010011, 0b01010101, 0b01010110, 0b01011001, 0b01011010,
450 0b01011100, 0b01100011, 0b01100101, 0b01100110, 0b01101001, 0b01101010,
451 0b01101100, 0b01110001, 0b01110010, 0b01110100, 0b01111000, 0b10000111,
452 0b10001011, 0b10001101, 0b10001110, 0b10010011, 0b10010101, 0b10010110,
453 0b10011001, 0b10011010, 0b10011100, 0b10100011, 0b10100101, 0b10100110,
454 0b10101001, 0b10101010, 0b10101100, 0b10110001, 0b10110010, 0b10110100,
455 0b10111000, 0b11000011, 0b11000101, 0b11000110, 0b11001001, 0b11001010,
456 0b11001100, 0b11010001, 0b11010010, 0b11010100, 0b11011000, 0b11100001,
457 0b11100010, 0b11100100, 0b11101000, 0b11110000};
458
459#define TAG(i) \
460 ((kAllExternalPointerTypeTags[i] << kExternalPointerTagShift) | \
461 kExternalPointerMarkBit)
462
463// clang-format off
464
465// When adding new tags, please ensure that the code using these tags is
466// "substitution-safe", i.e. still operate safely if external pointers of the
467// same type are swapped by an attacker. See comment above for more details.
468
469// Shared external pointers are owned by the shared Isolate and stored in the
470// shared external pointer table associated with that Isolate, where they can
471// be accessed from multiple threads at the same time. The objects referenced
472// in this way must therefore always be thread-safe.
473#define SHARED_EXTERNAL_POINTER_TAGS(V) \
474 V(kFirstSharedTag, TAG(0)) \
475 V(kWaiterQueueNodeTag, TAG(0)) \
476 V(kExternalStringResourceTag, TAG(1)) \
477 V(kExternalStringResourceDataTag, TAG(2)) \
478 V(kLastSharedTag, TAG(2))
479
480// External pointers using these tags are kept in a per-Isolate external
481// pointer table and can only be accessed when this Isolate is active.
482#define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V) \
483 V(kNativeContextMicrotaskQueueTag, TAG(10)) \
484 V(kEmbedderDataSlotPayloadTag, TAG(11)) \
485/* This tag essentially stands for a `void*` pointer in the V8 API, and */ \
486/* it is the Embedder's responsibility to ensure type safety (against */ \
487/* substitution) and lifetime validity of these objects. */ \
488 V(kExternalObjectValueTag, TAG(12)) \
489 V(kFunctionTemplateInfoCallbackTag, TAG(13)) \
490 V(kAccessorInfoGetterTag, TAG(14)) \
491 V(kAccessorInfoSetterTag, TAG(15)) \
492 V(kWasmInternalFunctionCallTargetTag, TAG(16)) \
493 V(kWasmTypeInfoNativeTypeTag, TAG(17)) \
494 V(kWasmExportedFunctionDataSignatureTag, TAG(18)) \
495 V(kWasmContinuationJmpbufTag, TAG(19)) \
496 V(kWasmIndirectFunctionTargetTag, TAG(20)) \
497 /* Foreigns */ \
498 V(kGenericForeignTag, TAG(30)) \
499 /* Managed */ \
500 V(kFirstManagedResourceTag, TAG(40)) \
501 V(kGenericManagedTag, TAG(40)) \
502 V(kWasmWasmStreamingTag, TAG(41)) \
503 V(kWasmFuncDataTag, TAG(42)) \
504 V(kWasmManagedDataTag, TAG(43)) \
505 V(kWasmNativeModuleTag, TAG(44)) \
506 V(kWasmStackMemoryTag, TAG(45)) \
507 V(kIcuBreakIteratorTag, TAG(46)) \
508 V(kIcuUnicodeStringTag, TAG(47)) \
509 V(kIcuListFormatterTag, TAG(48)) \
510 V(kIcuLocaleTag, TAG(49)) \
511 V(kIcuSimpleDateFormatTag, TAG(50)) \
512 V(kIcuDateIntervalFormatTag, TAG(51)) \
513 V(kIcuRelativeDateTimeFormatterTag, TAG(52)) \
514 V(kIcuLocalizedNumberFormatterTag, TAG(53)) \
515 V(kIcuPluralRulesTag, TAG(54)) \
516 V(kIcuCollatorTag, TAG(55)) \
517 V(kDisplayNamesInternalTag, TAG(56)) \
518 /* External resources whose lifetime is tied to */ \
519 /* their entry in the external pointer table but */ \
520 /* which are not referenced via a Managed */ \
521 V(kLastManagedResourceTag, TAG(56)) \
522 V(kArrayBufferExtensionTag, TAG(57))
523
524// All external pointer tags.
525#define ALL_EXTERNAL_POINTER_TAGS(V) \
526 SHARED_EXTERNAL_POINTER_TAGS(V) \
527 PER_ISOLATE_EXTERNAL_POINTER_TAGS(V)
528
529#define EXTERNAL_POINTER_TAG_ENUM(Name, Tag) Name = Tag,
530#define MAKE_TAG(HasMarkBit, TypeTag) \
531 ((static_cast<uint64_t>(TypeTag) << kExternalPointerTagShift) | \
532 (HasMarkBit ? kExternalPointerMarkBit : 0))
533enum ExternalPointerTag : uint64_t {
534 // Empty tag value. Mostly used as placeholder.
536 // External pointer tag that will match any external pointer. Use with care!
538 // External pointer tag that will match any external pointer in a Foreign.
539 // Use with care! If desired, this could be made more fine-granular.
541 // The free entry tag has all type bits set so every type check with a
542 // different type fails. It also doesn't have the mark bit set as free
543 // entries are (by definition) not alive.
545 // Evacuation entries are used during external pointer table compaction.
547 // Tag for zapped/invalidated entries. Those are considered to no longer be
548 // in use and so have the marking bit cleared.
550
552};
553
554#undef MAKE_TAG
555#undef TAG
556#undef EXTERNAL_POINTER_TAG_ENUM
557
558// clang-format on
559
560// True if the external pointer must be accessed from the shared isolate's
561// external pointer table.
562V8_INLINE static constexpr bool IsSharedExternalPointerType(
563 ExternalPointerTag tag) {
564 return tag >= kFirstSharedTag && tag <= kLastSharedTag;
565}
566
567// True if the external pointer may live in a read-only object, in which case
568// the table entry will be in the shared read-only segment of the external
569// pointer table.
570V8_INLINE static constexpr bool IsMaybeReadOnlyExternalPointerType(
571 ExternalPointerTag tag) {
572 return tag == kAccessorInfoGetterTag || tag == kAccessorInfoSetterTag ||
574}
575
576// True if the external pointer references an external object whose lifetime is
577// tied to the entry in the external pointer table.
578// In this case, the entry in the ExternalPointerTable always points to an
579// object derived from ExternalPointerTable::ManagedResource.
580V8_INLINE static constexpr bool IsManagedExternalPointerType(
581 ExternalPointerTag tag) {
583}
584
585// Sanity checks.
586#define CHECK_SHARED_EXTERNAL_POINTER_TAGS(Tag, ...) \
587 static_assert(IsSharedExternalPointerType(Tag));
588#define CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS(Tag, ...) \
589 static_assert(!IsSharedExternalPointerType(Tag));
590
593
594#undef CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS
595#undef CHECK_SHARED_EXTERNAL_POINTER_TAGS
596
597#undef SHARED_EXTERNAL_POINTER_TAGS
598#undef EXTERNAL_POINTER_TAGS
599
600//
601// Indirect Pointers.
602//
603// When the sandbox is enabled, indirect pointers are used to reference
604// HeapObjects that live outside of the sandbox (but are still managed by V8's
605// garbage collector). When object A references an object B through an indirect
606// pointer, object A will contain a IndirectPointerHandle, i.e. a shifted
607// 32-bit index, which identifies an entry in a pointer table (either the
608// trusted pointer table for TrustedObjects, or the code pointer table if it is
609// a Code object). This table entry then contains the actual pointer to object
610// B. Further, object B owns this pointer table entry, and it is responsible
611// for updating the "self-pointer" in the entry when it is relocated in memory.
612// This way, in contrast to "normal" pointers, indirect pointers never need to
613// be tracked by the GC (i.e. there is no remembered set for them).
614// These pointers do not exist when the sandbox is disabled.
615
616// An IndirectPointerHandle represents a 32-bit index into a pointer table.
617using IndirectPointerHandle = uint32_t;
618
619// A null handle always references an entry that contains nullptr.
621
622// When the sandbox is enabled, indirect pointers are used to implement:
623// - TrustedPointers: an indirect pointer using the trusted pointer table (TPT)
624// and referencing a TrustedObject in one of the trusted heap spaces.
625// - CodePointers, an indirect pointer using the code pointer table (CPT) and
626// referencing a Code object together with its instruction stream.
627
628//
629// Trusted Pointers.
630//
631// A pointer to a TrustedObject.
632// When the sandbox is enabled, these are indirect pointers using the trusted
633// pointer table (TPT). They are used to reference trusted objects (located in
634// one of V8's trusted heap spaces, outside of the sandbox) from inside the
635// sandbox in a memory-safe way. When the sandbox is disabled, these are
636// regular tagged pointers.
639// The size of the virtual memory reservation for the trusted pointer table.
640// As with the external pointer table, a maximum table size in combination with
641// shifted indices allows omitting bounds checks.
643
644// The trusted pointer handles are stores shifted to the left by this amount
645// to guarantee that they are smaller than the maximum table size.
646constexpr uint32_t kTrustedPointerHandleShift = 9;
647
648// A null handle always references an entry that contains nullptr.
652// The maximum number of entries in an trusted pointer table.
653constexpr int kTrustedPointerTableEntrySize = 8;
654constexpr int kTrustedPointerTableEntrySizeLog2 = 3;
655constexpr size_t kMaxTrustedPointers =
657static_assert((1 << (32 - kTrustedPointerHandleShift)) == kMaxTrustedPointers,
658 "kTrustedPointerTableReservationSize and "
659 "kTrustedPointerHandleShift don't match");
660
661//
662// Code Pointers.
663//
664// A pointer to a Code object.
665// Essentially a specialized version of a trusted pointer that (when the
666// sandbox is enabled) uses the code pointer table (CPT) instead of the TPT.
667// Each entry in the CPT contains both a pointer to a Code object as well as a
668// pointer to the Code's entrypoint. This allows calling/jumping into Code with
669// one fewer memory access (compared to the case where the entrypoint pointer
670// first needs to be loaded from the Code object). As such, a CodePointerHandle
671// can be used both to obtain the referenced Code object and to directly load
672// its entrypoint.
673//
674// When the sandbox is disabled, these are regular tagged pointers.
677// The size of the virtual memory reservation for the code pointer table.
678// As with the other tables, a maximum table size in combination with shifted
679// indices allows omitting bounds checks.
680constexpr size_t kCodePointerTableReservationSize = 128 * MB;
681
682// Code pointer handles are shifted by a different amount than indirect pointer
683// handles as the tables have a different maximum size.
684constexpr uint32_t kCodePointerHandleShift = 9;
685
686// A null handle always references an entry that contains nullptr.
688
689// It can sometimes be necessary to distinguish a code pointer handle from a
690// trusted pointer handle. A typical example would be a union trusted pointer
691// field that can refer to both Code objects and other trusted objects. To
692// support these use-cases, we use a simple marking scheme where some of the
693// low bits of a code pointer handle are set, while they will be unset on a
694// trusted pointer handle. This way, the correct table to resolve the handle
695// can be determined even in the absence of a type tag.
696constexpr uint32_t kCodePointerHandleMarker = 0x1;
697static_assert(kCodePointerHandleShift > 0);
698static_assert(kTrustedPointerHandleShift > 0);
700// The maximum number of entries in a code pointer table.
701constexpr int kCodePointerTableEntrySize = 16;
702constexpr int kCodePointerTableEntrySizeLog2 = 4;
703constexpr size_t kMaxCodePointers =
705static_assert(
707 "kCodePointerTableReservationSize and kCodePointerHandleShift don't match");
708
712// Constants that can be used to mark places that should be modified once
713// certain types of objects are moved out of the sandbox and into trusted space.
715constexpr bool kBuiltinCodeObjectsLiveInTrustedSpace = false;
719
720// {obj} must be the raw tagged pointer representation of a HeapObject
721// that's guaranteed to never be in ReadOnlySpace.
724// Returns if we need to throw when an error occurs. This infers the language
725// mode based on the current context and the closure. This returns true if the
726// language mode is strict.
727V8_EXPORT bool ShouldThrowOnError(internal::Isolate* isolate);
733class Internals {
734#ifdef V8_MAP_PACKING
735 V8_INLINE static constexpr Address UnpackMapWord(Address mapword) {
736 // TODO(wenyuzhao): Clear header metadata.
737 return mapword ^ kMapWordXorMask;
738 }
739#endif
741 public:
742 // These values match non-compiler-dependent values defined within
743 // the implementation of v8.
744 static const int kHeapObjectMapOffset = 0;
746 static const int kStringResourceOffset =
748
749 static const int kOddballKindOffset = 4 * kApiTaggedSize + kApiDoubleSize;
750 static const int kJSObjectHeaderSize = 3 * kApiTaggedSize;
751#ifdef V8_COMPRESS_POINTERS
754#else // !V8_COMPRESS_POINTERS
757#endif // !V8_COMPRESS_POINTERS
758 static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
759 static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
761#ifdef V8_ENABLE_SANDBOX
763#else
765#endif
767 static const int kStringRepresentationAndEncodingMask = 0x0f;
768 static const int kStringEncodingMask = 0x8;
769 static const int kExternalTwoByteRepresentationTag = 0x02;
770 static const int kExternalOneByteRepresentationTag = 0x0a;
772 static const uint32_t kNumIsolateDataSlots = 4;
774 static const int kNumberOfBooleanFlags = 6;
775 static const int kErrorMessageParamSize = 1;
776 static const int kTablesAlignmentPaddingSize = 1;
778 static const int kBuiltinTier0TableSize = 7 * kApiSystemPointerSize;
780 static const int kThreadLocalTopSize = 30 * kApiSystemPointerSize;
781 static const int kHandleScopeDataSize =
784 // ExternalPointerTable and TrustedPointerTable layout guarantees.
787 static const int kExternalBufferTableSize = 2 * kApiSystemPointerSize;
790
791 // IsolateData layout guarantees.
792 static const int kIsolateCageBaseOffset = 0;
793 static const int kIsolateStackGuardOffset =
795 static const int kVariousBooleanFlagsOffset =
797 static const int kErrorMessageParamOffset =
802 static const int kBuiltinTier0TableOffset =
804 static const int kNewAllocationInfoOffset =
806 static const int kOldAllocationInfoOffset =
808
809 static const int kFastCCallAlignmentPaddingSize =
811 static const int kIsolateFastCCallCallerFpOffset =
822 static const int kIsolateHandleScopeDataOffset =
824 static const int kIsolateEmbedderDataOffset =
826#ifdef V8_COMPRESS_POINTERS
827 static const int kIsolateExternalPointerTableOffset =
829 static const int kIsolateSharedExternalPointerTableAddressOffset =
830 kIsolateExternalPointerTableOffset + kExternalPointerTableSize;
831 static const int kIsolateCppHeapPointerTableOffset =
832 kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
833#ifdef V8_ENABLE_SANDBOX
834 static const int kIsolateTrustedCageBaseOffset =
835 kIsolateCppHeapPointerTableOffset + kExternalPointerTableSize;
836 static const int kIsolateTrustedPointerTableOffset =
837 kIsolateTrustedCageBaseOffset + kApiSystemPointerSize;
838 static const int kIsolateExternalBufferTableOffset =
839 kIsolateTrustedPointerTableOffset + kTrustedPointerTableSize;
840 static const int kIsolateSharedExternalBufferTableAddressOffset =
841 kIsolateExternalBufferTableOffset + kExternalBufferTableSize;
843 kIsolateSharedExternalBufferTableAddressOffset + kApiSystemPointerSize;
844#else
846 kIsolateCppHeapPointerTableOffset + kExternalPointerTableSize;
847#endif // V8_ENABLE_SANDBOX
848#else
851#endif // V8_COMPRESS_POINTERS
854 static const int kIsolateRootsOffset =
856
857#if V8_STATIC_ROOTS_BOOL
858
859// These constants are copied from static-roots.h and guarded by static asserts.
860#define EXPORTED_STATIC_ROOTS_PTR_LIST(V) \
861 V(UndefinedValue, 0x69) \
862 V(NullValue, 0x85) \
863 V(TrueValue, 0xc9) \
864 V(FalseValue, 0xad) \
865 V(EmptyString, 0xa1) \
866 V(TheHoleValue, 0x741)
867
868 using Tagged_t = uint32_t;
869 struct StaticReadOnlyRoot {
870#define DEF_ROOT(name, value) static constexpr Tagged_t k##name = value;
871 EXPORTED_STATIC_ROOTS_PTR_LIST(DEF_ROOT)
872#undef DEF_ROOT
873
874 static constexpr Tagged_t kFirstStringMap = 0xe5;
875 static constexpr Tagged_t kLastStringMap = 0x47d;
876
877#define PLUSONE(...) +1
878 static constexpr size_t kNumberOfExportedStaticRoots =
879 2 + EXPORTED_STATIC_ROOTS_PTR_LIST(PLUSONE);
880#undef PLUSONE
881 };
883#endif // V8_STATIC_ROOTS_BOOL
885 static const int kUndefinedValueRootIndex = 4;
886 static const int kTheHoleValueRootIndex = 5;
887 static const int kNullValueRootIndex = 6;
888 static const int kTrueValueRootIndex = 7;
889 static const int kFalseValueRootIndex = 8;
890 static const int kEmptyStringRootIndex = 9;
892 static const int kNodeClassIdOffset = 1 * kApiSystemPointerSize;
893 static const int kNodeFlagsOffset = 1 * kApiSystemPointerSize + 3;
894 static const int kNodeStateMask = 0x3;
895 static const int kNodeStateIsWeakValue = 2;
897 static const int kFirstNonstringType = 0x80;
898 static const int kOddballType = 0x83;
899 static const int kForeignType = 0xcc;
900 static const int kJSSpecialApiObjectType = 0x410;
901 static const int kJSObjectType = 0x421;
902 static const int kFirstJSApiObjectType = 0x422;
903 static const int kLastJSApiObjectType = 0x80A;
904 // Defines a range [kFirstEmbedderJSApiObjectType, kJSApiObjectTypesCount]
905 // of JSApiObject instance type values that an embedder can use.
906 static const int kFirstEmbedderJSApiObjectType = 0;
909
910 static const int kUndefinedOddballKind = 4;
911 static const int kNullOddballKind = 3;
913 // Constants used by PropertyCallbackInfo to check if we should throw when an
914 // error occurs.
915 static const int kThrowOnError = 0;
916 static const int kDontThrow = 1;
917 static const int kInferShouldThrowMode = 2;
918
919 // Soft limit for AdjustAmountofExternalAllocatedMemory. Trigger an
920 // incremental GC once the external memory reaches this limit.
921 static constexpr int kExternalAllocationSoftLimit = 64 * 1024 * 1024;
922
923#ifdef V8_MAP_PACKING
924 static const uintptr_t kMapWordMetadataMask = 0xffffULL << 48;
925 // The lowest two bits of mapwords are always `0b10`
926 static const uintptr_t kMapWordSignature = 0b10;
927 // XORing a (non-compressed) map with this mask ensures that the two
928 // low-order bits are 0b10. The 0 at the end makes this look like a Smi,
929 // although real Smis have all lower 32 bits unset. We only rely on these
930 // values passing as Smis in very few places.
931 static const int kMapWordXorMask = 0b11;
932#endif
933
934 V8_EXPORT static void CheckInitializedImpl(v8::Isolate* isolate);
935 V8_INLINE static void CheckInitialized(v8::Isolate* isolate) {
936#ifdef V8_ENABLE_CHECKS
938#endif
939 }
940
941 V8_INLINE static constexpr bool HasHeapObjectTag(Address value) {
942 return (value & kHeapObjectTagMask) == static_cast<Address>(kHeapObjectTag);
943 }
944
945 V8_INLINE static constexpr int SmiValue(Address value) {
946 return PlatformSmiTagging::SmiToInt(value);
947 }
948
949 V8_INLINE static constexpr Address IntToSmi(int value) {
950 return internal::IntToSmi(value);
951 }
952
953 V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
954 return PlatformSmiTagging::IsValidSmi(value);
955 }
956
957#if V8_STATIC_ROOTS_BOOL
958 V8_INLINE static bool is_identical(Address obj, Tagged_t constant) {
959 return static_cast<Tagged_t>(obj) == constant;
960 }
961
962 V8_INLINE static bool CheckInstanceMapRange(Address obj, Tagged_t first_map,
963 Tagged_t last_map) {
964 auto map = ReadRawField<Tagged_t>(obj, kHeapObjectMapOffset);
965#ifdef V8_MAP_PACKING
966 map = UnpackMapWord(map);
967#endif
968 return map >= first_map && map <= last_map;
969 }
970#endif
971
972 V8_INLINE static int GetInstanceType(Address obj) {
974#ifdef V8_MAP_PACKING
975 map = UnpackMapWord(map);
976#endif
977 return ReadRawField<uint16_t>(map, kMapInstanceTypeOffset);
978 }
979
980 V8_INLINE static Address LoadMap(Address obj) {
981 if (!HasHeapObjectTag(obj)) return kNullAddress;
983#ifdef V8_MAP_PACKING
984 map = UnpackMapWord(map);
985#endif
986 return map;
987 }
988
991 }
992
993 V8_INLINE static bool IsExternalTwoByteString(int instance_type) {
994 int representation = (instance_type & kStringRepresentationAndEncodingMask);
995 return representation == kExternalTwoByteRepresentationTag;
996 }
997
998 V8_INLINE static constexpr bool CanHaveInternalField(int instance_type) {
999 static_assert(kJSObjectType + 1 == kFirstJSApiObjectType);
1000 static_assert(kJSObjectType < kLastJSApiObjectType);
1002 // Check for IsJSObject() || IsJSSpecialApiObject() || IsJSApiObject()
1003 return instance_type == kJSSpecialApiObjectType ||
1004 // inlined version of base::IsInRange
1005 (static_cast<unsigned>(static_cast<unsigned>(instance_type) -
1006 static_cast<unsigned>(kJSObjectType)) <=
1007 static_cast<unsigned>(kLastJSApiObjectType - kJSObjectType));
1008 }
1009
1010 V8_INLINE static uint8_t GetNodeFlag(Address* obj, int shift) {
1011 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
1012 return *addr & static_cast<uint8_t>(1U << shift);
1013 }
1014
1015 V8_INLINE static void UpdateNodeFlag(Address* obj, bool value, int shift) {
1016 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
1017 uint8_t mask = static_cast<uint8_t>(1U << shift);
1018 *addr = static_cast<uint8_t>((*addr & ~mask) | (value << shift));
1019 }
1020
1021 V8_INLINE static uint8_t GetNodeState(Address* obj) {
1022 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
1023 return *addr & kNodeStateMask;
1024 }
1025
1026 V8_INLINE static void UpdateNodeState(Address* obj, uint8_t value) {
1027 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
1028 *addr = static_cast<uint8_t>((*addr & ~kNodeStateMask) | value);
1029 }
1030
1031 V8_INLINE static void SetEmbedderData(v8::Isolate* isolate, uint32_t slot,
1032 void* data) {
1033 Address addr = reinterpret_cast<Address>(isolate) +
1035 *reinterpret_cast<void**>(addr) = data;
1036 }
1037
1038 V8_INLINE static void* GetEmbedderData(const v8::Isolate* isolate,
1039 uint32_t slot) {
1040 Address addr = reinterpret_cast<Address>(isolate) +
1042 return *reinterpret_cast<void* const*>(addr);
1043 }
1044
1046 Address addr =
1047 reinterpret_cast<Address>(isolate) + kIsolateLongTaskStatsCounterOffset;
1048 ++(*reinterpret_cast<size_t*>(addr));
1049 }
1050
1051 V8_INLINE static Address* GetRootSlot(v8::Isolate* isolate, int index) {
1052 Address addr = reinterpret_cast<Address>(isolate) + kIsolateRootsOffset +
1054 return reinterpret_cast<Address*>(addr);
1055 }
1056
1057 V8_INLINE static Address GetRoot(v8::Isolate* isolate, int index) {
1058#if V8_STATIC_ROOTS_BOOL
1059 Address base = *reinterpret_cast<Address*>(
1060 reinterpret_cast<uintptr_t>(isolate) + kIsolateCageBaseOffset);
1061 switch (index) {
1062#define DECOMPRESS_ROOT(name, ...) \
1063 case k##name##RootIndex: \
1064 return base + StaticReadOnlyRoot::k##name;
1065 EXPORTED_STATIC_ROOTS_PTR_LIST(DECOMPRESS_ROOT)
1066#undef DECOMPRESS_ROOT
1067#undef EXPORTED_STATIC_ROOTS_PTR_LIST
1068 default:
1069 break;
1070 }
1071#endif // V8_STATIC_ROOTS_BOOL
1072 return *GetRootSlot(isolate, index);
1073 }
1074
1075#ifdef V8_ENABLE_SANDBOX
1076 V8_INLINE static Address* GetExternalPointerTableBase(v8::Isolate* isolate) {
1077 Address addr = reinterpret_cast<Address>(isolate) +
1078 kIsolateExternalPointerTableOffset +
1080 return *reinterpret_cast<Address**>(addr);
1081 }
1082
1083 V8_INLINE static Address* GetSharedExternalPointerTableBase(
1084 v8::Isolate* isolate) {
1085 Address addr = reinterpret_cast<Address>(isolate) +
1086 kIsolateSharedExternalPointerTableAddressOffset;
1087 addr = *reinterpret_cast<Address*>(addr);
1089 return *reinterpret_cast<Address**>(addr);
1091#endif
1092
1093 template <typename T>
1094 V8_INLINE static T ReadRawField(Address heap_object_ptr, int offset) {
1095 Address addr = heap_object_ptr + offset - kHeapObjectTag;
1096#ifdef V8_COMPRESS_POINTERS
1097 if (sizeof(T) > kApiTaggedSize) {
1098 // TODO(ishell, v8:8875): When pointer compression is enabled 8-byte size
1099 // fields (external pointers, doubles and BigInt data) are only
1100 // kTaggedSize aligned so we have to use unaligned pointer friendly way of
1101 // accessing them in order to avoid undefined behavior in C++ code.
1102 T r;
1103 memcpy(&r, reinterpret_cast<void*>(addr), sizeof(T));
1104 return r;
1105 }
1106#endif
1107 return *reinterpret_cast<const T*>(addr);
1108 }
1109
1110 V8_INLINE static Address ReadTaggedPointerField(Address heap_object_ptr,
1111 int offset) {
1112#ifdef V8_COMPRESS_POINTERS
1113 uint32_t value = ReadRawField<uint32_t>(heap_object_ptr, offset);
1114 Address base = GetPtrComprCageBaseFromOnHeapAddress(heap_object_ptr);
1115 return base + static_cast<Address>(static_cast<uintptr_t>(value));
1116#else
1117 return ReadRawField<Address>(heap_object_ptr, offset);
1118#endif
1119 }
1120
1121 V8_INLINE static Address ReadTaggedSignedField(Address heap_object_ptr,
1122 int offset) {
1123#ifdef V8_COMPRESS_POINTERS
1124 uint32_t value = ReadRawField<uint32_t>(heap_object_ptr, offset);
1125 return static_cast<Address>(static_cast<uintptr_t>(value));
1126#else
1127 return ReadRawField<Address>(heap_object_ptr, offset);
1128#endif
1129 }
1130
1132#ifdef V8_ENABLE_SANDBOX
1133 return reinterpret_cast<v8::Isolate*>(
1135#else
1136 // Not used in non-sandbox mode.
1137 return nullptr;
1138#endif
1139 }
1140
1141 template <ExternalPointerTag tag>
1143 Address heap_object_ptr,
1144 int offset) {
1145#ifdef V8_ENABLE_SANDBOX
1146 static_assert(tag != kExternalPointerNullTag);
1147 // See src/sandbox/external-pointer-table-inl.h. Logic duplicated here so
1148 // it can be inlined and doesn't require an additional call.
1149 Address* table = IsSharedExternalPointerType(tag)
1150 ? GetSharedExternalPointerTableBase(isolate)
1151 : GetExternalPointerTableBase(isolate);
1153 ReadRawField<ExternalPointerHandle>(heap_object_ptr, offset);
1154 uint32_t index = handle >> kExternalPointerIndexShift;
1155 std::atomic<Address>* ptr =
1156 reinterpret_cast<std::atomic<Address>*>(&table[index]);
1157 Address entry = std::atomic_load_explicit(ptr, std::memory_order_relaxed);
1158 return entry & ~tag;
1159#else
1160 return ReadRawField<Address>(heap_object_ptr, offset);
1161#endif // V8_ENABLE_SANDBOX
1162 }
1163
1164#ifdef V8_COMPRESS_POINTERS
1165 V8_INLINE static Address GetPtrComprCageBaseFromOnHeapAddress(Address addr) {
1166 return addr & -static_cast<intptr_t>(kPtrComprCageBaseAlignment);
1167 }
1168
1169 V8_INLINE static uint32_t CompressTagged(Address value) {
1170 return static_cast<uint32_t>(value);
1171 }
1172
1173 V8_INLINE static Address DecompressTaggedField(Address heap_object_ptr,
1174 uint32_t value) {
1175 Address base = GetPtrComprCageBaseFromOnHeapAddress(heap_object_ptr);
1176 return base + static_cast<Address>(static_cast<uintptr_t>(value));
1177 }
1178
1179#endif // V8_COMPRESS_POINTERS
1180};
1182// Only perform cast check for types derived from v8::Data since
1183// other types do not implement the Cast method.
1184template <bool PerformCheck>
1185struct CastCheck {
1186 template <class T>
1187 static void Perform(T* data);
1189
1190template <>
1191template <class T>
1192void CastCheck<true>::Perform(T* data) {
1193 T::Cast(data);
1195
1196template <>
1197template <class T>
1198void CastCheck<false>::Perform(T* data) {}
1199
1200template <class T>
1201V8_INLINE void PerformCastCheck(T* data) {
1202 CastCheck<std::is_base_of<Data, T>::value &&
1203 !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
1205
1206// A base class for backing stores, which is needed due to vagaries of
1207// how static casts work with std::shared_ptr.
1209
1210// The maximum value in enum GarbageCollectionReason, defined in heap.h.
1211// This is needed for histograms sampling garbage collection reasons.
1213
1214// Base class for the address block allocator compatible with standard
1215// containers, which registers its allocated range as strong roots.
1217 public:
1218 Heap* heap() const { return heap_; }
1220 bool operator==(const StrongRootAllocatorBase& other) const {
1221 return heap_ == other.heap_;
1222 }
1223 bool operator!=(const StrongRootAllocatorBase& other) const {
1224 return heap_ != other.heap_;
1226
1227 protected:
1228 explicit StrongRootAllocatorBase(Heap* heap) : heap_(heap) {}
1230
1231 // Allocate/deallocate a range of n elements of type internal::Address.
1232 Address* allocate_impl(size_t n);
1233 void deallocate_impl(Address* p, size_t n) noexcept;
1234
1235 private:
1236 Heap* heap_;
1237};
1238
1239// The general version of this template behaves just as std::allocator, with
1240// the exception that the constructor takes the isolate as parameter. Only
1241// specialized versions, e.g., internal::StrongRootAllocator<internal::Address>
1242// and internal::StrongRootAllocator<v8::Local<T>> register the allocated range
1243// as strong roots.
1244template <typename T>
1245class StrongRootAllocator : private std::allocator<T> {
1246 public:
1247 using value_type = T;
1248
1249 explicit StrongRootAllocator(Heap* heap) {}
1250 explicit StrongRootAllocator(Isolate* isolate) {}
1251 explicit StrongRootAllocator(v8::Isolate* isolate) {}
1252 template <typename U>
1253 StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept {}
1254
1255 using std::allocator<T>::allocate;
1256 using std::allocator<T>::deallocate;
1257};
1258
1259// A class of iterators that wrap some different iterator type.
1260// If specified, ElementType is the type of element accessed by the wrapper
1261// iterator; in this case, the actual reference and pointer types of Iterator
1262// must be convertible to ElementType& and ElementType*, respectively.
1263template <typename Iterator, typename ElementType = void>
1264class WrappedIterator {
1265 public:
1266 static_assert(
1267 !std::is_void_v<ElementType> ||
1268 (std::is_convertible_v<typename std::iterator_traits<Iterator>::pointer,
1269 ElementType*> &&
1270 std::is_convertible_v<typename std::iterator_traits<Iterator>::reference,
1271 ElementType&>));
1272
1274 typename std::iterator_traits<Iterator>::iterator_category;
1275 using difference_type =
1276 typename std::iterator_traits<Iterator>::difference_type;
1278 std::conditional_t<std::is_void_v<ElementType>,
1279 typename std::iterator_traits<Iterator>::value_type,
1280 ElementType>;
1281 using pointer =
1282 std::conditional_t<std::is_void_v<ElementType>,
1283 typename std::iterator_traits<Iterator>::pointer,
1284 ElementType*>;
1285 using reference =
1286 std::conditional_t<std::is_void_v<ElementType>,
1287 typename std::iterator_traits<Iterator>::reference,
1288 ElementType&>;
1289
1290 constexpr WrappedIterator() noexcept : it_() {}
1291 constexpr explicit WrappedIterator(Iterator it) noexcept : it_(it) {}
1293 template <typename OtherIterator, typename OtherElementType,
1294 std::enable_if_t<std::is_convertible_v<OtherIterator, Iterator>,
1295 bool> = true>
1298 : it_(it.base()) {}
1300 constexpr reference operator*() const noexcept { return *it_; }
1301 constexpr pointer operator->() const noexcept { return it_.operator->(); }
1302
1303 constexpr WrappedIterator& operator++() noexcept {
1304 ++it_;
1305 return *this;
1306 }
1307 constexpr WrappedIterator operator++(int) noexcept {
1308 WrappedIterator result(*this);
1309 ++(*this);
1310 return result;
1311 }
1312
1313 constexpr WrappedIterator& operator--() noexcept {
1314 --it_;
1315 return *this;
1316 }
1317 constexpr WrappedIterator operator--(int) noexcept {
1318 WrappedIterator result(*this);
1319 --(*this);
1320 return result;
1321 }
1322 constexpr WrappedIterator operator+(difference_type n) const noexcept {
1323 WrappedIterator result(*this);
1324 result += n;
1325 return result;
1326 }
1328 it_ += n;
1329 return *this;
1331 constexpr WrappedIterator operator-(difference_type n) const noexcept {
1332 return *this + (-n);
1333 }
1335 *this += -n;
1336 return *this;
1337 }
1338 constexpr reference operator[](difference_type n) const noexcept {
1339 return it_[n];
1340 }
1341
1342 constexpr Iterator base() const noexcept { return it_; }
1343
1344 private:
1345 template <typename OtherIterator, typename OtherElementType>
1346 friend class WrappedIterator;
1347
1348 private:
1349 Iterator it_;
1351
1352template <typename Iterator, typename ElementType, typename OtherIterator,
1353 typename OtherElementType>
1354constexpr bool operator==(
1355 const WrappedIterator<Iterator, ElementType>& x,
1356 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept {
1357 return x.base() == y.base();
1359
1360template <typename Iterator, typename ElementType, typename OtherIterator,
1361 typename OtherElementType>
1362constexpr bool operator<(
1363 const WrappedIterator<Iterator, ElementType>& x,
1364 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept {
1365 return x.base() < y.base();
1367
1368template <typename Iterator, typename ElementType, typename OtherIterator,
1369 typename OtherElementType>
1370constexpr bool operator!=(
1371 const WrappedIterator<Iterator, ElementType>& x,
1372 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept {
1373 return !(x == y);
1375
1376template <typename Iterator, typename ElementType, typename OtherIterator,
1377 typename OtherElementType>
1378constexpr bool operator>(
1379 const WrappedIterator<Iterator, ElementType>& x,
1380 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept {
1381 return y < x;
1383
1384template <typename Iterator, typename ElementType, typename OtherIterator,
1385 typename OtherElementType>
1386constexpr bool operator>=(
1387 const WrappedIterator<Iterator, ElementType>& x,
1388 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept {
1389 return !(x < y);
1391
1392template <typename Iterator, typename ElementType, typename OtherIterator,
1393 typename OtherElementType>
1394constexpr bool operator<=(
1395 const WrappedIterator<Iterator, ElementType>& x,
1396 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept {
1397 return !(y < x);
1399
1400template <typename Iterator, typename ElementType, typename OtherIterator,
1401 typename OtherElementType>
1402constexpr auto operator-(
1403 const WrappedIterator<Iterator, ElementType>& x,
1404 const WrappedIterator<OtherIterator, OtherElementType>& y) noexcept
1405 -> decltype(x.base() - y.base()) {
1406 return x.base() - y.base();
1407}
1408
1409template <typename Iterator, typename ElementType>
1410constexpr WrappedIterator<Iterator> operator+(
1412 const WrappedIterator<Iterator, ElementType>& x) noexcept {
1413 x += n;
1414 return x;
1415}
1417// Helper functions about values contained in handles.
1418// A value is either an indirect pointer or a direct pointer, depending on
1419// whether direct local support is enabled.
1420class ValueHelper final {
1421 public:
1422#ifdef V8_ENABLE_DIRECT_LOCAL
1423 static constexpr Address kTaggedNullAddress = 1;
1424 static constexpr Address kEmpty = kTaggedNullAddress;
1425#else
1426 static constexpr Address kEmpty = kNullAddress;
1427#endif // V8_ENABLE_DIRECT_LOCAL
1428
1429 template <typename T>
1430 V8_INLINE static bool IsEmpty(T* value) {
1431 return reinterpret_cast<Address>(value) == kEmpty;
1432 }
1433
1434 // Returns a handle's "value" for all kinds of abstract handles. For Local,
1435 // it is equivalent to `*handle`. The variadic parameters support handle
1436 // types with extra type parameters, like `Persistent<T, M>`.
1437 template <template <typename T, typename... Ms> typename H, typename T,
1438 typename... Ms>
1439 V8_INLINE static T* HandleAsValue(const H<T, Ms...>& handle) {
1440 return handle.template value<T>();
1441 }
1442
1443#ifdef V8_ENABLE_DIRECT_LOCAL
1444
1445 template <typename T>
1446 V8_INLINE static Address ValueAsAddress(const T* value) {
1447 return reinterpret_cast<Address>(value);
1448 }
1449
1450 template <typename T, bool check_null = true, typename S>
1451 V8_INLINE static T* SlotAsValue(S* slot) {
1452 if (check_null && slot == nullptr) {
1453 return reinterpret_cast<T*>(kTaggedNullAddress);
1454 }
1455 return *reinterpret_cast<T**>(slot);
1456 }
1458#else // !V8_ENABLE_DIRECT_LOCAL
1459
1460 template <typename T>
1461 V8_INLINE static Address ValueAsAddress(const T* value) {
1462 return *reinterpret_cast<const Address*>(value);
1463 }
1464
1465 template <typename T, bool check_null = true, typename S>
1466 V8_INLINE static T* SlotAsValue(S* slot) {
1467 return reinterpret_cast<T*>(slot);
1468 }
1469
1470#endif // V8_ENABLE_DIRECT_LOCAL
1471};
1476class HandleHelper final {
1477 public:
1488 template <typename T1, typename T2>
1489 V8_INLINE static bool EqualHandles(const T1& lhs, const T2& rhs) {
1490 if (lhs.IsEmpty()) return rhs.IsEmpty();
1491 if (rhs.IsEmpty()) return false;
1492 return lhs.ptr() == rhs.ptr();
1493 }
1494};
1495
1496V8_EXPORT void VerifyHandleIsNonEmpty(bool is_empty);
1497
1498} // namespace internal
1499} // namespace v8
1500
1501#endif // INCLUDE_V8_INTERNAL_H_
Definition: v8-isolate.h:210
Definition: v8-internal.h:1204
Definition: v8-internal.h:1472
static bool EqualHandles(const T1 &lhs, const T2 &rhs)
Definition: v8-internal.h:1485
Definition: v8-internal.h:729
static Address LoadMap(Address obj)
Definition: v8-internal.h:976
static bool IsExternalTwoByteString(int instance_type)
Definition: v8-internal.h:989
static const int kIsolateCageBaseOffset
Definition: v8-internal.h:788
static const int kEmbedderDataArrayHeaderSize
Definition: v8-internal.h:755
static const int kHeapObjectMapOffset
Definition: v8-internal.h:740
static const int kEmbedderDataSlotSize
Definition: v8-internal.h:756
static const int kIsolateApiCallbackThunkArgumentOffset
Definition: v8-internal.h:845
static Address ReadExternalPointerField(v8::Isolate *isolate, Address heap_object_ptr, int offset)
Definition: v8-internal.h:1138
static const int kJSAPIObjectWithEmbedderSlotsHeaderSize
Definition: v8-internal.h:751
static constexpr bool HasHeapObjectTag(Address value)
Definition: v8-internal.h:937
static const int kOddballType
Definition: v8-internal.h:894
static const int kInferShouldThrowMode
Definition: v8-internal.h:913
static const int kNewAllocationInfoOffset
Definition: v8-internal.h:800
static Address GetRoot(v8::Isolate *isolate, int index)
Definition: v8-internal.h:1053
static const int kStringEncodingMask
Definition: v8-internal.h:764
static const int kIsolateFastCCallCallerPcOffset
Definition: v8-internal.h:810
static uint8_t GetNodeFlag(Address *obj, int shift)
Definition: v8-internal.h:1006
static const int kIsolateThreadLocalTopOffset
Definition: v8-internal.h:816
static const uint32_t kNumIsolateDataSlots
Definition: v8-internal.h:768
static const int kForeignType
Definition: v8-internal.h:895
static const int kFirstEmbedderJSApiObjectType
Definition: v8-internal.h:902
static const int kNumberOfBooleanFlags
Definition: v8-internal.h:770
static uint8_t GetNodeState(Address *obj)
Definition: v8-internal.h:1017
static const int kThreadLocalTopSize
Definition: v8-internal.h:776
static const int kIsolateRootsOffset
Definition: v8-internal.h:850
static const int kExternalPointerTableSize
Definition: v8-internal.h:782
static const int kUndefinedOddballKind
Definition: v8-internal.h:906
static const int kMapInstanceTypeOffset
Definition: v8-internal.h:741
static const int kIsolateStackGuardOffset
Definition: v8-internal.h:789
static const int kLinearAllocationAreaSize
Definition: v8-internal.h:775
static const int kFastCCallAlignmentPaddingSize
Definition: v8-internal.h:805
static const int kIsolateFastCCallCallerFpOffset
Definition: v8-internal.h:807
static const int kErrorMessageParamSize
Definition: v8-internal.h:771
static void CheckInitialized(v8::Isolate *isolate)
Definition: v8-internal.h:931
static void UpdateNodeState(Address *obj, uint8_t value)
Definition: v8-internal.h:1022
static const int kJSObjectType
Definition: v8-internal.h:897
static const int kBuiltinTier0TableOffset
Definition: v8-internal.h:798
static const int kIsolateLongTaskStatsCounterOffset
Definition: v8-internal.h:814
static const int kNativeContextEmbedderDataOffset
Definition: v8-internal.h:762
static const int kLastJSApiObjectType
Definition: v8-internal.h:899
static constexpr bool CanHaveInternalField(int instance_type)
Definition: v8-internal.h:994
static const int kIsolateHandleScopeDataOffset
Definition: v8-internal.h:818
static const int kFirstNonstringType
Definition: v8-internal.h:893
static const int kEmptyStringRootIndex
Definition: v8-internal.h:886
static const int kBuiltinTier0EntryTableOffset
Definition: v8-internal.h:795
static const int kFixedArrayHeaderSize
Definition: v8-internal.h:754
static const int kNullOddballKind
Definition: v8-internal.h:907
static const int kUndefinedValueRootIndex
Definition: v8-internal.h:881
static const int kExternalTwoByteRepresentationTag
Definition: v8-internal.h:765
static const int kExternalBufferTableSize
Definition: v8-internal.h:783
static constexpr Address IntToSmi(int value)
Definition: v8-internal.h:945
static const int kDontThrow
Definition: v8-internal.h:912
static void CheckInitializedImpl(v8::Isolate *isolate)
static void * GetEmbedderData(const v8::Isolate *isolate, uint32_t slot)
Definition: v8-internal.h:1034
static const int kStackGuardSize
Definition: v8-internal.h:769
static const int kNodeStateMask
Definition: v8-internal.h:890
static const int kNodeStateIsWeakValue
Definition: v8-internal.h:891
static const int kFirstJSApiObjectType
Definition: v8-internal.h:898
static const int kStringResourceOffset
Definition: v8-internal.h:742
static const int kErrorMessageParamOffset
Definition: v8-internal.h:793
static const int kExternalPointerTableBasePointerOffset
Definition: v8-internal.h:781
static const int kFalseValueRootIndex
Definition: v8-internal.h:885
static const int kIsolateFastApiCallTargetOffset
Definition: v8-internal.h:812
static const int kTrueValueRootIndex
Definition: v8-internal.h:884
static int GetInstanceType(Address obj)
Definition: v8-internal.h:968
static const int kThrowOnError
Definition: v8-internal.h:911
static Address ReadTaggedSignedField(Address heap_object_ptr, int offset)
Definition: v8-internal.h:1117
static const int kOddballKindOffset
Definition: v8-internal.h:745
static const int kBuiltinTier0TableSize
Definition: v8-internal.h:774
static const int kContinuationPreservedEmbedderDataOffset
Definition: v8-internal.h:848
static Address ReadTaggedPointerField(Address heap_object_ptr, int offset)
Definition: v8-internal.h:1106
static constexpr bool IsValidSmi(intptr_t value)
Definition: v8-internal.h:949
static const int kNullValueRootIndex
Definition: v8-internal.h:883
static void SetEmbedderData(v8::Isolate *isolate, uint32_t slot, void *data)
Definition: v8-internal.h:1027
static Address * GetRootSlot(v8::Isolate *isolate, int index)
Definition: v8-internal.h:1047
static const int kTrustedPointerTableSize
Definition: v8-internal.h:784
static const int kTheHoleValueRootIndex
Definition: v8-internal.h:882
static constexpr int SmiValue(Address value)
Definition: v8-internal.h:941
static const int kTablesAlignmentPaddingSize
Definition: v8-internal.h:772
static const int kHandleScopeDataSize
Definition: v8-internal.h:777
static const int kExternalOneByteRepresentationTag
Definition: v8-internal.h:766
static const int kBuiltinTier0EntryTableSize
Definition: v8-internal.h:773
static void UpdateNodeFlag(Address *obj, bool value, int shift)
Definition: v8-internal.h:1011
static void IncrementLongTasksStatsCounter(v8::Isolate *isolate)
Definition: v8-internal.h:1041
static const int kOldAllocationInfoOffset
Definition: v8-internal.h:802
static const int kIsolateEmbedderDataOffset
Definition: v8-internal.h:820
static T ReadRawField(Address heap_object_ptr, int offset)
Definition: v8-internal.h:1090
static const int kEmbedderDataSlotExternalPointerOffset
Definition: v8-internal.h:760
static int GetOddballKind(Address obj)
Definition: v8-internal.h:985
static const int kNodeFlagsOffset
Definition: v8-internal.h:889
static const int kTrustedPointerTableBasePointerOffset
Definition: v8-internal.h:785
static const int kLastEmbedderJSApiObjectType
Definition: v8-internal.h:903
static const int kVariousBooleanFlagsOffset
Definition: v8-internal.h:791
static const int kNodeClassIdOffset
Definition: v8-internal.h:888
static const int kStringRepresentationAndEncodingMask
Definition: v8-internal.h:763
static constexpr int kExternalAllocationSoftLimit
Definition: v8-internal.h:917
static const int kJSObjectHeaderSize
Definition: v8-internal.h:746
static v8::Isolate * GetIsolateForSandbox(Address obj)
Definition: v8-internal.h:1127
static const int kJSSpecialApiObjectType
Definition: v8-internal.h:896
Definition: v8-internal.h:1212
Definition: v8-internal.h:1241
T value_type
Definition: v8-internal.h:1243
StrongRootAllocator(const StrongRootAllocator< U > &other) noexcept
Definition: v8-internal.h:1249
Definition: v8-internal.h:1416
static Address ValueAsAddress(const T *value)
Definition: v8-internal.h:1457
static constexpr Address kEmpty
Definition: v8-internal.h:1422
static T * SlotAsValue(S *slot)
Definition: v8-internal.h:1462
static T * HandleAsValue(const H< T, Ms... > &handle)
Definition: v8-internal.h:1435
static bool IsEmpty(T *value)
Definition: v8-internal.h:1426
Definition: v8-internal.h:1260
constexpr WrappedIterator & operator-=(difference_type n) noexcept
Definition: v8-internal.h:1330
constexpr WrappedIterator operator--(int) noexcept
Definition: v8-internal.h:1313
constexpr WrappedIterator & operator+=(difference_type n) noexcept
Definition: v8-internal.h:1323
constexpr Iterator base() const noexcept
Definition: v8-internal.h:1338
std::conditional_t< std::is_void_v< ElementType >, typename std::iterator_traits< Iterator >::reference, ElementType & > reference
Definition: v8-internal.h:1284
std::conditional_t< std::is_void_v< ElementType >, typename std::iterator_traits< Iterator >::value_type, ElementType > value_type
Definition: v8-internal.h:1276
constexpr WrappedIterator & operator++() noexcept
Definition: v8-internal.h:1299
constexpr pointer operator->() const noexcept
Definition: v8-internal.h:1297
constexpr reference operator[](difference_type n) const noexcept
Definition: v8-internal.h:1334
typename std::iterator_traits< Iterator >::difference_type difference_type
Definition: v8-internal.h:1272
std::conditional_t< std::is_void_v< ElementType >, typename std::iterator_traits< Iterator >::pointer, ElementType * > pointer
Definition: v8-internal.h:1280
constexpr WrappedIterator & operator--() noexcept
Definition: v8-internal.h:1309
typename std::iterator_traits< Iterator >::iterator_category iterator_category
Definition: v8-internal.h:1270
constexpr reference operator*() const noexcept
Definition: v8-internal.h:1296
constexpr WrappedIterator operator+(difference_type n) const noexcept
Definition: v8-internal.h:1318
constexpr WrappedIterator operator++(int) noexcept
Definition: v8-internal.h:1303
constexpr WrappedIterator operator-(difference_type n) const noexcept
Definition: v8-internal.h:1327
friend class WrappedIterator
Definition: v8-internal.h:1342
const intptr_t kHeapObjectTagMask
Definition: v8-internal.h:54
constexpr int kCodePointerTableEntrySizeLog2
Definition: v8-internal.h:698
constexpr bool kRuntimeGeneratedCodeObjectsLiveInTrustedSpace
Definition: v8-internal.h:710
uint32_t ExternalBufferHandle
Definition: v8-internal.h:328
internal::Isolate * IsolateFromNeverReadOnlySpaceObject(Address obj)
constexpr uint64_t kExternalPointerTagShift
Definition: v8-internal.h:439
IndirectPointerHandle TrustedPointerHandle
Definition: v8-internal.h:633
const int kApiSystemPointerSize
Definition: v8-internal.h:44
constexpr bool SandboxIsEnabled()
Definition: v8-internal.h:163
constexpr size_t kExternalBufferTableReservationSize
Definition: v8-internal.h:349
const int kApiDoubleSize
Definition: v8-internal.h:45
constexpr bool operator<=(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept
Definition: v8-internal.h:1390
constexpr intptr_t kIntptrAllBitsSet
Definition: v8-internal.h:72
constexpr int GB
Definition: v8-internal.h:36
void VerifyHandleIsNonEmpty(bool is_empty)
const int kApiInt32Size
Definition: v8-internal.h:46
const int kForwardingTagSize
Definition: v8-internal.h:61
uint32_t CppHeapPointerHandle
Definition: v8-internal.h:309
const intptr_t kForwardingTagMask
Definition: v8-internal.h:62
IndirectPointerHandle CodePointerHandle
Definition: v8-internal.h:671
constexpr size_t kMaxExternalBufferPointers
Definition: v8-internal.h:359
const int kSmiTagSize
Definition: v8-internal.h:66
const int kApiInt64Size
Definition: v8-internal.h:47
constexpr int kExternalBufferTableEntrySizeLog2
Definition: v8-internal.h:358
constexpr uint64_t kExternalPointerTagMask
Definition: v8-internal.h:437
constexpr int kCodePointerTableEntryCodeObjectOffset
Definition: v8-internal.h:706
constexpr int kTrustedPointerTableEntrySizeLog2
Definition: v8-internal.h:650
constexpr int kTrustedPointerTableEntrySize
Definition: v8-internal.h:649
constexpr ExternalPointer_t kNullExternalPointer
Definition: v8-internal.h:301
constexpr bool operator>(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept
Definition: v8-internal.h:1374
Address ExternalPointer_t
Definition: v8-internal.h:298
constexpr WrappedIterator< Iterator > operator+(typename WrappedIterator< Iterator, ElementType >::difference_type n, const WrappedIterator< Iterator, ElementType > &x) noexcept
Definition: v8-internal.h:1406
uint32_t IndirectPointerHandle
Definition: v8-internal.h:613
constexpr CppHeapPointer_t kNullCppHeapPointer
Definition: v8-internal.h:321
const int kApiSizetSize
Definition: v8-internal.h:48
constexpr int kCodePointerTableEntryEntrypointOffset
Definition: v8-internal.h:705
constexpr size_t kMaxExternalPointers
Definition: v8-internal.h:279
constexpr uint64_t kExternalPointerTagMaskWithoutMarkBit
Definition: v8-internal.h:438
constexpr size_t kCodePointerTableReservationSize
Definition: v8-internal.h:676
constexpr TrustedPointerHandle kNullTrustedPointerHandle
Definition: v8-internal.h:645
constexpr ExternalBufferHandle kNullExternalBufferHandle
Definition: v8-internal.h:354
constexpr uint64_t kAllExternalPointerTypeTags[]
Definition: v8-internal.h:445
const int kWeakHeapObjectTag
Definition: v8-internal.h:52
constexpr ExternalPointerHandle kNullExternalPointerHandle
Definition: v8-internal.h:302
constexpr bool operator<(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept
Definition: v8-internal.h:1358
constexpr bool operator!=(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept
Definition: v8-internal.h:1366
constexpr uintptr_t kUintptrAllBitsSet
Definition: v8-internal.h:73
const int kForwardingTag
Definition: v8-internal.h:60
const intptr_t kHeapObjectReferenceTagMask
Definition: v8-internal.h:55
constexpr bool SmiValuesAre31Bits()
Definition: v8-internal.h:151
constexpr size_t kMaxTrustedPointers
Definition: v8-internal.h:651
bool ShouldThrowOnError(internal::Isolate *isolate)
constexpr auto operator-(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept -> decltype(x.base() - y.base())
Definition: v8-internal.h:1398
constexpr int KB
Definition: v8-internal.h:34
constexpr bool kBuiltinCodeObjectsLiveInTrustedSpace
Definition: v8-internal.h:711
constexpr bool operator>=(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept
Definition: v8-internal.h:1382
constexpr uint32_t kTrustedPointerHandleShift
Definition: v8-internal.h:642
constexpr uint32_t kCodePointerHandleShift
Definition: v8-internal.h:680
const int kHeapObjectTag
Definition: v8-internal.h:51
const int kSmiShiftSize
Definition: v8-internal.h:147
constexpr size_t kMaxCodePointers
Definition: v8-internal.h:699
SmiTagging< kApiTaggedSize > PlatformSmiTagging
Definition: v8-internal.h:142
const int kSmiValueSize
Definition: v8-internal.h:148
constexpr bool SmiValuesAre32Bits()
Definition: v8-internal.h:152
constexpr IndirectPointerHandle kNullIndirectPointerHandle
Definition: v8-internal.h:616
uintptr_t Address
Definition: v8-internal.h:31
void PerformCastCheck(T *data)
Definition: v8-internal.h:1197
constexpr size_t kTrustedPointerTableReservationSize
Definition: v8-internal.h:638
uint32_t ExternalPointerHandle
Definition: v8-internal.h:290
const intptr_t kSmiTagMask
Definition: v8-internal.h:67
constexpr uint32_t kExternalBufferHandleShift
Definition: v8-internal.h:350
const int kHeapObjectTagSize
Definition: v8-internal.h:53
const int kSmiMaxValue
Definition: v8-internal.h:150
Address ExternalBuffer_t
Definition: v8-internal.h:336
constexpr bool Is64()
Definition: v8-internal.h:153
constexpr bool kAllCodeObjectsLiveInTrustedSpace
Definition: v8-internal.h:712
constexpr bool operator==(const WrappedIterator< Iterator, ElementType > &x, const WrappedIterator< OtherIterator, OtherElementType > &y) noexcept
Definition: v8-internal.h:1350
const int kSmiTag
Definition: v8-internal.h:65
constexpr CodePointerHandle kNullCodePointerHandle
Definition: v8-internal.h:683
Address CppHeapPointer_t
Definition: v8-internal.h:318
constexpr CppHeapPointerHandle kNullCppHeapPointerHandle
Definition: v8-internal.h:322
constexpr int kGarbageCollectionReasonMaxValue
Definition: v8-internal.h:1208
constexpr int kCodePointerTableEntrySize
Definition: v8-internal.h:697
constexpr int kExternalBufferTableEntrySize
Definition: v8-internal.h:357
ExternalPointerTag
Definition: v8-internal.h:533
@ kExternalPointerEvacuationEntryTag
Definition: v8-internal.h:546
@ kAccessorInfoGetterTag
Definition: v8-internal.h:551
@ kFirstSharedTag
Definition: v8-internal.h:551
@ kAccessorInfoSetterTag
Definition: v8-internal.h:551
@ kAnyForeignTag
Definition: v8-internal.h:540
@ kExternalPointerFreeEntryTag
Definition: v8-internal.h:544
@ kAnyExternalPointerTag
Definition: v8-internal.h:537
@ kLastSharedTag
Definition: v8-internal.h:551
@ kExternalPointerNullTag
Definition: v8-internal.h:535
@ kLastManagedResourceTag
Definition: v8-internal.h:551
@ kExternalPointerZappedEntryTag
Definition: v8-internal.h:549
@ kFirstManagedResourceTag
Definition: v8-internal.h:551
@ kFunctionTemplateInfoCallbackTag
Definition: v8-internal.h:551
constexpr uint32_t kCodePointerHandleMarker
Definition: v8-internal.h:692
const int kSmiMinValue
Definition: v8-internal.h:149
constexpr int MB
Definition: v8-internal.h:35
constexpr uint64_t kExternalPointerMarkBit
Definition: v8-internal.h:436
Address SandboxedPointer_t
Definition: v8-internal.h:173
const int kApiTaggedSize
Definition: v8-internal.h:132
constexpr bool PointerCompressionIsEnabled()
Definition: v8-internal.h:135
Definition: libplatform.h:15
Definition: v8-internal.h:1181
static void Perform(T *data)
static constexpr int SmiToInt(Address value)
Definition: v8-internal.h:85
static constexpr bool IsValidSmi(intptr_t value)
Definition: v8-internal.h:90
static constexpr int SmiToInt(Address value)
Definition: v8-internal.h:110
static constexpr bool IsValidSmi(intptr_t value)
Definition: v8-internal.h:115
Definition: v8-internal.h:70
#define EXTERNAL_POINTER_TAG_ENUM(Name, Tag)
Definition: v8-internal.h:529
#define ALL_EXTERNAL_POINTER_TAGS(V)
Definition: v8-internal.h:525
#define CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS(Tag,...)
Definition: v8-internal.h:587
#define SHARED_EXTERNAL_POINTER_TAGS(V)
Definition: v8-internal.h:473
#define MAKE_TAG(HasMarkBit, TypeTag)
Definition: v8-internal.h:530
#define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V)
Definition: v8-internal.h:482
#define CHECK_SHARED_EXTERNAL_POINTER_TAGS(Tag,...)
Definition: v8-internal.h:585
#define V8_EXPORT
Definition: v8config.h:762
#define V8_INLINE
Definition: v8config.h:477