5#ifndef INCLUDE_V8_INTERNAL_H_
6#define INCLUDE_V8_INTERNAL_H_
30static constexpr Address kNullAddress = 0;
32constexpr int KB = 1024;
33constexpr int MB =
KB * 1024;
34constexpr int GB =
MB * 1024;
35#ifdef V8_TARGET_ARCH_X64
36constexpr size_t TB =
size_t{
GB} * 1024;
67template <
size_t tagged_ptr_size>
86 return static_cast<int32_t
>(
static_cast<uint32_t
>(value)) >> shift_bits;
92 return (
static_cast<uintptr_t
>(value) -
111 return static_cast<int>(
static_cast<intptr_t
>(value) >> shift_bits);
115 return (value ==
static_cast<int32_t
>(value));
119#ifdef V8_COMPRESS_POINTERS
122constexpr size_t kPtrComprCageReservationSize =
size_t{1} << 32;
123constexpr size_t kPtrComprCageBaseAlignment =
size_t{1} << 32;
127 "Pointer compression can be enabled only for 64-bit architectures");
137#ifdef V8_31BIT_SMIS_ON_64BIT_ARCH
147const int kSmiMinValue =
static_cast<int>(PlatformSmiTagging::kSmiMinValue);
148const int kSmiMaxValue =
static_cast<int>(PlatformSmiTagging::kSmiMaxValue);
162#ifdef V8_ENABLE_SANDBOX
173#ifdef V8_ENABLE_SANDBOX
176#ifdef V8_TARGET_OS_ANDROID
180constexpr size_t kSandboxSizeLog2 = 37;
183constexpr size_t kSandboxSizeLog2 = 40;
185constexpr size_t kSandboxSize = 1ULL << kSandboxSizeLog2;
192constexpr size_t kSandboxAlignment = kPtrComprCageBaseAlignment;
198constexpr uint64_t kSandboxedPointerShift = 64 - kSandboxSizeLog2;
203constexpr size_t kSandboxGuardRegionSize = 32ULL *
GB;
205static_assert((kSandboxGuardRegionSize % kSandboxAlignment) == 0,
206 "The size of the guard regions around the sandbox must be a "
207 "multiple of its required alignment.");
219constexpr size_t kSandboxMinimumReservationSize = 8ULL *
GB;
221static_assert(kSandboxMinimumReservationSize > kPtrComprCageReservationSize,
222 "The minimum reservation size for a sandbox must be larger than "
223 "the pointer compression cage contained within it.");
229constexpr size_t kMaxSafeBufferSizeForSandbox = 32ULL *
GB - 1;
230static_assert(kMaxSafeBufferSizeForSandbox <= kSandboxGuardRegionSize,
231 "The maximum allowed buffer size must not be larger than the "
232 "sandbox's guard regions");
234constexpr size_t kBoundedSizeShift = 29;
235static_assert(1ULL << (64 - kBoundedSizeShift) ==
236 kMaxSafeBufferSizeForSandbox + 1,
237 "The maximum size of a BoundedSize must be synchronized with the "
238 "kMaxSafeBufferSizeForSandbox");
242#ifdef V8_COMPRESS_POINTERS
244#ifdef V8_TARGET_OS_ANDROID
250static const size_t kExternalPointerTableReservationSize = 512 *
MB;
255static const uint32_t kExternalPointerIndexShift = 6;
257static const size_t kExternalPointerTableReservationSize = 1024 *
MB;
258static const uint32_t kExternalPointerIndexShift = 5;
262static const size_t kMaxExternalPointers =
264static_assert((1 << (32 - kExternalPointerIndexShift)) == kMaxExternalPointers,
265 "kExternalPointerTableReservationSize and "
266 "kExternalPointerIndexShift don't match");
271static const size_t kMaxExternalPointers = 0;
287#ifdef V8_ENABLE_SANDBOX
369 0b00001111, 0b00010111, 0b00011011, 0b00011101, 0b00011110, 0b00100111,
370 0b00101011, 0b00101101, 0b00101110, 0b00110011, 0b00110101, 0b00110110,
371 0b00111001, 0b00111010, 0b00111100, 0b01000111, 0b01001011, 0b01001101,
372 0b01001110, 0b01010011, 0b01010101, 0b01010110, 0b01011001, 0b01011010,
373 0b01011100, 0b01100011, 0b01100101, 0b01100110, 0b01101001, 0b01101010,
374 0b01101100, 0b01110001, 0b01110010, 0b01110100, 0b01111000, 0b10000111,
375 0b10001011, 0b10001101, 0b10001110, 0b10010011, 0b10010101, 0b10010110,
376 0b10011001, 0b10011010, 0b10011100, 0b10100011, 0b10100101, 0b10100110,
377 0b10101001, 0b10101010, 0b10101100, 0b10110001, 0b10110010, 0b10110100,
378 0b10111000, 0b11000011, 0b11000101, 0b11000110, 0b11001001, 0b11001010,
379 0b11001100, 0b11010001, 0b11010010, 0b11010100, 0b11011000, 0b11100001,
380 0b11100010, 0b11100100, 0b11101000, 0b11110000};
383 ((kAllExternalPointerTypeTags[i] << kExternalPointerTagShift) | \
384 kExternalPointerMarkBit)
396#define SHARED_EXTERNAL_POINTER_TAGS(V) \
397 V(kFirstSharedTag, TAG(0)) \
398 V(kWaiterQueueNodeTag, TAG(0)) \
399 V(kExternalStringResourceTag, TAG(1)) \
400 V(kExternalStringResourceDataTag, TAG(2)) \
401 V(kLastSharedTag, TAG(2))
405#define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V) \
406 V(kForeignForeignAddressTag, TAG(10)) \
407 V(kNativeContextMicrotaskQueueTag, TAG(11)) \
408 V(kEmbedderDataSlotPayloadTag, TAG(12)) \
412 V(kExternalObjectValueTag, TAG(13)) \
413 V(kCallHandlerInfoCallbackTag, TAG(14)) \
414 V(kAccessorInfoGetterTag, TAG(15)) \
415 V(kAccessorInfoSetterTag, TAG(16)) \
416 V(kWasmInternalFunctionCallTargetTag, TAG(17)) \
417 V(kWasmTypeInfoNativeTypeTag, TAG(18)) \
418 V(kWasmExportedFunctionDataSignatureTag, TAG(19)) \
419 V(kWasmContinuationJmpbufTag, TAG(20)) \
420 V(kArrayBufferExtensionTag, TAG(21))
423#define ALL_EXTERNAL_POINTER_TAGS(V) \
424 SHARED_EXTERNAL_POINTER_TAGS(V) \
425 PER_ISOLATE_EXTERNAL_POINTER_TAGS(V)
427#define EXTERNAL_POINTER_TAG_ENUM(Name, Tag) Name = Tag,
428#define MAKE_TAG(HasMarkBit, TypeTag) \
429 ((static_cast<uint64_t>(TypeTag) << kExternalPointerTagShift) | \
430 (HasMarkBit ? kExternalPointerMarkBit : 0))
448#undef EXTERNAL_POINTER_TAG_ENUM
454V8_INLINE static constexpr bool IsSharedExternalPointerType(
456 return tag >= kFirstSharedTag && tag <= kLastSharedTag;
460#define CHECK_SHARED_EXTERNAL_POINTER_TAGS(Tag, ...) \
461 static_assert(IsSharedExternalPointerType(Tag));
462#define CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS(Tag, ...) \
463 static_assert(!IsSharedExternalPointerType(Tag));
468#undef CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS
469#undef CHECK_SHARED_EXTERNAL_POINTER_TAGS
471#undef SHARED_EXTERNAL_POINTER_TAGS
472#undef EXTERNAL_POINTER_TAGS
491 return mapword ^ kMapWordXorMask;
508#ifdef V8_ENABLE_SANDBOX
556#ifdef V8_COMPRESS_POINTERS
557 static const int kIsolateExternalPointerTableOffset =
559 static const int kIsolateSharedExternalPointerTableAddressOffset =
568#if V8_STATIC_ROOTS_BOOL
571#define EXPORTED_STATIC_ROOTS_PTR_LIST(V) \
579 using Tagged_t = uint32_t;
580 struct StaticReadOnlyRoot {
581#define DEF_ROOT(name) V8_EXPORT static const Tagged_t k##name;
582 EXPORTED_STATIC_ROOTS_PTR_LIST(DEF_ROOT)
585 V8_EXPORT static const Tagged_t kFirstStringMap;
586 V8_EXPORT static const Tagged_t kLastStringMap;
627 static const uintptr_t kMapWordMetadataMask = 0xffffULL << 48;
629 static const uintptr_t kMapWordSignature = 0b10;
634 static const int kMapWordXorMask = 0b11;
639#ifdef V8_ENABLE_CHECKS
649 return PlatformSmiTagging::SmiToInt(value);
653 return internal::IntToSmi(value);
657 return PlatformSmiTagging::IsValidSmi(value);
660#if V8_STATIC_ROOTS_BOOL
662 return static_cast<Tagged_t
>(obj) == constant;
665 V8_INLINE static bool CheckInstanceMapRange(
Address obj, Tagged_t first_map,
669 map = UnpackMapWord(map);
671 return map >= first_map && map <= last_map;
678 map = UnpackMapWord(map);
699 (
static_cast<unsigned>(
static_cast<unsigned>(instance_type) -
706 return *addr &
static_cast<uint8_t
>(1U << shift);
711 uint8_t mask =
static_cast<uint8_t
>(1U << shift);
712 *addr =
static_cast<uint8_t
>((*addr & ~mask) | (value << shift));
722 *addr =
static_cast<uint8_t
>((*addr & ~kNodeStateMask) | value);
729 *
reinterpret_cast<void**
>(addr) = data;
736 return *
reinterpret_cast<void* const*
>(addr);
742 ++(*
reinterpret_cast<size_t*
>(addr));
748 return reinterpret_cast<Address*
>(addr);
752#if V8_STATIC_ROOTS_BOOL
756#define DECOMPRESS_ROOT(name) \
757 case k##name##RootIndex: \
758 return base + StaticReadOnlyRoot::k##name;
759 EXPORTED_STATIC_ROOTS_PTR_LIST(DECOMPRESS_ROOT)
760#undef DECOMPRESS_ROOT
764#undef EXPORTED_STATIC_ROOTS_PTR_LIST
769#ifdef V8_ENABLE_SANDBOX
772 kIsolateExternalPointerTableOffset +
774 return *
reinterpret_cast<Address**
>(addr);
780 kIsolateSharedExternalPointerTableAddressOffset;
781 addr = *
reinterpret_cast<Address*
>(addr);
783 return *
reinterpret_cast<Address**
>(addr);
787 template <
typename T>
790#ifdef V8_COMPRESS_POINTERS
797 memcpy(&r,
reinterpret_cast<void*
>(addr),
sizeof(T));
801 return *
reinterpret_cast<const T*
>(addr);
806#ifdef V8_COMPRESS_POINTERS
807 uint32_t value = ReadRawField<uint32_t>(heap_object_ptr, offset);
808 Address base = GetPtrComprCageBaseFromOnHeapAddress(heap_object_ptr);
809 return base +
static_cast<Address>(
static_cast<uintptr_t
>(value));
811 return ReadRawField<Address>(heap_object_ptr, offset);
817#ifdef V8_COMPRESS_POINTERS
818 uint32_t value = ReadRawField<uint32_t>(heap_object_ptr, offset);
819 return static_cast<Address>(
static_cast<uintptr_t
>(value));
821 return ReadRawField<Address>(heap_object_ptr, offset);
826#ifdef V8_ENABLE_SANDBOX
835 template <ExternalPo
interTag tag>
839#ifdef V8_ENABLE_SANDBOX
843 Address* table = IsSharedExternalPointerType(tag)
844 ? GetSharedExternalPointerTableBase(isolate)
845 : GetExternalPointerTableBase(isolate);
847 ReadRawField<ExternalPointerHandle>(heap_object_ptr, offset);
848 uint32_t index = handle >> kExternalPointerIndexShift;
849 std::atomic<Address>* ptr =
850 reinterpret_cast<std::atomic<Address>*
>(&table[index]);
851 Address entry = std::atomic_load_explicit(ptr, std::memory_order_relaxed);
854 return ReadRawField<Address>(heap_object_ptr, offset);
858#ifdef V8_COMPRESS_POINTERS
860 return addr & -
static_cast<intptr_t
>(kPtrComprCageBaseAlignment);
865 Address base = GetPtrComprCageBaseFromOnHeapAddress(heap_object_ptr);
866 return base +
static_cast<Address>(
static_cast<uintptr_t
>(value));
874template <
bool PerformCheck>
893 !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
907#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
908 static constexpr Address kLocalTaggedNullAddress = 1;
910 template <
typename T>
912 return reinterpret_cast<T*
>(kLocalTaggedNullAddress);
915 template <
typename T>
917 return reinterpret_cast<Address>(value);
920 template <
typename T,
typename S>
922 return *
reinterpret_cast<T**
>(slot);
925 template <
typename T>
927 return reinterpret_cast<T*
>(
const_cast<T**
>(&value));
932 template <
typename T>
937 template <
typename T>
939 return *
reinterpret_cast<const Address*
>(value);
942 template <
typename T,
typename S>
944 return reinterpret_cast<T*
>(slot);
947 template <
typename T>
static const int kIsolateCageBaseOffset
static const int kTrueValueRootIndex
static const int kInferShouldThrowMode
static V8_INLINE void UpdateNodeFlag(Address *obj, bool value, int shift)
static const int kJSSpecialApiObjectType
static V8_INLINE void IncrementLongTasksStatsCounter(v8::Isolate *isolate)
static const int kExternalPointerTableSize
static const int kOddballKindOffset
static const int kOldAllocationInfoOffset
static const int kFalseValueRootIndex
static constexpr int kExternalAllocationSoftLimit
static const int kIsolateStackGuardOffset
static const int kNullValueRootIndex
static const int kIsolateFastCCallCallerPcOffset
static const int kDontThrow
static const int kEmptyStringRootIndex
static V8_INLINE uint8_t GetNodeState(Address *obj)
static const int kNativeContextEmbedderDataOffset
static V8_INLINE uint8_t GetNodeFlag(Address *obj, int shift)
static const int kStringRepresentationAndEncodingMask
static const int kIsolateThreadLocalTopOffset
static const int kIsolateLongTaskStatsCounterOffset
static const int kEmbedderDataArrayHeaderSize
static V8_INLINE bool HasHeapObjectTag(Address value)
static const int kExternalTwoByteRepresentationTag
static const int kNodeStateMask
static const int kUndefinedValueRootIndex
static V8_INLINE int SmiValue(Address value)
static V8_INLINE constexpr bool IsValidSmi(intptr_t value)
static const int kThrowOnError
static const int kEmbedderDataSlotExternalPointerOffset
static const int kBuiltinTier0TableSize
static V8_INLINE Address ReadTaggedSignedField(Address heap_object_ptr, int offset)
static V8_INLINE T ReadRawField(Address heap_object_ptr, int offset)
static V8_INLINE void CheckInitialized(v8::Isolate *isolate)
static const uint32_t kNumIsolateDataSlots
static V8_INLINE Address * GetRootSlot(v8::Isolate *isolate, int index)
static const int kBuiltinTier0EntryTableSize
static const int kStackGuardSize
static const int kIsolateFastApiCallTargetOffset
static V8_INLINE constexpr bool CanHaveInternalField(int instance_type)
static V8_INLINE v8::Isolate * GetIsolateForSandbox(Address obj)
static const int kNodeFlagsOffset
static const int kLastJSApiObjectType
static const int kExternalOneByteRepresentationTag
static const int kNodeStateIsWeakValue
static V8_EXPORT void CheckInitializedImpl(v8::Isolate *isolate)
static const int kBuiltinTier0TableOffset
static const int kForeignType
static const int kNodeClassIdOffset
static V8_INLINE int GetInstanceType(Address obj)
static const int kIsolateRootsOffset
static const int kFirstJSApiObjectType
static const int kOddballType
static const int kMapInstanceTypeOffset
static const int kLinearAllocationAreaSize
static const int kIsolateEmbedderDataOffset
static V8_INLINE int GetOddballKind(Address obj)
static V8_INLINE void * GetEmbedderData(const v8::Isolate *isolate, uint32_t slot)
static const int kNewAllocationInfoOffset
static const int kUndefinedOddballKind
static const int kEmbedderDataSlotSize
static const int kHeapObjectMapOffset
static V8_INLINE Address ReadTaggedPointerField(Address heap_object_ptr, int offset)
static const int kTracedNodeClassIdOffset
static const int kNullOddballKind
static V8_INLINE bool IsExternalTwoByteString(int instance_type)
static V8_INLINE constexpr Address IntToSmi(int value)
static const int kFirstNonstringType
static V8_INLINE void UpdateNodeState(Address *obj, uint8_t value)
static const int kBuiltinTier0EntryTableOffset
static const int kStringEncodingMask
static const int kExternalPointerTableBufferOffset
static V8_INLINE Address GetRoot(v8::Isolate *isolate, int index)
static const int kVariousBooleanFlagsOffset
static const int kThreadLocalTopSize
static const int kJSObjectHeaderSize
static V8_INLINE void SetEmbedderData(v8::Isolate *isolate, uint32_t slot, void *data)
static const int kFixedArrayHeaderSize
static const int kJSObjectType
static const int kTheHoleValueRootIndex
static V8_INLINE Address ReadExternalPointerField(v8::Isolate *isolate, Address heap_object_ptr, int offset)
static const int kStringResourceOffset
static const int kIsolateFastCCallCallerFpOffset
static V8_INLINE Address ValueAsAddress(const T *value)
static V8_INLINE T * ValueAsSlot(T *const &value)
static V8_INLINE T * SlotAsValue(S *slot)
static constexpr T * EmptyValue()
constexpr bool PointerCompressionIsEnabled()
Address SandboxedPointer_t
const int kApiSystemPointerSize
constexpr uint64_t kAllExternalPointerTypeTags[]
Address ExternalPointer_t
constexpr uint64_t kExternalPointerTagShift
const intptr_t kHeapObjectTagMask
const int kHeapObjectTagSize
const intptr_t kForwardingTagMask
SmiTagging< kApiTaggedSize > PlatformSmiTagging
V8_EXPORT internal::Isolate * IsolateFromNeverReadOnlySpaceObject(Address obj)
constexpr bool SmiValuesAre32Bits()
constexpr bool SmiValuesAre31Bits()
constexpr uintptr_t kUintptrAllBitsSet
@ kExternalPointerNullTag
@ kExternalPointerFreeEntryTag
@ kExternalPointerEvacuationEntryTag
uint32_t ExternalPointerHandle
constexpr uint64_t kExternalPointerTagMask
const int kForwardingTagSize
V8_INLINE void PerformCastCheck(T *data)
constexpr bool SandboxIsEnabled()
const int kWeakHeapObjectTag
V8_EXPORT bool ShouldThrowOnError(internal::Isolate *isolate)
constexpr intptr_t kIntptrAllBitsSet
const intptr_t kHeapObjectReferenceTagMask
const intptr_t kSmiTagMask
constexpr uint64_t kExternalPointerMarkBit
constexpr int kGarbageCollectionReasonMaxValue
static void Perform(T *data)
static V8_INLINE constexpr bool IsValidSmi(intptr_t value)
static V8_INLINE int SmiToInt(Address value)
static V8_INLINE constexpr bool IsValidSmi(intptr_t value)
static V8_INLINE int SmiToInt(Address value)
#define EXTERNAL_POINTER_TAG_ENUM(Name, Tag)
#define ALL_EXTERNAL_POINTER_TAGS(V)
#define CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS(Tag,...)
#define SHARED_EXTERNAL_POINTER_TAGS(V)
#define MAKE_TAG(HasMarkBit, TypeTag)
#define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V)
#define CHECK_SHARED_EXTERNAL_POINTER_TAGS(Tag,...)