• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium 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 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H
6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H
7 
8 #include <stdint.h>
9 
10 #include <cstddef>
11 
12 #include "third_party/base/base_export.h"
13 #include "third_party/base/compiler_specific.h"
14 #include "third_party/build/build_config.h"
15 
16 namespace pdfium {
17 namespace base {
18 
19 #if defined(OS_WIN)
20 static const size_t kPageAllocationGranularityShift = 16;  // 64KB
21 #elif defined(_MIPS_ARCH_LOONGSON)
22 static const size_t kPageAllocationGranularityShift = 14;  // 16KB
23 #else
24 static const size_t kPageAllocationGranularityShift = 12;  // 4KB
25 #endif
26 static const size_t kPageAllocationGranularity =
27     1 << kPageAllocationGranularityShift;
28 static const size_t kPageAllocationGranularityOffsetMask =
29     kPageAllocationGranularity - 1;
30 static const size_t kPageAllocationGranularityBaseMask =
31     ~kPageAllocationGranularityOffsetMask;
32 
33 // All Blink-supported systems have 4096 sized system pages and can handle
34 // permissions and commit / decommit at this granularity.
35 // Loongson have 16384 sized system pages.
36 #if defined(_MIPS_ARCH_LOONGSON)
37 static const size_t kSystemPageSize = 16384;
38 #else
39 static const size_t kSystemPageSize = 4096;
40 #endif
41 static const size_t kSystemPageOffsetMask = kSystemPageSize - 1;
42 static const size_t kSystemPageBaseMask = ~kSystemPageOffsetMask;
43 
44 enum PageAccessibilityConfiguration {
45   PageAccessible,
46   PageInaccessible,
47 };
48 
49 // Allocate one or more pages.
50 // The requested address is just a hint; the actual address returned may
51 // differ. The returned address will be aligned at least to align bytes.
52 // len is in bytes, and must be a multiple of kPageAllocationGranularity.
53 // align is in bytes, and must be a power-of-two multiple of
54 // kPageAllocationGranularity.
55 // If addr is null, then a suitable and randomized address will be chosen
56 // automatically.
57 // PageAccessibilityConfiguration controls the permission of the
58 // allocated pages.
59 // This call will return null if the allocation cannot be satisfied.
60 BASE_EXPORT void* AllocPages(void* address,
61                              size_t len,
62                              size_t align,
63                              PageAccessibilityConfiguration);
64 
65 // Free one or more pages.
66 // addr and len must match a previous call to allocPages().
67 BASE_EXPORT void FreePages(void* address, size_t length);
68 
69 // Mark one or more system pages as being inaccessible.
70 // Subsequently accessing any address in the range will fault, and the
71 // addresses will not be re-used by future allocations.
72 // len must be a multiple of kSystemPageSize bytes.
73 BASE_EXPORT void SetSystemPagesInaccessible(void* address, size_t length);
74 
75 // Mark one or more system pages as being accessible.
76 // The pages will be readable and writeable.
77 // len must be a multiple of kSystemPageSize bytes.
78 // The result bool value indicates whether the permission
79 // change succeeded or not. You must check the result
80 // (in most cases you need to CHECK that it is true).
81 BASE_EXPORT WARN_UNUSED_RESULT bool SetSystemPagesAccessible(void* address,
82                                                              size_t length);
83 
84 // Decommit one or more system pages. Decommitted means that the physical memory
85 // is released to the system, but the virtual address space remains reserved.
86 // System pages are re-committed by calling recommitSystemPages(). Touching
87 // a decommitted page _may_ fault.
88 // Clients should not make any assumptions about the contents of decommitted
89 // system pages, before or after they write to the page. The only guarantee
90 // provided is that the contents of the system page will be deterministic again
91 // after recommitting and writing to it. In particlar note that system pages are
92 // not guaranteed to be zero-filled upon re-commit. len must be a multiple of
93 // kSystemPageSize bytes.
94 BASE_EXPORT void DecommitSystemPages(void* address, size_t length);
95 
96 // Recommit one or more system pages. Decommitted system pages must be
97 // recommitted before they are read are written again.
98 // Note that this operation may be a no-op on some platforms.
99 // len must be a multiple of kSystemPageSize bytes.
100 BASE_EXPORT void RecommitSystemPages(void* address, size_t length);
101 
102 // Discard one or more system pages. Discarding is a hint to the system that
103 // the page is no longer required. The hint may:
104 // - Do nothing.
105 // - Discard the page immediately, freeing up physical pages.
106 // - Discard the page at some time in the future in response to memory pressure.
107 // Only committed pages should be discarded. Discarding a page does not
108 // decommit it, and it is valid to discard an already-discarded page.
109 // A read or write to a discarded page will not fault.
110 // Reading from a discarded page may return the original page content, or a
111 // page full of zeroes.
112 // Writing to a discarded page is the only guaranteed way to tell the system
113 // that the page is required again. Once written to, the content of the page is
114 // guaranteed stable once more. After being written to, the page content may be
115 // based on the original page content, or a page of zeroes.
116 // len must be a multiple of kSystemPageSize bytes.
117 BASE_EXPORT void DiscardSystemPages(void* address, size_t length);
118 
RoundUpToSystemPage(uintptr_t address)119 ALWAYS_INLINE uintptr_t RoundUpToSystemPage(uintptr_t address) {
120   return (address + kSystemPageOffsetMask) & kSystemPageBaseMask;
121 }
122 
RoundDownToSystemPage(uintptr_t address)123 ALWAYS_INLINE uintptr_t RoundDownToSystemPage(uintptr_t address) {
124   return address & kSystemPageBaseMask;
125 }
126 
127 // Returns errno (or GetLastError code) when mmap (or VirtualAlloc) fails.
128 BASE_EXPORT uint32_t GetAllocPageErrorCode();
129 
130 }  // namespace base
131 }  // namespace pdfium
132 
133 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_H
134