1 // Copyright 2021 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 V8_BASE_VIRTUAL_ADDRESS_SPACE_H_ 6 #define V8_BASE_VIRTUAL_ADDRESS_SPACE_H_ 7 8 #include "include/v8-platform.h" 9 #include "src/base/base-export.h" 10 #include "src/base/compiler-specific.h" 11 #include "src/base/platform/platform.h" 12 #include "src/base/region-allocator.h" 13 14 namespace v8 { 15 namespace base { 16 17 using Address = uintptr_t; 18 constexpr Address kNullAddress = 0; 19 20 class VirtualAddressSubspace; 21 22 /* 23 * Common parent class to implement deletion of subspaces. 24 */ 25 class VirtualAddressSpaceBase NON_EXPORTED_BASE(::v8::VirtualAddressSpace)26 : public NON_EXPORTED_BASE(::v8::VirtualAddressSpace) { 27 public: 28 using VirtualAddressSpace::VirtualAddressSpace; 29 30 private: 31 friend VirtualAddressSubspace; 32 // Called by a subspace during destruction. Responsible for freeing the 33 // address space reservation and any other data associated with the subspace 34 // in the parent space. 35 virtual void FreeSubspace(VirtualAddressSubspace* subspace) = 0; 36 }; 37 38 /* 39 * Helper routine to determine whether one set of page permissions (the lhs) is 40 * a subset of another one (the rhs). 41 */ 42 V8_BASE_EXPORT bool IsSubset(PagePermissions lhs, PagePermissions rhs); 43 44 /* 45 * The virtual address space of the current process. Conceptionally, there 46 * should only be one such "root" instance. However, in practice there is no 47 * issue with having multiple instances as the actual resources are managed by 48 * the OS kernel. 49 */ 50 class V8_BASE_EXPORT VirtualAddressSpace : public VirtualAddressSpaceBase { 51 public: 52 VirtualAddressSpace(); 53 ~VirtualAddressSpace() override = default; 54 55 void SetRandomSeed(int64_t seed) override; 56 57 Address RandomPageAddress() override; 58 59 Address AllocatePages(Address hint, size_t size, size_t alignment, 60 PagePermissions access) override; 61 62 void FreePages(Address address, size_t size) override; 63 64 bool SetPagePermissions(Address address, size_t size, 65 PagePermissions access) override; 66 67 bool AllocateGuardRegion(Address address, size_t size) override; 68 69 void FreeGuardRegion(Address address, size_t size) override; 70 71 Address AllocateSharedPages(Address hint, size_t size, 72 PagePermissions permissions, 73 PlatformSharedMemoryHandle handle, 74 uint64_t offset) override; 75 76 void FreeSharedPages(Address address, size_t size) override; 77 78 bool CanAllocateSubspaces() override; 79 80 std::unique_ptr<v8::VirtualAddressSpace> AllocateSubspace( 81 Address hint, size_t size, size_t alignment, 82 PagePermissions max_page_permissions) override; 83 84 bool DiscardSystemPages(Address address, size_t size) override; 85 86 bool DecommitPages(Address address, size_t size) override; 87 88 private: 89 void FreeSubspace(VirtualAddressSubspace* subspace) override; 90 }; 91 92 /* 93 * A subspace of a parent virtual address space. This represents a reserved 94 * contiguous region of virtual address space in the current process. 95 */ 96 class V8_BASE_EXPORT VirtualAddressSubspace : public VirtualAddressSpaceBase { 97 public: 98 ~VirtualAddressSubspace() override; 99 100 void SetRandomSeed(int64_t seed) override; 101 102 Address RandomPageAddress() override; 103 104 Address AllocatePages(Address hint, size_t size, size_t alignment, 105 PagePermissions permissions) override; 106 107 void FreePages(Address address, size_t size) override; 108 109 bool SetPagePermissions(Address address, size_t size, 110 PagePermissions permissions) override; 111 112 bool AllocateGuardRegion(Address address, size_t size) override; 113 114 void FreeGuardRegion(Address address, size_t size) override; 115 116 Address AllocateSharedPages(Address hint, size_t size, 117 PagePermissions permissions, 118 PlatformSharedMemoryHandle handle, 119 uint64_t offset) override; 120 121 void FreeSharedPages(Address address, size_t size) override; 122 CanAllocateSubspaces()123 bool CanAllocateSubspaces() override { return true; } 124 125 std::unique_ptr<v8::VirtualAddressSpace> AllocateSubspace( 126 Address hint, size_t size, size_t alignment, 127 PagePermissions max_page_permissions) override; 128 129 bool DiscardSystemPages(Address address, size_t size) override; 130 131 bool DecommitPages(Address address, size_t size) override; 132 133 private: 134 // The VirtualAddressSpace class creates instances of this class when 135 // allocating sub spaces. 136 friend class v8::base::VirtualAddressSpace; 137 138 void FreeSubspace(VirtualAddressSubspace* subspace) override; 139 140 VirtualAddressSubspace(AddressSpaceReservation reservation, 141 VirtualAddressSpaceBase* parent_space, 142 PagePermissions max_page_permissions); 143 144 // The address space reservation backing this subspace. 145 AddressSpaceReservation reservation_; 146 147 // Mutex guarding the non-threadsafe RegionAllocator and 148 // RandomNumberGenerator. 149 Mutex mutex_; 150 151 // RegionAllocator to manage the virtual address reservation and divide it 152 // into further regions as necessary. 153 RegionAllocator region_allocator_; 154 155 // Random number generator for generating random addresses. 156 RandomNumberGenerator rng_; 157 158 // Pointer to the parent space. Must be kept alive by the owner of this 159 // instance during its lifetime. 160 VirtualAddressSpaceBase* parent_space_; 161 }; 162 163 } // namespace base 164 } // namespace v8 165 #endif // V8_BASE_VIRTUAL_ADDRESS_SPACE_H_ 166