• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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