1 // Copyright 2018 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_BOUNDED_PAGE_ALLOCATOR_H_ 6 #define V8_BASE_BOUNDED_PAGE_ALLOCATOR_H_ 7 8 #include "include/v8-platform.h" 9 #include "src/base/platform/mutex.h" 10 #include "src/base/region-allocator.h" 11 12 namespace v8 { 13 namespace base { 14 15 // This is a v8::PageAllocator implementation that allocates pages within the 16 // pre-reserved region of virtual space. This class requires the virtual space 17 // to be kept reserved during the lifetime of this object. 18 // The main application of bounded page allocator are 19 // - V8 heap pointer compression which requires the whole V8 heap to be 20 // allocated within a contiguous range of virtual address space, 21 // - executable page allocation, which allows to use PC-relative 32-bit code 22 // displacement on certain 64-bit platforms. 23 // Bounded page allocator uses other page allocator instance for doing actual 24 // page allocations. 25 // The implementation is thread-safe. 26 class V8_BASE_EXPORT BoundedPageAllocator : public v8::PageAllocator { 27 public: 28 using Address = uintptr_t; 29 30 BoundedPageAllocator(v8::PageAllocator* page_allocator, Address start, 31 size_t size, size_t allocate_page_size); 32 BoundedPageAllocator(const BoundedPageAllocator&) = delete; 33 BoundedPageAllocator& operator=(const BoundedPageAllocator&) = delete; 34 ~BoundedPageAllocator() override = default; 35 36 // These functions are not inlined to avoid https://crbug.com/v8/8275. 37 Address begin() const; 38 size_t size() const; 39 40 // Returns true if given address is in the range controlled by the bounded 41 // page allocator instance. contains(Address address)42 bool contains(Address address) const { 43 return region_allocator_.contains(address); 44 } 45 AllocatePageSize()46 size_t AllocatePageSize() override { return allocate_page_size_; } 47 CommitPageSize()48 size_t CommitPageSize() override { return commit_page_size_; } 49 SetRandomMmapSeed(int64_t seed)50 void SetRandomMmapSeed(int64_t seed) override { 51 page_allocator_->SetRandomMmapSeed(seed); 52 } 53 GetRandomMmapAddr()54 void* GetRandomMmapAddr() override { 55 return page_allocator_->GetRandomMmapAddr(); 56 } 57 58 void* AllocatePages(void* hint, size_t size, size_t alignment, 59 Permission access) override; 60 61 bool ReserveForSharedMemoryMapping(void* address, size_t size) override; 62 63 // Allocates pages at given address, returns true on success. 64 bool AllocatePagesAt(Address address, size_t size, Permission access); 65 66 bool FreePages(void* address, size_t size) override; 67 68 bool ReleasePages(void* address, size_t size, size_t new_size) override; 69 70 bool SetPermissions(void* address, size_t size, Permission access) override; 71 72 bool DiscardSystemPages(void* address, size_t size) override; 73 74 private: 75 v8::base::Mutex mutex_; 76 const size_t allocate_page_size_; 77 const size_t commit_page_size_; 78 v8::PageAllocator* const page_allocator_; 79 v8::base::RegionAllocator region_allocator_; 80 }; 81 82 } // namespace base 83 } // namespace v8 84 85 #endif // V8_BASE_BOUNDED_PAGE_ALLOCATOR_H_ 86