OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 : PROT_NONE; | 92 : PROT_NONE; |
93 ret = mmap(hint, len, accessFlag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | 93 ret = mmap(hint, len, accessFlag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
94 if (ret == MAP_FAILED) { | 94 if (ret == MAP_FAILED) { |
95 releaseStore(&s_allocPageErrorCode, errno); | 95 releaseStore(&s_allocPageErrorCode, errno); |
96 ret = 0; | 96 ret = 0; |
97 } | 97 } |
98 #endif | 98 #endif |
99 return ret; | 99 return ret; |
100 } | 100 } |
101 | 101 |
102 // Trims base to given length and alignment. Windows returns null on failure and
frees base. | 102 // Trims base to given length and alignment. Windows returns null on failure and |
| 103 // frees base. |
103 static void* trimMapping(void* base, | 104 static void* trimMapping(void* base, |
104 size_t baseLen, | 105 size_t baseLen, |
105 size_t trimLen, | 106 size_t trimLen, |
106 uintptr_t align, | 107 uintptr_t align, |
107 PageAccessibilityConfiguration pageAccessibility) { | 108 PageAccessibilityConfiguration pageAccessibility) { |
108 size_t preSlack = reinterpret_cast<uintptr_t>(base) & (align - 1); | 109 size_t preSlack = reinterpret_cast<uintptr_t>(base) & (align - 1); |
109 if (preSlack) | 110 if (preSlack) |
110 preSlack = align - preSlack; | 111 preSlack = align - preSlack; |
111 size_t postSlack = baseLen - preSlack - trimLen; | 112 size_t postSlack = baseLen - preSlack - trimLen; |
112 ASSERT(baseLen >= trimLen || preSlack || postSlack); | 113 ASSERT(baseLen >= trimLen || preSlack || postSlack); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 #endif | 172 #endif |
172 } else if (!addr) { // We know we're OOM when an unhinted allocation fails. | 173 } else if (!addr) { // We know we're OOM when an unhinted allocation fails. |
173 return nullptr; | 174 return nullptr; |
174 | 175 |
175 } else { | 176 } else { |
176 #if CPU(32BIT) | 177 #if CPU(32BIT) |
177 addr = reinterpret_cast<char*>(addr) + align; | 178 addr = reinterpret_cast<char*>(addr) + align; |
178 #endif | 179 #endif |
179 } | 180 } |
180 | 181 |
181 #if !CPU( \ | 182 #if !CPU(32BIT) |
182 32BIT) // Keep trying random addresses on systems that have a large address
space. | 183 // Keep trying random addresses on systems that have a large address space. |
183 addr = getRandomPageBase(); | 184 addr = getRandomPageBase(); |
184 addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & | 185 addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & |
185 alignBaseMask); | 186 alignBaseMask); |
186 #endif | 187 #endif |
187 } | 188 } |
188 | 189 |
189 // Map a larger allocation so we can force alignment, but continue randomizing
only on 64-bit POSIX. | 190 // Map a larger allocation so we can force alignment, but continue randomizing |
| 191 // only on 64-bit POSIX. |
190 size_t tryLen = len + (align - kPageAllocationGranularity); | 192 size_t tryLen = len + (align - kPageAllocationGranularity); |
191 RELEASE_ASSERT(tryLen >= len); | 193 RELEASE_ASSERT(tryLen >= len); |
192 void* ret; | 194 void* ret; |
193 | 195 |
194 do { | 196 do { |
195 // Don't continue to burn cycles on mandatory hints (Windows). | 197 // Don't continue to burn cycles on mandatory hints (Windows). |
196 addr = kHintIsAdvisory ? getRandomPageBase() : nullptr; | 198 addr = kHintIsAdvisory ? getRandomPageBase() : nullptr; |
197 ret = systemAllocPages(addr, tryLen, pageAccessibility); | 199 ret = systemAllocPages(addr, tryLen, pageAccessibility); |
198 // The retries are for Windows, where a race can steal our mapping on resize
. | 200 // The retries are for Windows, where a race can steal our mapping on |
| 201 // resize. |
199 } while (ret && | 202 } while (ret && |
200 !(ret = trimMapping(ret, tryLen, len, align, pageAccessibility))); | 203 !(ret = trimMapping(ret, tryLen, len, align, pageAccessibility))); |
201 | 204 |
202 return ret; | 205 return ret; |
203 } | 206 } |
204 | 207 |
205 void freePages(void* addr, size_t len) { | 208 void freePages(void* addr, size_t len) { |
206 ASSERT(!(reinterpret_cast<uintptr_t>(addr) & | 209 ASSERT(!(reinterpret_cast<uintptr_t>(addr) & |
207 kPageAllocationGranularityOffsetMask)); | 210 kPageAllocationGranularityOffsetMask)); |
208 ASSERT(!(len & kPageAllocationGranularityOffsetMask)); | 211 ASSERT(!(len & kPageAllocationGranularityOffsetMask)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 // not guaranteed to be zeroed when returned to the application. | 270 // not guaranteed to be zeroed when returned to the application. |
268 using DiscardVirtualMemoryFunction = | 271 using DiscardVirtualMemoryFunction = |
269 DWORD(WINAPI*)(PVOID virtualAddress, SIZE_T size); | 272 DWORD(WINAPI*)(PVOID virtualAddress, SIZE_T size); |
270 static DiscardVirtualMemoryFunction discardVirtualMemory = | 273 static DiscardVirtualMemoryFunction discardVirtualMemory = |
271 reinterpret_cast<DiscardVirtualMemoryFunction>(-1); | 274 reinterpret_cast<DiscardVirtualMemoryFunction>(-1); |
272 if (discardVirtualMemory == | 275 if (discardVirtualMemory == |
273 reinterpret_cast<DiscardVirtualMemoryFunction>(-1)) | 276 reinterpret_cast<DiscardVirtualMemoryFunction>(-1)) |
274 discardVirtualMemory = | 277 discardVirtualMemory = |
275 reinterpret_cast<DiscardVirtualMemoryFunction>(GetProcAddress( | 278 reinterpret_cast<DiscardVirtualMemoryFunction>(GetProcAddress( |
276 GetModuleHandle(L"Kernel32.dll"), "DiscardVirtualMemory")); | 279 GetModuleHandle(L"Kernel32.dll"), "DiscardVirtualMemory")); |
277 // Use DiscardVirtualMemory when available because it releases faster than MEM
_RESET. | 280 // Use DiscardVirtualMemory when available because it releases faster than |
| 281 // MEM_RESET. |
278 DWORD ret = 1; | 282 DWORD ret = 1; |
279 if (discardVirtualMemory) | 283 if (discardVirtualMemory) |
280 ret = discardVirtualMemory(addr, len); | 284 ret = discardVirtualMemory(addr, len); |
281 // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on fa
ilure. | 285 // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on |
| 286 // failure. |
282 if (ret) { | 287 if (ret) { |
283 void* ret = VirtualAlloc(addr, len, MEM_RESET, PAGE_READWRITE); | 288 void* ret = VirtualAlloc(addr, len, MEM_RESET, PAGE_READWRITE); |
284 RELEASE_ASSERT(ret); | 289 RELEASE_ASSERT(ret); |
285 } | 290 } |
286 #endif | 291 #endif |
287 } | 292 } |
288 | 293 |
289 uint32_t getAllocPageErrorCode() { | 294 uint32_t getAllocPageErrorCode() { |
290 return acquireLoad(&s_allocPageErrorCode); | 295 return acquireLoad(&s_allocPageErrorCode); |
291 } | 296 } |
292 | 297 |
293 } // namespace WTF | 298 } // namespace WTF |
OLD | NEW |