blob: 5e0b5beb149d988c312babeed87f9d90d4851460 [file] [log] [blame]
// 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::RecommitPages(
void* address, size_t size, PageAllocator::Permission access) {
return vas_->RecommitPages(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