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 #include "src/base/virtual-address-space-page-allocator.h"
6
7 namespace v8 {
8 namespace base {
9
VirtualAddressSpacePageAllocator(v8::VirtualAddressSpace * vas)10 VirtualAddressSpacePageAllocator::VirtualAddressSpacePageAllocator(
11 v8::VirtualAddressSpace* vas)
12 : vas_(vas) {}
13
AllocatePages(void * hint,size_t size,size_t alignment,PageAllocator::Permission access)14 void* VirtualAddressSpacePageAllocator::AllocatePages(
15 void* hint, size_t size, size_t alignment,
16 PageAllocator::Permission access) {
17 return reinterpret_cast<void*>(
18 vas_->AllocatePages(reinterpret_cast<Address>(hint), size, alignment,
19 static_cast<PagePermissions>(access)));
20 }
21
FreePages(void * ptr,size_t size)22 bool VirtualAddressSpacePageAllocator::FreePages(void* ptr, size_t size) {
23 MutexGuard guard(&mutex_);
24 Address address = reinterpret_cast<Address>(ptr);
25 // Was this allocation resized previously? If so, use the original size.
26 auto result = resized_allocations_.find(address);
27 if (result != resized_allocations_.end()) {
28 size = result->second;
29 resized_allocations_.erase(result);
30 }
31 vas_->FreePages(address, size);
32 return true;
33 }
34
ReleasePages(void * ptr,size_t size,size_t new_size)35 bool VirtualAddressSpacePageAllocator::ReleasePages(void* ptr, size_t size,
36 size_t new_size) {
37 // The VirtualAddressSpace class doesn't support this method because it can't
38 // be properly implemented on top of Windows placeholder mappings (they cannot
39 // be partially freed or resized while being allocated). Instead, we emulate
40 // this behaviour by decommitting the released pages, which in effect achieves
41 // exactly what ReleasePages would normally do as well. However, we still need
42 // to pass the original size to FreePages eventually, so we'll need to keep
43 // track of that.
44 DCHECK_LE(new_size, size);
45
46 MutexGuard guard(&mutex_);
47 // Will fail if the allocation was resized previously, which is desired.
48 Address address = reinterpret_cast<Address>(ptr);
49 resized_allocations_.insert({address, size});
50 CHECK(vas_->DecommitPages(address + new_size, size - new_size));
51 return true;
52 }
53
SetPermissions(void * address,size_t size,PageAllocator::Permission access)54 bool VirtualAddressSpacePageAllocator::SetPermissions(
55 void* address, size_t size, PageAllocator::Permission access) {
56 return vas_->SetPagePermissions(reinterpret_cast<Address>(address), size,
57 static_cast<PagePermissions>(access));
58 }
59
DiscardSystemPages(void * address,size_t size)60 bool VirtualAddressSpacePageAllocator::DiscardSystemPages(void* address,
61 size_t size) {
62 return vas_->DiscardSystemPages(reinterpret_cast<Address>(address), size);
63 }
64
DecommitPages(void * address,size_t size)65 bool VirtualAddressSpacePageAllocator::DecommitPages(void* address,
66 size_t size) {
67 return vas_->DecommitPages(reinterpret_cast<Address>(address), size);
68 }
69
70 } // namespace base
71 } // namespace v8
72