5#ifndef V8_COMMON_CODE_MEMORY_ACCESS_H_
6#define V8_COMMON_CODE_MEMORY_ACCESS_H_
38class RwxMemoryWriteScopeForTesting;
40class CodeSpaceWriteScope;
43#if V8_HAS_PKU_JIT_WRITE_PROTECT
52#define THREAD_ISOLATION_ALIGN_SZ 0x1000
53#define THREAD_ISOLATION_ALIGN alignas(THREAD_ISOLATION_ALIGN_SZ)
54#define THREAD_ISOLATION_ALIGN_OFFSET_MASK (THREAD_ISOLATION_ALIGN_SZ - 1)
55#define THREAD_ISOLATION_FILL_PAGE_SZ(size) \
56 ((THREAD_ISOLATION_ALIGN_SZ - \
57 ((size) & THREAD_ISOLATION_ALIGN_OFFSET_MASK)) % \
58 THREAD_ISOLATION_ALIGN_SZ)
62#define THREAD_ISOLATION_ALIGN_SZ 0
63#define THREAD_ISOLATION_ALIGN
64#define THREAD_ISOLATION_FILL_PAGE_SZ(size) 0
106#if V8_HAS_PKU_JIT_WRITE_PROTECT
107 static int memory_protection_key();
109 static bool IsPKUWritable();
114 static V8_EXPORT void SetDefaultPermissionsForSignalHandler();
120 friend class WritableJumpTablePair;
131class WritableJumpTablePair;
144 static bool Enabled();
152 kWasmLazyCompileTable,
156 static void RegisterJitPage(Address address,
size_t size);
158 static void UnregisterJitPage(Address address,
size_t size);
161 V8_NODISCARD static bool MakeExecutable(Address address,
size_t size);
167 Address addr,
size_t size, JitAllocationType type,
168 bool enforce_write_api =
false);
172 Address addr,
size_t size,
bool enforce_write_api =
false);
174 static void RegisterJitAllocations(Address
start,
175 const std::vector<size_t>& sizes,
176 JitAllocationType type);
184 Address addr,
size_t size, JitAllocationType type,
185 bool enforce_write_api =
false);
187#ifdef V8_ENABLE_WEBASSEMBLY
190 static WritableJumpTablePair LookupJumpTableAllocations(
191 Address jump_table_address,
size_t jump_table_size,
192 Address far_jump_table_address,
size_t far_jump_table_size);
197 static WritableJitPage LookupWritableJitPage(Address addr,
size_t size);
199 static void UnregisterWasmAllocation(Address addr,
size_t size);
203 static bool CanLookupStartOfJitAllocationAt(Address inner_pointer);
204 static std::optional<Address> StartOfJitAllocationAt(Address inner_pointer);
211 static void RegisterJitAllocationForTesting(Address obj,
size_t size);
212 static void UnregisterJitAllocationForTesting(Address addr,
size_t size);
214#if V8_HAS_PKU_JIT_WRITE_PROTECT
215 static int pkey() {
return trusted_data_.pkey; }
216 static bool PkeyIsAvailable() {
return trusted_data_.pkey != -1; }
220 static bool initialized() {
return trusted_data_.initialized; }
221 static void CheckTrackedMemoryEmpty();
237 ThreadIsolation::allocator()->Allocate(n *
sizeof(
value_type)));
239 return static_cast<value_type*
>(::operator
new(n *
sizeof(
T)));
245 ThreadIsolation::allocator()->Free(ptr);
247 ::operator
delete(ptr);
275 base::Address Address()
const {
return address_; }
286 const std::vector<base::Address>& addr);
290 std::pair<base::Address, JitAllocation&> AllocationContaining(
293 bool Empty()
const {
return jit_page_->allocations_.empty(); }
294 void Shrink(
class JitPage* tail);
295 void Expand(
size_t offset);
314 typedef std::map<Address, JitAllocation, std::less<Address>,
322 friend bool ThreadIsolation::CanLookupStartOfJitAllocationAt(Address);
327 return trusted_data_.allocator;
332 typedef std::map<Address, JitPage*, std::less<Address>,
333 StlAllocator<std::pair<const Address, JitPage*>>>
341#if V8_HAS_PKU_JIT_WRITE_PROTECT
349 bool initialized =
false;
360 template <
typename T,
typename... Args>
361 static void ConstructNew(T** ptr, Args&&...
args);
362 template <
typename T>
363 static void Delete(T* ptr);
372 static std::optional<JitPageReference> TryLookupJitPage(Address addr,
375 static std::optional<JitPageReference> TryLookupJitPageLocked(Address addr,
379 static std::pair<JitPageReference, JitPageReference> SplitJitPages(
380 Address addr1,
size_t size1, Address addr2,
size_t size2);
386 friend class WritableJumpTablePair;
413 template <
typename T,
size_t offset>
415 template <
typename T,
size_t offset>
417 template <
typename T,
size_t offset>
419 template <
typename T,
size_t offset>
422 template <
typename T,
size_t offset>
425 template <
typename T>
435 template <
typename T>
437 template <
typename T>
439 template <
typename T>
455 bool enforce_write_api =
false);
459 bool enforce_write_api);
477 std::optional<ThreadIsolation::JitPageReference>
page_ref_;
504 template <
typename T,
size_t offset>
506 template <
size_t offset>
541 bool Empty()
const {
return page_ref_.Empty(); }
548#ifdef V8_ENABLE_WEBASSEMBLY
553 WritableJitAllocation& far_jump_table() {
return writable_far_jump_table_; }
555 ~WritableJumpTablePair();
556 WritableJumpTablePair(
const WritableJumpTablePair&) =
delete;
557 WritableJumpTablePair& operator=(
const WritableJumpTablePair&) =
delete;
559 static WritableJumpTablePair ForTesting(
Address jump_table_address,
560 size_t jump_table_size,
561 Address far_jump_table_address,
562 size_t far_jump_table_size);
566 size_t jump_table_size,
567 Address far_jump_table_address,
568 size_t far_jump_table_size);
571 struct ForTestingTag {};
572 WritableJumpTablePair(
Address jump_table_address,
size_t jump_table_size,
573 Address far_jump_table_address,
574 size_t far_jump_table_size, ForTestingTag);
579 WritableJitAllocation writable_jump_table_;
580 WritableJitAllocation writable_far_jump_table_;
582 RwxMemoryWriteScope write_scope_;
583 std::optional<std::pair<ThreadIsolation::JitPageReference,
584 ThreadIsolation::JitPageReference>>
587 friend class ThreadIsolation;
631#if V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT
638#ifdef V8_ENABLE_MEMORY_SEALING
V8_INLINE NopRwxMemoryWriteScope()=default
V8_INLINE NopRwxMemoryWriteScope(const char *comment)
RwxMemoryWriteScopeForTesting(const RwxMemoryWriteScopeForTesting &)=delete
RwxMemoryWriteScopeForTesting & operator=(const RwxMemoryWriteScopeForTesting &)=delete
RwxMemoryWriteScope(const RwxMemoryWriteScope &)=delete
RwxMemoryWriteScope & operator=(const RwxMemoryWriteScope &)=delete
JitAllocation(size_t size, JitAllocationType type)
JitAllocationType Type() const
AllocationMap allocations_
std::map< Address, JitAllocation, std::less< Address >, StlAllocator< std::pair< const Address, JitAllocation > > > AllocationMap
std::map< Address, JitPage *, std::less< Address >, StlAllocator< std::pair< const Address, JitPage * > > > JitPageMap
static ThreadIsolatedAllocator * allocator()
V8_INLINE void WriteHeaderSlot(Tagged< T > value, RelaxedStoreTag) const
V8_INLINE ~WritableFreeSpace()
WritableFreeSpace & operator=(const WritableFreeSpace &)=delete
void ClearTagged(size_t count) const
WritableFreeSpace(const WritableFreeSpace &)=delete
static V8_INLINE WritableFreeSpace ForNonExecutableMemory(base::Address addr, size_t size)
const base::Address address_
base::Address Address() const
friend class WritableJumpTablePair
static V8_INLINE WritableJitAllocation ForNonExecutableMemory(Address addr, size_t size, ThreadIsolation::JitAllocationType type)
ThreadIsolation::JitPageReference & page_ref()
V8_INLINE void WriteUnalignedValue(Address address, T value)
const ThreadIsolation::JitAllocation allocation_
V8_INLINE void CopyCode(size_t dst_offset, const uint8_t *src, size_t num_bytes)
V8_INLINE void WriteValue(Address address, T value)
static WritableJitAllocation ForInstructionStream(Tagged< InstructionStream > istream)
std::optional< ThreadIsolation::JitPageReference > page_ref_
V8_INLINE void WriteHeaderSlot(Tagged< T > value, RelaxedStoreTag)
V8_INLINE void WriteHeaderSlot(T value)
V8_INLINE void WriteProtectedPointerHeaderSlot(Tagged< T > value, RelaxedStoreTag)
V8_INLINE ~WritableJitAllocation()
V8_INLINE void ClearBytes(size_t offset, size_t len)
V8_INLINE void WriteProtectedPointerHeaderSlot(Tagged< T > value, ReleaseStoreTag)
V8_INLINE void WriteHeaderSlot(Tagged< T > value, ReleaseStoreTag)
WritableJitAllocation(const WritableJitAllocation &)=delete
V8_INLINE void CopyData(size_t dst_offset, const uint8_t *src, size_t num_bytes)
V8_INLINE std::optional< RwxMemoryWriteScope > WriteScopeForApiEnforcement() const
std::optional< RwxMemoryWriteScope > write_scope_
WritableJitAllocation & operator=(const WritableJitAllocation &)=delete
RwxMemoryWriteScope write_scope_
V8_INLINE ~WritableJitPage()
friend class ThreadIsolation
WritableJitPage(const WritableJitPage &)=delete
WritableJitPage & operator=(const WritableJitPage &)=delete
ThreadIsolation::JitPageReference page_ref_
#define THREAD_ISOLATION_ALIGN
#define THREAD_ISOLATION_ALIGN_SZ
base::Vector< const DirectHandle< Object > > args
bool operator!=(ExternalReference lhs, ExternalReference rhs)
bool operator==(ExternalReference lhs, ExternalReference rhs)
#define V8_EXPORT_PRIVATE
void deallocate(value_type *ptr, size_t n)
value_type * allocate(size_t n)
StlAllocator(const StlAllocator< U > &) noexcept
base::Mutex * jit_pages_mutex_