Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: base/allocator/partition_allocator/page_allocator.cc

Issue 2614883006: Change PartitionAlloc to Chromium naming style. (Closed)
Patch Set: Rebase and fix some names. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/allocator/partition_allocator/page_allocator.h" 5 #include "base/allocator/partition_allocator/page_allocator.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 8
9 #include "base/allocator/partition_allocator/address_space_randomization.h" 9 #include "base/allocator/partition_allocator/address_space_randomization.h"
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
(...skipping 27 matching lines...) Expand all
38 static base::subtle::Atomic32 s_allocPageErrorCode = ERROR_SUCCESS; 38 static base::subtle::Atomic32 s_allocPageErrorCode = ERROR_SUCCESS;
39 39
40 #else 40 #else
41 #error Unknown OS 41 #error Unknown OS
42 #endif // defined(OS_POSIX) 42 #endif // defined(OS_POSIX)
43 43
44 namespace base { 44 namespace base {
45 45
46 // This internal function wraps the OS-specific page allocation call: 46 // This internal function wraps the OS-specific page allocation call:
47 // |VirtualAlloc| on Windows, and |mmap| on POSIX. 47 // |VirtualAlloc| on Windows, and |mmap| on POSIX.
48 static void* systemAllocPages( 48 static void* SystemAllocPages(
49 void* hint, 49 void* hint,
50 size_t len, 50 size_t length,
51 PageAccessibilityConfiguration pageAccessibility) { 51 PageAccessibilityConfiguration page_accessibility) {
52 DCHECK(!(len & kPageAllocationGranularityOffsetMask)); 52 DCHECK(!(length & kPageAllocationGranularityOffsetMask));
53 DCHECK(!(reinterpret_cast<uintptr_t>(hint) & 53 DCHECK(!(reinterpret_cast<uintptr_t>(hint) &
54 kPageAllocationGranularityOffsetMask)); 54 kPageAllocationGranularityOffsetMask));
55 void* ret; 55 void* ret;
56 #if defined(OS_WIN) 56 #if defined(OS_WIN)
57 DWORD accessFlag = 57 DWORD access_flag =
58 pageAccessibility == PageAccessible ? PAGE_READWRITE : PAGE_NOACCESS; 58 page_accessibility == PageAccessible ? PAGE_READWRITE : PAGE_NOACCESS;
59 ret = VirtualAlloc(hint, len, MEM_RESERVE | MEM_COMMIT, accessFlag); 59 ret = VirtualAlloc(hint, length, MEM_RESERVE | MEM_COMMIT, access_flag);
60 if (!ret) 60 if (!ret)
61 base::subtle::Release_Store(&s_allocPageErrorCode, GetLastError()); 61 base::subtle::Release_Store(&s_allocPageErrorCode, GetLastError());
62 #else 62 #else
63 int accessFlag = pageAccessibility == PageAccessible 63 int access_flag = page_accessibility == PageAccessible
64 ? (PROT_READ | PROT_WRITE) 64 ? (PROT_READ | PROT_WRITE)
65 : PROT_NONE; 65 : PROT_NONE;
66 ret = mmap(hint, len, accessFlag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 66 ret = mmap(hint, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
67 if (ret == MAP_FAILED) { 67 if (ret == MAP_FAILED) {
68 base::subtle::Release_Store(&s_allocPageErrorCode, errno); 68 base::subtle::Release_Store(&s_allocPageErrorCode, errno);
69 ret = 0; 69 ret = 0;
70 } 70 }
71 #endif 71 #endif
72 return ret; 72 return ret;
73 } 73 }
74 74
75 // Trims base to given length and alignment. Windows returns null on failure and 75 // Trims base to given length and alignment. Windows returns null on failure and
76 // frees base. 76 // frees base.
77 static void* trimMapping(void* base, 77 static void* TrimMapping(void* base,
78 size_t baseLen, 78 size_t base_length,
79 size_t trimLen, 79 size_t trim_length,
80 uintptr_t align, 80 uintptr_t align,
81 PageAccessibilityConfiguration pageAccessibility) { 81 PageAccessibilityConfiguration page_accessibility) {
82 size_t preSlack = reinterpret_cast<uintptr_t>(base) & (align - 1); 82 size_t pre_slack = reinterpret_cast<uintptr_t>(base) & (align - 1);
83 if (preSlack) 83 if (pre_slack)
84 preSlack = align - preSlack; 84 pre_slack = align - pre_slack;
85 size_t postSlack = baseLen - preSlack - trimLen; 85 size_t post_slack = base_length - pre_slack - trim_length;
86 DCHECK(baseLen >= trimLen || preSlack || postSlack); 86 DCHECK(base_length >= trim_length || pre_slack || post_slack);
87 DCHECK(preSlack < baseLen); 87 DCHECK(pre_slack < base_length);
88 DCHECK(postSlack < baseLen); 88 DCHECK(post_slack < base_length);
89 void* ret = base; 89 void* ret = base;
90 90
91 #if defined(OS_POSIX) // On POSIX we can resize the allocation run. 91 #if defined(OS_POSIX) // On POSIX we can resize the allocation run.
92 (void)pageAccessibility; 92 (void)page_accessibility;
93 if (preSlack) { 93 if (pre_slack) {
94 int res = munmap(base, preSlack); 94 int res = munmap(base, pre_slack);
95 CHECK(!res); 95 CHECK(!res);
96 ret = reinterpret_cast<char*>(base) + preSlack; 96 ret = reinterpret_cast<char*>(base) + pre_slack;
97 } 97 }
98 if (postSlack) { 98 if (post_slack) {
99 int res = munmap(reinterpret_cast<char*>(ret) + trimLen, postSlack); 99 int res = munmap(reinterpret_cast<char*>(ret) + trim_length, post_slack);
100 CHECK(!res); 100 CHECK(!res);
101 } 101 }
102 #else // On Windows we can't resize the allocation run. 102 #else // On Windows we can't resize the allocation run.
103 if (preSlack || postSlack) { 103 if (pre_slack || post_slack) {
104 ret = reinterpret_cast<char*>(base) + preSlack; 104 ret = reinterpret_cast<char*>(base) + pre_slack;
105 freePages(base, baseLen); 105 FreePages(base, base_length);
106 ret = systemAllocPages(ret, trimLen, pageAccessibility); 106 ret = SystemAllocPages(ret, trim_length, page_accessibility);
107 } 107 }
108 #endif 108 #endif
109 109
110 return ret; 110 return ret;
111 } 111 }
112 112
113 void* allocPages(void* addr, 113 void* AllocPages(void* address,
114 size_t len, 114 size_t length,
115 size_t align, 115 size_t align,
116 PageAccessibilityConfiguration pageAccessibility) { 116 PageAccessibilityConfiguration page_accessibility) {
117 DCHECK(len >= kPageAllocationGranularity); 117 DCHECK(length >= kPageAllocationGranularity);
118 DCHECK(!(len & kPageAllocationGranularityOffsetMask)); 118 DCHECK(!(length & kPageAllocationGranularityOffsetMask));
119 DCHECK(align >= kPageAllocationGranularity); 119 DCHECK(align >= kPageAllocationGranularity);
120 DCHECK(!(align & kPageAllocationGranularityOffsetMask)); 120 DCHECK(!(align & kPageAllocationGranularityOffsetMask));
121 DCHECK(!(reinterpret_cast<uintptr_t>(addr) & 121 DCHECK(!(reinterpret_cast<uintptr_t>(address) &
122 kPageAllocationGranularityOffsetMask)); 122 kPageAllocationGranularityOffsetMask));
123 uintptr_t alignOffsetMask = align - 1; 123 uintptr_t align_offset_mask = align - 1;
124 uintptr_t alignBaseMask = ~alignOffsetMask; 124 uintptr_t align_base_mask = ~align_offset_mask;
125 DCHECK(!(reinterpret_cast<uintptr_t>(addr) & alignOffsetMask)); 125 DCHECK(!(reinterpret_cast<uintptr_t>(address) & align_offset_mask));
126 126
127 // If the client passed null as the address, choose a good one. 127 // If the client passed null as the address, choose a good one.
128 if (!addr) { 128 if (!address) {
129 addr = getRandomPageBase(); 129 address = GetRandomPageBase();
130 addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & 130 address = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) &
131 alignBaseMask); 131 align_base_mask);
132 } 132 }
133 133
134 // First try to force an exact-size, aligned allocation from our random base. 134 // First try to force an exact-size, aligned allocation from our random base.
135 for (int count = 0; count < 3; ++count) { 135 for (int count = 0; count < 3; ++count) {
136 void* ret = systemAllocPages(addr, len, pageAccessibility); 136 void* ret = SystemAllocPages(address, length, page_accessibility);
137 if (kHintIsAdvisory || ret) { 137 if (kHintIsAdvisory || ret) {
138 // If the alignment is to our liking, we're done. 138 // If the alignment is to our liking, we're done.
139 if (!(reinterpret_cast<uintptr_t>(ret) & alignOffsetMask)) 139 if (!(reinterpret_cast<uintptr_t>(ret) & align_offset_mask))
140 return ret; 140 return ret;
141 freePages(ret, len); 141 FreePages(ret, length);
142 #if defined(ARCH_CPU_32_BITS) 142 #if defined(ARCH_CPU_32_BITS)
143 addr = reinterpret_cast<void*>( 143 address = reinterpret_cast<void*>(
144 (reinterpret_cast<uintptr_t>(ret) + align) & alignBaseMask); 144 (reinterpret_cast<uintptr_t>(ret) + align) & align_base_mask);
145 #endif 145 #endif
146 } else if (!addr) { // We know we're OOM when an unhinted allocation fails. 146 } else if (!address) { // We know we're OOM when an unhinted allocation
147 // fails.
147 return nullptr; 148 return nullptr;
148
149 } else { 149 } else {
150 #if defined(ARCH_CPU_32_BITS) 150 #if defined(ARCH_CPU_32_BITS)
151 addr = reinterpret_cast<char*>(addr) + align; 151 address = reinterpret_cast<char*>(address) + align;
152 #endif 152 #endif
153 } 153 }
154 154
155 #if !defined(ARCH_CPU_32_BITS) 155 #if !defined(ARCH_CPU_32_BITS)
156 // Keep trying random addresses on systems that have a large address space. 156 // Keep trying random addresses on systems that have a large address space.
157 addr = getRandomPageBase(); 157 address = GetRandomPageBase();
158 addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & 158 address = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) &
159 alignBaseMask); 159 align_base_mask);
160 #endif 160 #endif
161 } 161 }
162 162
163 // Map a larger allocation so we can force alignment, but continue randomizing 163 // Map a larger allocation so we can force alignment, but continue randomizing
164 // only on 64-bit POSIX. 164 // only on 64-bit POSIX.
165 size_t tryLen = len + (align - kPageAllocationGranularity); 165 size_t try_length = length + (align - kPageAllocationGranularity);
166 CHECK(tryLen >= len); 166 CHECK(try_length >= length);
167 void* ret; 167 void* ret;
168 168
169 do { 169 do {
170 // Don't continue to burn cycles on mandatory hints (Windows). 170 // Don't continue to burn cycles on mandatory hints (Windows).
171 addr = kHintIsAdvisory ? getRandomPageBase() : nullptr; 171 address = kHintIsAdvisory ? GetRandomPageBase() : nullptr;
172 ret = systemAllocPages(addr, tryLen, pageAccessibility); 172 ret = SystemAllocPages(address, try_length, page_accessibility);
173 // The retries are for Windows, where a race can steal our mapping on 173 // The retries are for Windows, where a race can steal our mapping on
174 // resize. 174 // resize.
175 } while (ret && 175 } while (ret &&
176 (ret = trimMapping(ret, tryLen, len, align, pageAccessibility)) == 176 (ret = TrimMapping(ret, try_length, length, align,
177 nullptr); 177 page_accessibility)) == nullptr);
178 178
179 return ret; 179 return ret;
180 } 180 }
181 181
182 void freePages(void* addr, size_t len) { 182 void FreePages(void* address, size_t length) {
183 DCHECK(!(reinterpret_cast<uintptr_t>(addr) & 183 DCHECK(!(reinterpret_cast<uintptr_t>(address) &
184 kPageAllocationGranularityOffsetMask)); 184 kPageAllocationGranularityOffsetMask));
185 DCHECK(!(len & kPageAllocationGranularityOffsetMask)); 185 DCHECK(!(length & kPageAllocationGranularityOffsetMask));
186 #if defined(OS_POSIX) 186 #if defined(OS_POSIX)
187 int ret = munmap(addr, len); 187 int ret = munmap(address, length);
188 CHECK(!ret); 188 CHECK(!ret);
189 #else 189 #else
190 BOOL ret = VirtualFree(addr, 0, MEM_RELEASE); 190 BOOL ret = VirtualFree(address, 0, MEM_RELEASE);
191 CHECK(ret); 191 CHECK(ret);
192 #endif 192 #endif
193 } 193 }
194 194
195 void setSystemPagesInaccessible(void* addr, size_t len) { 195 void SetSystemPagesInaccessible(void* address, size_t length) {
196 DCHECK(!(len & kSystemPageOffsetMask)); 196 DCHECK(!(length & kSystemPageOffsetMask));
197 #if defined(OS_POSIX) 197 #if defined(OS_POSIX)
198 int ret = mprotect(addr, len, PROT_NONE); 198 int ret = mprotect(address, length, PROT_NONE);
199 CHECK(!ret); 199 CHECK(!ret);
200 #else 200 #else
201 BOOL ret = VirtualFree(addr, len, MEM_DECOMMIT); 201 BOOL ret = VirtualFree(address, length, MEM_DECOMMIT);
202 CHECK(ret); 202 CHECK(ret);
203 #endif 203 #endif
204 } 204 }
205 205
206 bool setSystemPagesAccessible(void* addr, size_t len) { 206 bool SetSystemPagesAccessible(void* address, size_t length) {
207 DCHECK(!(len & kSystemPageOffsetMask)); 207 DCHECK(!(length & kSystemPageOffsetMask));
208 #if defined(OS_POSIX) 208 #if defined(OS_POSIX)
209 return !mprotect(addr, len, PROT_READ | PROT_WRITE); 209 return !mprotect(address, length, PROT_READ | PROT_WRITE);
210 #else 210 #else
211 return !!VirtualAlloc(addr, len, MEM_COMMIT, PAGE_READWRITE); 211 return !!VirtualAlloc(address, length, MEM_COMMIT, PAGE_READWRITE);
212 #endif 212 #endif
213 } 213 }
214 214
215 void decommitSystemPages(void* addr, size_t len) { 215 void DecommitSystemPages(void* address, size_t length) {
216 DCHECK(!(len & kSystemPageOffsetMask)); 216 DCHECK(!(length & kSystemPageOffsetMask));
217 #if defined(OS_POSIX) 217 #if defined(OS_POSIX)
218 int ret = madvise(addr, len, MADV_FREE); 218 int ret = madvise(address, length, MADV_FREE);
219 if (ret != 0 && errno == EINVAL) { 219 if (ret != 0 && errno == EINVAL) {
220 // MADV_FREE only works on Linux 4.5+ . If request failed, 220 // MADV_FREE only works on Linux 4.5+ . If request failed,
221 // retry with older MADV_DONTNEED . Note that MADV_FREE 221 // retry with older MADV_DONTNEED . Note that MADV_FREE
222 // being defined at compile time doesn't imply runtime support. 222 // being defined at compile time doesn't imply runtime support.
223 ret = madvise(addr, len, MADV_DONTNEED); 223 ret = madvise(address, length, MADV_DONTNEED);
224 } 224 }
225 CHECK(!ret); 225 CHECK(!ret);
226 #else 226 #else
227 setSystemPagesInaccessible(addr, len); 227 SetSystemPagesInaccessible(address, length);
228 #endif 228 #endif
229 } 229 }
230 230
231 void recommitSystemPages(void* addr, size_t len) { 231 void RecommitSystemPages(void* address, size_t length) {
232 DCHECK(!(len & kSystemPageOffsetMask)); 232 DCHECK(!(length & kSystemPageOffsetMask));
233 #if defined(OS_POSIX) 233 #if defined(OS_POSIX)
234 (void)addr; 234 (void)address;
235 #else 235 #else
236 CHECK(setSystemPagesAccessible(addr, len)); 236 CHECK(SetSystemPagesAccessible(address, length));
237 #endif 237 #endif
238 } 238 }
239 239
240 void discardSystemPages(void* addr, size_t len) { 240 void DiscardSystemPages(void* address, size_t length) {
241 DCHECK(!(len & kSystemPageOffsetMask)); 241 DCHECK(!(length & kSystemPageOffsetMask));
242 #if defined(OS_POSIX) 242 #if defined(OS_POSIX)
243 // On POSIX, the implementation detail is that discard and decommit are the 243 // On POSIX, the implementation detail is that discard and decommit are the
244 // same, and lead to pages that are returned to the system immediately and 244 // same, and lead to pages that are returned to the system immediately and
245 // get replaced with zeroed pages when touched. So we just call 245 // get replaced with zeroed pages when touched. So we just call
246 // decommitSystemPages() here to avoid code duplication. 246 // DecommitSystemPages() here to avoid code duplication.
247 decommitSystemPages(addr, len); 247 DecommitSystemPages(address, length);
248 #else 248 #else
249 // On Windows discarded pages are not returned to the system immediately and 249 // On Windows discarded pages are not returned to the system immediately and
250 // not guaranteed to be zeroed when returned to the application. 250 // not guaranteed to be zeroed when returned to the application.
251 using DiscardVirtualMemoryFunction = 251 using DiscardVirtualMemoryFunction =
252 DWORD(WINAPI*)(PVOID virtualAddress, SIZE_T size); 252 DWORD(WINAPI*)(PVOID virtualAddress, SIZE_T size);
253 static DiscardVirtualMemoryFunction discardVirtualMemory = 253 static DiscardVirtualMemoryFunction discard_virtual_memory =
254 reinterpret_cast<DiscardVirtualMemoryFunction>(-1); 254 reinterpret_cast<DiscardVirtualMemoryFunction>(-1);
255 if (discardVirtualMemory == 255 if (discard_virtual_memory ==
256 reinterpret_cast<DiscardVirtualMemoryFunction>(-1)) 256 reinterpret_cast<DiscardVirtualMemoryFunction>(-1))
257 discardVirtualMemory = 257 discard_virtual_memory =
258 reinterpret_cast<DiscardVirtualMemoryFunction>(GetProcAddress( 258 reinterpret_cast<DiscardVirtualMemoryFunction>(GetProcAddress(
259 GetModuleHandle(L"Kernel32.dll"), "DiscardVirtualMemory")); 259 GetModuleHandle(L"Kernel32.dll"), "DiscardVirtualMemory"));
260 // Use DiscardVirtualMemory when available because it releases faster than 260 // Use DiscardVirtualMemory when available because it releases faster than
261 // MEM_RESET. 261 // MEM_RESET.
262 DWORD ret = 1; 262 DWORD ret = 1;
263 if (discardVirtualMemory) 263 if (discard_virtual_memory)
264 ret = discardVirtualMemory(addr, len); 264 ret = discard_virtual_memory(address, length);
265 // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on 265 // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on
266 // failure. 266 // failure.
267 if (ret) { 267 if (ret) {
268 void* ret = VirtualAlloc(addr, len, MEM_RESET, PAGE_READWRITE); 268 void* ret = VirtualAlloc(address, length, MEM_RESET, PAGE_READWRITE);
269 CHECK(ret); 269 CHECK(ret);
270 } 270 }
271 #endif 271 #endif
272 } 272 }
273 273
274 uint32_t getAllocPageErrorCode() { 274 uint32_t GetAllocPageErrorCode() {
275 return base::subtle::Acquire_Load(&s_allocPageErrorCode); 275 return base::subtle::Acquire_Load(&s_allocPageErrorCode);
276 } 276 }
277 277
278 } // namespace base 278 } // namespace base
OLDNEW
« no previous file with comments | « base/allocator/partition_allocator/page_allocator.h ('k') | base/allocator/partition_allocator/partition_alloc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698