| 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 |