| OLD | NEW |
| 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 <atomic> |
| 10 |
| 9 #include "base/allocator/partition_allocator/address_space_randomization.h" | 11 #include "base/allocator/partition_allocator/address_space_randomization.h" |
| 10 #include "base/atomicops.h" | |
| 11 #include "base/base_export.h" | 12 #include "base/base_export.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 14 | 15 |
| 15 #if defined(OS_POSIX) | 16 #if defined(OS_POSIX) |
| 16 | 17 |
| 17 #include <errno.h> | 18 #include <errno.h> |
| 18 #include <sys/mman.h> | 19 #include <sys/mman.h> |
| 19 | 20 |
| 20 #ifndef MADV_FREE | 21 #ifndef MADV_FREE |
| 21 #define MADV_FREE MADV_DONTNEED | 22 #define MADV_FREE MADV_DONTNEED |
| 22 #endif | 23 #endif |
| 23 | 24 |
| 24 #ifndef MAP_ANONYMOUS | 25 #ifndef MAP_ANONYMOUS |
| 25 #define MAP_ANONYMOUS MAP_ANON | 26 #define MAP_ANONYMOUS MAP_ANON |
| 26 #endif | 27 #endif |
| 27 | 28 |
| 28 // On POSIX |mmap| uses a nearby address if the hint address is blocked. | 29 // On POSIX |mmap| uses a nearby address if the hint address is blocked. |
| 29 static const bool kHintIsAdvisory = true; | 30 static const bool kHintIsAdvisory = true; |
| 30 static volatile base::subtle::Atomic32 s_allocPageErrorCode = 0; | 31 static std::atomic<int32_t> s_allocPageErrorCode{0}; |
| 31 | 32 |
| 32 #elif defined(OS_WIN) | 33 #elif defined(OS_WIN) |
| 33 | 34 |
| 34 #include <windows.h> | 35 #include <windows.h> |
| 35 | 36 |
| 36 // |VirtualAlloc| will fail if allocation at the hint address is blocked. | 37 // |VirtualAlloc| will fail if allocation at the hint address is blocked. |
| 37 static const bool kHintIsAdvisory = false; | 38 static const bool kHintIsAdvisory = false; |
| 38 static base::subtle::Atomic32 s_allocPageErrorCode = ERROR_SUCCESS; | 39 static std::atomic<int32_t> s_allocPageErrorCode{ERROR_SUCCESS}; |
| 39 | 40 |
| 40 #else | 41 #else |
| 41 #error Unknown OS | 42 #error Unknown OS |
| 42 #endif // defined(OS_POSIX) | 43 #endif // defined(OS_POSIX) |
| 43 | 44 |
| 44 namespace base { | 45 namespace base { |
| 45 | 46 |
| 46 // This internal function wraps the OS-specific page allocation call: | 47 // This internal function wraps the OS-specific page allocation call: |
| 47 // |VirtualAlloc| on Windows, and |mmap| on POSIX. | 48 // |VirtualAlloc| on Windows, and |mmap| on POSIX. |
| 48 static void* SystemAllocPages( | 49 static void* SystemAllocPages( |
| 49 void* hint, | 50 void* hint, |
| 50 size_t length, | 51 size_t length, |
| 51 PageAccessibilityConfiguration page_accessibility) { | 52 PageAccessibilityConfiguration page_accessibility) { |
| 52 DCHECK(!(length & kPageAllocationGranularityOffsetMask)); | 53 DCHECK(!(length & kPageAllocationGranularityOffsetMask)); |
| 53 DCHECK(!(reinterpret_cast<uintptr_t>(hint) & | 54 DCHECK(!(reinterpret_cast<uintptr_t>(hint) & |
| 54 kPageAllocationGranularityOffsetMask)); | 55 kPageAllocationGranularityOffsetMask)); |
| 55 void* ret; | 56 void* ret; |
| 56 #if defined(OS_WIN) | 57 #if defined(OS_WIN) |
| 57 DWORD access_flag = | 58 DWORD access_flag = |
| 58 page_accessibility == PageAccessible ? PAGE_READWRITE : PAGE_NOACCESS; | 59 page_accessibility == PageAccessible ? PAGE_READWRITE : PAGE_NOACCESS; |
| 59 ret = VirtualAlloc(hint, length, MEM_RESERVE | MEM_COMMIT, access_flag); | 60 ret = VirtualAlloc(hint, length, MEM_RESERVE | MEM_COMMIT, access_flag); |
| 60 if (!ret) | 61 if (!ret) |
| 61 base::subtle::Release_Store(&s_allocPageErrorCode, GetLastError()); | 62 s_allocPageErrorCode = GetLastError(); |
| 62 #else | 63 #else |
| 63 int access_flag = page_accessibility == PageAccessible | 64 int access_flag = page_accessibility == PageAccessible |
| 64 ? (PROT_READ | PROT_WRITE) | 65 ? (PROT_READ | PROT_WRITE) |
| 65 : PROT_NONE; | 66 : PROT_NONE; |
| 66 ret = mmap(hint, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | 67 ret = mmap(hint, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
| 67 if (ret == MAP_FAILED) { | 68 if (ret == MAP_FAILED) { |
| 68 base::subtle::Release_Store(&s_allocPageErrorCode, errno); | 69 s_allocPageErrorCode = errno; |
| 69 ret = 0; | 70 ret = 0; |
| 70 } | 71 } |
| 71 #endif | 72 #endif |
| 72 return ret; | 73 return ret; |
| 73 } | 74 } |
| 74 | 75 |
| 75 // Trims base to given length and alignment. Windows returns null on failure and | 76 // Trims base to given length and alignment. Windows returns null on failure and |
| 76 // frees base. | 77 // frees base. |
| 77 static void* TrimMapping(void* base, | 78 static void* TrimMapping(void* base, |
| 78 size_t base_length, | 79 size_t base_length, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on | 266 // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on |
| 266 // failure. | 267 // failure. |
| 267 if (ret) { | 268 if (ret) { |
| 268 void* ret = VirtualAlloc(address, length, MEM_RESET, PAGE_READWRITE); | 269 void* ret = VirtualAlloc(address, length, MEM_RESET, PAGE_READWRITE); |
| 269 CHECK(ret); | 270 CHECK(ret); |
| 270 } | 271 } |
| 271 #endif | 272 #endif |
| 272 } | 273 } |
| 273 | 274 |
| 274 uint32_t GetAllocPageErrorCode() { | 275 uint32_t GetAllocPageErrorCode() { |
| 275 return base::subtle::Acquire_Load(&s_allocPageErrorCode); | 276 return s_allocPageErrorCode; |
| 276 } | 277 } |
| 277 | 278 |
| 278 } // namespace base | 279 } // namespace base |
| OLD | NEW |