// Copyright 2018 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. #include "src/base/virtual-address-space-page-allocator.h" namespace v8 { namespace base { VirtualAddressSpacePageAllocator::VirtualAddressSpacePageAllocator( v8::VirtualAddressSpace* vas) : vas_(vas) {} void* VirtualAddressSpacePageAllocator::AllocatePages( void* hint, size_t size, size_t alignment, PageAllocator::Permission access) { return reinterpret_cast<void*>( vas_->AllocatePages(reinterpret_cast<Address>(hint), size, alignment, static_cast<PagePermissions>(access))); } bool VirtualAddressSpacePageAllocator::FreePages(void* ptr, size_t size) { MutexGuard guard(&mutex_); Address address = reinterpret_cast<Address>(ptr); // Was this allocation resized previously? If so, use the original size. auto result = resized_allocations_.find(address); if (result != resized_allocations_.end()) { size = result->second; resized_allocations_.erase(result); } vas_->FreePages(address, size); return true; } bool VirtualAddressSpacePageAllocator::ReleasePages(void* ptr, size_t size, size_t new_size) { // The VirtualAddressSpace class doesn't support this method because it can't // be properly implemented on top of Windows placeholder mappings (they cannot // be partially freed or resized while being allocated). Instead, we emulate // this behaviour by decommitting the released pages, which in effect achieves // exactly what ReleasePages would normally do as well. However, we still need // to pass the original size to FreePages eventually, so we'll need to keep // track of that. DCHECK_LE(new_size, size); MutexGuard guard(&mutex_); // Will fail if the allocation was resized previously, which is desired. Address address = reinterpret_cast<Address>(ptr); resized_allocations_.insert({address, size}); CHECK(vas_->DecommitPages(address + new_size, size - new_size)); return true; } bool VirtualAddressSpacePageAllocator::SetPermissions( void* address, size_t size, PageAllocator::Permission access) { return vas_->SetPagePermissions(reinterpret_cast<Address>(address), size, static_cast<PagePermissions>(access)); } bool VirtualAddressSpacePageAllocator::DiscardSystemPages(void* address, size_t size) { return vas_->DiscardSystemPages(reinterpret_cast<Address>(address), size); } bool VirtualAddressSpacePageAllocator::DecommitPages(void* address, size_t size) { return vas_->DecommitPages(reinterpret_cast<Address>(address), size); } } // namespace base } // namespace v8