/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/common/ptr-compr-inl.h
383 строки
12 KB
Michaël Zasso
deps: update V8 to 14.1.146.11
04 окт 2025, 19:47
Не верифицирован
04 окт 2025, 19:47
7772a2d
Код
Авторство
О чём код?
// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_COMMON_PTR_COMPR_INL_H_ #define V8_COMMON_PTR_COMPR_INL_H_ #include "src/common/ptr-compr.h" // Include the non-inl header before the rest of the headers. #include "src/common/globals.h" #include "src/execution/isolate.h" #include "src/objects/tagged.h" #include "src/utils/utils.h" #ifdef V8_ENABLE_SANDBOX #include "src/sandbox/sandbox.h" #endif // V8_ENABLE_SANDBOX namespace v8 { namespace internal { #ifdef V8_COMPRESS_POINTERS // Always return the global/thread local cage base for isolate PtrComprCageBase::PtrComprCageBase(const Isolate* isolate) : address_(V8HeapCompressionScheme::base()) {} PtrComprCageBase::PtrComprCageBase(const LocalIsolate* isolate) : address_(V8HeapCompressionScheme::base()) {} // // V8HeapCompressionSchemeImpl // constexpr Address kPtrComprCageBaseMask = ~(kPtrComprCageBaseAlignment - 1); // static template <typename Cage> constexpr Address V8HeapCompressionSchemeImpl<Cage>::GetPtrComprCageBaseAddress( Address on_heap_addr) { return RoundDown<kPtrComprCageBaseAlignment>(on_heap_addr); } // static template <typename Cage> Address V8HeapCompressionSchemeImpl<Cage>::GetPtrComprCageBaseAddress( PtrComprCageBase cage_base) { Address base = cage_base.address(); V8_ASSUME((base & kPtrComprCageBaseMask) == base); base = reinterpret_cast<Address>(V8_ASSUME_ALIGNED( reinterpret_cast<void*>(base), kPtrComprCageBaseAlignment)); return base; } // static template <typename Cage> void V8HeapCompressionSchemeImpl<Cage>::InitBase(Address base) { CHECK_EQ(base, GetPtrComprCageBaseAddress(base)); #if defined(USING_V8_SHARED_PRIVATE) && \ defined(V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES) Cage::set_base_non_inlined(base); #else Cage::base_ = base; #endif } // static template <typename Cage> Address V8HeapCompressionSchemeImpl<Cage>::base() { #if defined(USING_V8_SHARED_PRIVATE) && \ defined(V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES) Address base = Cage::base_non_inlined(); #else Address base = Cage::base_; #endif // V8_ASSUME_ALIGNED is often not preserved across ptr-to-int casts (i.e. when // casting to an Address). To increase our chances we additionally encode the // same information in this V8_ASSUME. V8_ASSUME((base & kPtrComprCageBaseMask) == base); return reinterpret_cast<Address>(V8_ASSUME_ALIGNED( reinterpret_cast<void*>(base), kPtrComprCageBaseAlignment)); } // static template <typename Cage> Tagged_t V8HeapCompressionSchemeImpl<Cage>::CompressObject(Address tagged) { #ifdef V8_COMPRESS_POINTERS // Ensure that we do not accidentally compress value from a different cage. // Cleared weak reference must be either pure (with empty upper part) or // belong to the same cage. DCHECK_IMPLIES( !HAS_SMI_TAG(tagged) && (tagged != kClearedWeakHeapObjectLower32), (tagged & kPtrComprCageBaseMask) == base()); #endif return static_cast<Tagged_t>(tagged); } // static template <typename Cage> constexpr Tagged_t V8HeapCompressionSchemeImpl<Cage>::CompressAny( Address tagged) { return static_cast<Tagged_t>(tagged); } // static template <typename Cage> Address V8HeapCompressionSchemeImpl<Cage>::DecompressTaggedSigned( Tagged_t raw_value) { // For runtime code the upper 32-bits of the Smi value do not matter. return static_cast<Address>(raw_value); } // static template <typename Cage> Address V8HeapCompressionSchemeImpl<Cage>::DecompressTagged( Tagged_t raw_value) { #ifdef V8_COMPRESS_POINTERS Address cage_base = base(); #ifdef V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES DCHECK_WITH_MSG(cage_base != kNullAddress, "V8HeapCompressionSchemeImpl::base is not initialized for " "current thread"); #endif // V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES #else Address cage_base = GetPtrComprCageBaseAddress(on_heap_addr); #endif // V8_COMPRESS_POINTERS Address result = cage_base + static_cast<Address>(raw_value); V8_ASSUME(static_cast<uint32_t>(result) == raw_value); return result; } // static template <typename Cage> template <typename ProcessPointerCallback> void V8HeapCompressionSchemeImpl<Cage>::ProcessIntermediatePointers( Address raw_value, ProcessPointerCallback callback) { // If pointer compression is enabled, we may have random compressed pointers // on the stack that may be used for subsequent operations. // Extract, decompress and trace both halfwords. Address decompressed_low = V8HeapCompressionSchemeImpl<Cage>::DecompressTagged( static_cast<Tagged_t>(raw_value)); callback(decompressed_low); Address decompressed_high = V8HeapCompressionSchemeImpl<Cage>::DecompressTagged( static_cast<Tagged_t>(raw_value >> (sizeof(Tagged_t) * CHAR_BIT))); callback(decompressed_high); } #ifdef V8_EXTERNAL_CODE_SPACE // // ExternalCodeCompressionScheme // constexpr Address kMinExpectedOSPageSizeMask = ~(kMinExpectedOSPageSize - 1); // static Address ExternalCodeCompressionScheme::PrepareCageBaseAddress( Address on_heap_addr) { return RoundDown<kMinExpectedOSPageSize>(on_heap_addr); } // static Address ExternalCodeCompressionScheme::GetPtrComprCageBaseAddress( PtrComprCageBase cage_base) { Address base = cage_base.address(); V8_ASSUME((base & kMinExpectedOSPageSizeMask) == base); base = reinterpret_cast<Address>( V8_ASSUME_ALIGNED(reinterpret_cast<void*>(base), kMinExpectedOSPageSize)); return base; } // static void ExternalCodeCompressionScheme::InitBase(Address base) { CHECK_EQ(base, PrepareCageBaseAddress(base)); #if defined(USING_V8_SHARED_PRIVATE) && \ defined(V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES) set_base_non_inlined(base); #else base_ = base; #endif } // static V8_CONST Address ExternalCodeCompressionScheme::base() { #if defined(USING_V8_SHARED_PRIVATE) && \ defined(V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES) Address base = base_non_inlined(); #else Address base = base_; #endif // V8_ASSUME_ALIGNED is often not preserved across ptr-to-int casts (i.e. when // casting to an Address). To increase our chances we additionally encode the // same information in this V8_ASSUME. V8_ASSUME((base & kMinExpectedOSPageSizeMask) == base); return reinterpret_cast<Address>( V8_ASSUME_ALIGNED(reinterpret_cast<void*>(base), kMinExpectedOSPageSize)); } // static Tagged_t ExternalCodeCompressionScheme::CompressObject(Address tagged) { // Sanity check - the tagged value should belong to this cage. #ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE DCHECK_IMPLIES( !HAS_SMI_TAG(tagged), (base() <= tagged) && (tagged < base() + kPtrComprCageReservationSize)); #endif return static_cast<Tagged_t>(tagged); } // static constexpr Tagged_t ExternalCodeCompressionScheme::CompressAny(Address tagged) { return static_cast<Tagged_t>(tagged); } // static Address ExternalCodeCompressionScheme::DecompressTagged(Tagged_t raw_value) { Address cage_base = base(); #ifdef V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES DCHECK_WITH_MSG(cage_base != kNullAddress, "ExternalCodeCompressionScheme::base is not initialized for " "current thread"); #endif // V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES V8_ASSUME((cage_base & kMinExpectedOSPageSizeMask) == cage_base); Address diff = static_cast<Address>(static_cast<uint32_t>(raw_value)) - static_cast<Address>(static_cast<uint32_t>(cage_base)); // The cage base value was chosen such that it's less or equal than any // pointer in the cage, thus if we got a negative diff then it means that // the decompressed value is off by 4GB. if (static_cast<intptr_t>(diff) < 0) { diff += size_t{4} * GB; } DCHECK(is_uint32(diff)); Address result = cage_base + diff; DCHECK_EQ(static_cast<uint32_t>(result), raw_value); return result; } // static template <typename ProcessPointerCallback> void ExternalCodeCompressionScheme::ProcessIntermediatePointers( Address raw_value, ProcessPointerCallback callback) { // If pointer compression is enabled, we may have random compressed pointers // on the stack that may be used for subsequent operations. // Extract, decompress and trace both halfwords. Address decompressed_low = ExternalCodeCompressionScheme::DecompressTagged( static_cast<Tagged_t>(raw_value)); callback(decompressed_low); Address decompressed_high = ExternalCodeCompressionScheme::DecompressTagged( static_cast<Tagged_t>(raw_value >> (sizeof(Tagged_t) * CHAR_BIT))); callback(decompressed_high); } #endif // V8_EXTERNAL_CODE_SPACE // // Misc functions. // V8_INLINE PtrComprCageBase GetPtrComprCageBaseFromOnHeapAddress(Address address) { return PtrComprCageBase( V8HeapCompressionScheme::GetPtrComprCageBaseAddress(address)); } // Load the main pointer compression cage base. V8_INLINE PtrComprCageBase GetPtrComprCageBase() { return PtrComprCageBase(V8HeapCompressionScheme::base()); } #else // // V8HeapCompressionSchemeImpl // // static template <typename Cage> constexpr Address V8HeapCompressionSchemeImpl<Cage>::GetPtrComprCageBaseAddress( Address on_heap_addr) { UNREACHABLE(); return {}; } // static template <typename Cage> Tagged_t V8HeapCompressionSchemeImpl<Cage>::CompressObject(Address tagged) { UNREACHABLE(); } // static template <typename Cage> constexpr Tagged_t V8HeapCompressionSchemeImpl<Cage>::CompressAny( Address tagged) { UNREACHABLE(); return {}; } // static template <typename Cage> Address V8HeapCompressionSchemeImpl<Cage>::DecompressTaggedSigned( Tagged_t raw_value) { UNREACHABLE(); } // static template <typename Cage> Address V8HeapCompressionSchemeImpl<Cage>::DecompressTagged( Tagged_t raw_value) { UNREACHABLE(); } // static template <typename Cage> template <typename ProcessPointerCallback> void V8HeapCompressionSchemeImpl<Cage>::ProcessIntermediatePointers( Address raw_value, ProcessPointerCallback callback) { UNREACHABLE(); } // // Misc functions. // V8_INLINE constexpr PtrComprCageBase GetPtrComprCageBaseFromOnHeapAddress( Address address) { return PtrComprCageBase(); } V8_INLINE PtrComprCageBase GetPtrComprCageBase() { return PtrComprCageBase(); } #endif // V8_COMPRESS_POINTERS V8_INLINE PtrComprCageBase GetPtrComprCageBase(Tagged<HeapObject> object) { return GetPtrComprCageBaseFromOnHeapAddress(object.ptr()); } #ifdef V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES PtrComprCageAccessScope::PtrComprCageAccessScope(Isolate* isolate) : cage_base_(V8HeapCompressionScheme::base()), #ifdef V8_EXTERNAL_CODE_SPACE code_cage_base_(ExternalCodeCompressionScheme::base()), #endif // V8_EXTERNAL_CODE_SPACE saved_current_isolate_group_(IsolateGroup::current()) #ifdef V8_ENABLE_SANDBOX , saved_trusted_cage_base_(TrustedSpaceCompressionScheme::base()), saved_current_sandbox_(Sandbox::current()) #endif // V8_ENABLE_SANDBOX { V8HeapCompressionScheme::InitBase(isolate->cage_base()); #ifdef V8_EXTERNAL_CODE_SPACE ExternalCodeCompressionScheme::InitBase(isolate->code_cage_base()); #endif // V8_EXTERNAL_CODE_SPACE IsolateGroup::set_current(isolate->isolate_group()); #ifdef V8_ENABLE_SANDBOX TrustedSpaceCompressionScheme::InitBase( isolate->isolate_group()->GetTrustedPtrComprCageBase()); Sandbox::set_current(isolate->isolate_group()->sandbox()); #endif // V8_ENABLE_SANDBOX } PtrComprCageAccessScope::~PtrComprCageAccessScope() { V8HeapCompressionScheme::InitBase(cage_base_); #ifdef V8_EXTERNAL_CODE_SPACE ExternalCodeCompressionScheme::InitBase(code_cage_base_); #endif // V8_EXTERNAL_CODE_SPACE IsolateGroup::set_current(saved_current_isolate_group_); #ifdef V8_ENABLE_SANDBOX TrustedSpaceCompressionScheme::InitBase(saved_trusted_cage_base_); Sandbox::set_current(saved_current_sandbox_); #endif // V8_ENABLE_SANDBOX } #endif // V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES } // namespace internal } // namespace v8 #endif // V8_COMMON_PTR_COMPR_INL_H_