/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/sandbox/external-pointer-inl.h
164 строки
7 KB
Michaël Zasso
deps: update V8 to 14.3.127.12
13 ноя 2025, 17:08
Не верифицирован
13 ноя 2025, 17:08
53379f3
Код
Авторство
О чём код?
// Copyright 2020 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_SANDBOX_EXTERNAL_POINTER_INL_H_ #define V8_SANDBOX_EXTERNAL_POINTER_INL_H_ #include "src/sandbox/external-pointer.h" // Include the non-inl header before the rest of the headers. #include "include/v8-internal.h" #include "src/base/atomic-utils.h" #include "src/objects/slots-inl.h" #include "src/sandbox/external-pointer-table-inl.h" #include "src/sandbox/isolate-inl.h" #include "src/sandbox/isolate.h" namespace v8 { namespace internal { template <ExternalPointerTag tag> inline void ExternalPointerMember<tag>::Init(Address host_address, IsolateForSandbox isolate, Address value) { InitExternalPointerField<tag>( host_address, reinterpret_cast<Address>(storage_), isolate, value); } template <ExternalPointerTag tag> inline Address ExternalPointerMember<tag>::load( const IsolateForSandbox isolate) const { return ReadExternalPointerField<tag>(reinterpret_cast<Address>(storage_), isolate); } template <ExternalPointerTag tag> inline void ExternalPointerMember<tag>::store(IsolateForSandbox isolate, Address value) { WriteExternalPointerField<tag>(reinterpret_cast<Address>(storage_), isolate, value); } template <ExternalPointerTag tag> inline ExternalPointer_t ExternalPointerMember<tag>::load_encoded() const { return base::bit_cast<ExternalPointer_t>(storage_); } template <ExternalPointerTag tag> inline void ExternalPointerMember<tag>::store_encoded(ExternalPointer_t value) { memcpy(storage_, &value, sizeof(ExternalPointer_t)); } template <ExternalPointerTag tag> V8_INLINE void InitExternalPointerField(Address host_address, Address field_address, IsolateForSandbox isolate, Address value) { #ifdef V8_ENABLE_SANDBOX static_assert(tag != kExternalPointerNullTag); ExternalPointerTable& table = isolate.GetExternalPointerTableFor(tag); ExternalPointerHandle handle = table.AllocateAndInitializeEntry( isolate.GetExternalPointerTableSpaceFor(tag, host_address), value, tag); // Use a Release_Store to ensure that the store of the pointer into the // table is not reordered after the store of the handle. Otherwise, other // threads may access an uninitialized table entry and crash. auto location = reinterpret_cast<ExternalPointerHandle*>(field_address); base::AsAtomic32::Release_Store(location, handle); #else WriteExternalPointerField<tag>(field_address, isolate, value); #endif // V8_ENABLE_SANDBOX } V8_INLINE void InitExternalPointerField(Address host_address, Address field_address, IsolateForSandbox isolate, ExternalPointerTag tag, Address value) { #ifdef V8_ENABLE_SANDBOX DCHECK_NE(tag, kExternalPointerNullTag); ExternalPointerTable& table = isolate.GetExternalPointerTableFor(tag); ExternalPointerHandle handle = table.AllocateAndInitializeEntry( isolate.GetExternalPointerTableSpaceFor(tag, host_address), value, tag); // Use a Release_Store to ensure that the store of the pointer into the // table is not reordered after the store of the handle. Otherwise, other // threads may access an uninitialized table entry and crash. auto location = reinterpret_cast<ExternalPointerHandle*>(field_address); base::AsAtomic32::Release_Store(location, handle); #else WriteExternalPointerField(field_address, isolate, tag, value); #endif // V8_ENABLE_SANDBOX } template <ExternalPointerTagRange tag_range> V8_INLINE Address ReadExternalPointerField(Address field_address, IsolateForSandbox isolate) { #ifdef V8_ENABLE_SANDBOX // static_assert(tag != kExternalPointerNullTag); // TODO // Handles may be written to objects from other threads so the handle needs // to be loaded atomically. We assume that the load from the table cannot // be reordered before the load of the handle due to the data dependency // between the two loads and therefore use relaxed memory ordering, but // technically we should use memory_order_consume here. auto location = reinterpret_cast<ExternalPointerHandle*>(field_address); ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location); return isolate.GetExternalPointerTableFor(tag_range).Get(handle, tag_range); #else return ReadMaybeUnalignedValue<Address>(field_address); #endif // V8_ENABLE_SANDBOX } V8_INLINE Address ReadExternalPointerField(Address field_address, IsolateForSandbox isolate, ExternalPointerTagRange tag_range) { #ifdef V8_ENABLE_SANDBOX DCHECK_NE(tag_range.first, kExternalPointerNullTag); // Handles may be written to objects from other threads so the handle needs // to be loaded atomically. We assume that the load from the table cannot // be reordered before the load of the handle due to the data dependency // between the two loads and therefore use relaxed memory ordering, but // technically we should use memory_order_consume here. auto location = reinterpret_cast<ExternalPointerHandle*>(field_address); ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location); return isolate.GetExternalPointerTableFor(tag_range).Get(handle, tag_range); #else return ReadMaybeUnalignedValue<Address>(field_address); #endif // V8_ENABLE_SANDBOX } template <ExternalPointerTag tag> V8_INLINE void WriteExternalPointerField(Address field_address, IsolateForSandbox isolate, Address value) { #ifdef V8_ENABLE_SANDBOX static_assert(tag != kExternalPointerNullTag); // See comment above for why this is a Relaxed_Load. auto location = reinterpret_cast<ExternalPointerHandle*>(field_address); ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location); isolate.GetExternalPointerTableFor(tag).Set(handle, value, tag); #else WriteMaybeUnalignedValue<Address>(field_address, value); #endif // V8_ENABLE_SANDBOX } V8_INLINE void WriteExternalPointerField(Address field_address, IsolateForSandbox isolate, ExternalPointerTag tag, Address value) { #ifdef V8_ENABLE_SANDBOX DCHECK_NE(tag, kExternalPointerNullTag); // See comment above for why this is a Relaxed_Load. auto location = reinterpret_cast<ExternalPointerHandle*>(field_address); ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location); isolate.GetExternalPointerTableFor(tag).Set(handle, value, tag); #else WriteMaybeUnalignedValue<Address>(field_address, value); #endif // V8_ENABLE_SANDBOX } V8_INLINE void SetupLazilyInitializedExternalPointerField( Address field_address) {} } // namespace internal } // namespace v8 #endif // V8_SANDBOX_EXTERNAL_POINTER_INL_H_