// Copyright 2012 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_UTILS_ALLOCATION_H_ #define V8_UTILS_ALLOCATION_H_ #include "include/v8-platform.h" #include "src/base/address-region.h" #include "src/base/bounded-page-allocator.h" #include "src/base/compiler-specific.h" #include "src/base/platform/memory.h" #include "src/init/v8.h" namespace v8 { namespace base { class BoundedPageAllocator; } // namespace base namespace internal { class Isolate; // This file defines memory allocation functions. If a first attempt at an // allocation fails, these functions call back into the embedder, then attempt // the allocation a second time. The embedder callback must not reenter V8. // Superclass for classes managed with new & delete. class V8_EXPORT_PRIVATE Malloced { … }; // Function that may release reserved memory regions to allow failed allocations // to succeed. V8_EXPORT_PRIVATE void OnCriticalMemoryPressure(); template <typename T> T* NewArray(size_t size) { … } template <typename T, typename = typename std::enable_if< base::is_trivially_copyable<T>::value>::type> T* NewArray(size_t size, T default_val) { … } template <typename T> void DeleteArray(T* array) { … } template <typename T> struct ArrayDeleter { … }; ArrayUniquePtr; // The normal strdup functions use malloc. These versions of StrDup // and StrNDup uses new and calls the FatalProcessOutOfMemory handler // if allocation fails. V8_EXPORT_PRIVATE char* StrDup(const char* str); char* StrNDup(const char* str, int n); // Allocation policy for allocating in the C free store using malloc // and free. Used as the default policy for lists. class FreeStoreAllocationPolicy { … }; MallocFn; // Performs a malloc, with retry logic on failure. Returns nullptr on failure. // Call free to release memory allocated with this function. void* AllocWithRetry(size_t size, MallocFn = base::Malloc); // Performs a malloc, with retry logic on failure. Returns nullptr on failure. // Call free to release memory allocated with this function. base::AllocationResult<void*> AllocAtLeastWithRetry(size_t size); V8_EXPORT_PRIVATE void* AlignedAllocWithRetry(size_t size, size_t alignment); V8_EXPORT_PRIVATE void AlignedFree(void* ptr); // Returns platfrom page allocator instance. Guaranteed to be a valid pointer. V8_EXPORT_PRIVATE v8::PageAllocator* GetPlatformPageAllocator(); // Returns platfrom virtual memory space instance. Guaranteed to be a valid // pointer. V8_EXPORT_PRIVATE v8::VirtualAddressSpace* GetPlatformVirtualAddressSpace(); #ifdef V8_ENABLE_SANDBOX // Returns the page allocator instance for allocating pages inside the sandbox. // Guaranteed to be a valid pointer. V8_EXPORT_PRIVATE v8::PageAllocator* GetSandboxPageAllocator(); #endif // Returns the appropriate page allocator to use for ArrayBuffer backing // stores. If the sandbox is enabled, these must be allocated inside the // sandbox and so this will be the SandboxPageAllocator. Otherwise it will be // the PlatformPageAllocator. inline v8::PageAllocator* GetArrayBufferPageAllocator() { … } // Sets the given page allocator as the platform page allocator and returns // the current one. This function *must* be used only for testing purposes. // It is not thread-safe and the testing infrastructure should ensure that // the tests do not modify the value simultaneously. V8_EXPORT_PRIVATE v8::PageAllocator* SetPlatformPageAllocatorForTesting( v8::PageAllocator* page_allocator); // Gets the page granularity for AllocatePages and FreePages. Addresses returned // by AllocatePages are aligned to this size. V8_EXPORT_PRIVATE size_t AllocatePageSize(); // Gets the granularity at which the permissions and release calls can be made. V8_EXPORT_PRIVATE size_t CommitPageSize(); // Generate a random address to be used for hinting allocation calls. V8_EXPORT_PRIVATE void* GetRandomMmapAddr(); // Allocates memory. Permissions are set according to the access argument. // |address| is a hint. |size| and |alignment| must be multiples of // AllocatePageSize(). Returns the address of the allocated memory, with the // specified size and alignment, or nullptr on failure. V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT void* AllocatePages(v8::PageAllocator* page_allocator, void* address, size_t size, size_t alignment, PageAllocator::Permission access); // Frees memory allocated by a call to AllocatePages. |address| and |size| must // be multiples of AllocatePageSize(). V8_EXPORT_PRIVATE void FreePages(v8::PageAllocator* page_allocator, void* address, const size_t size); // Releases memory that is no longer needed. The range specified by |address| // and |size| must be an allocated memory region. |size| and |new_size| must be // multiples of CommitPageSize(). Memory from |new_size| to |size| is released. // Released memory is left in an undefined state, so it should not be accessed. V8_EXPORT_PRIVATE void ReleasePages(v8::PageAllocator* page_allocator, void* address, size_t size, size_t new_size); // Sets permissions according to |access|. |address| and |size| must be // multiples of CommitPageSize(). Setting permission to kNoAccess may // cause the memory contents to be lost. Returns true on success, otherwise // false. V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT bool SetPermissions(v8::PageAllocator* page_allocator, void* address, size_t size, PageAllocator::Permission access); inline bool SetPermissions(v8::PageAllocator* page_allocator, Address address, size_t size, PageAllocator::Permission access) { … } // Defines whether the address space reservation is going to be used for // allocating executable pages. enum class JitPermission { … }; // Represents and controls an area of reserved memory. class VirtualMemory final { … }; // Represents a VirtualMemory reservation along with a BoundedPageAllocator that // can be used to allocate within the reservation. // // Virtual memory cages are used for the pointer compression cage, the code // ranges (on platforms that require code ranges), and trusted ranges (when the // sandbox is enabled). They are configurable via ReservationParams. // // +-----------+------------ ~~~ --+- ~~~ -+ // | ... | ... | ... | // +-----------+------------ ~~~ --+- ~~~ -+ // ^ ^ // cage base allocatable base // // <-------------------> // allocatable size // <-------------------------------> // cage size // <---------------------------------------> // reservation size // // - The reservation is made using ReservationParams::page_allocator. // - cage base is the start of the virtual memory reservation and the base // address of the cage. // - allocatable base is the cage base rounded up to the nearest // ReservationParams::page_size, and is the start of the allocatable area for // the BoundedPageAllocator. // - cage size is the size of the area from cage base to the end of the // allocatable area. // // - The reservation size is configured by ReservationParams::reservation_size // but it might be actually bigger if we end up over-reserving the virtual // address space. // // Additionally, // - The alignment of the cage base is configured by // ReservationParams::base_alignment. // - The page size of the BoundedPageAllocator is configured by // ReservationParams::page_size. // - A hint for the value of start can be passed by // ReservationParams::requested_start_hint and it must be aligned to // ReservationParams::base_alignment. // // The configuration is subject to the following alignment requirements. // Below, AllocatePageSize is short for // ReservationParams::page_allocator->AllocatePageSize(). // // - The reservation size must be AllocatePageSize-aligned. // - If the base alignment is not kAnyBaseAlignment then the base alignment // must be AllocatePageSize-aligned. // - The base alignment may be kAnyBaseAlignment to denote any alignment is // acceptable. In this case the base bias size does not need to be aligned. class VirtualMemoryCage { … }; } // namespace internal } // namespace v8 #endif // V8_UTILS_ALLOCATION_H_