summaryrefslogtreecommitdiff
path: root/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/base/allocator/partition_allocator/page_allocator_internals_win.h')
-rw-r--r--third_party/base/allocator/partition_allocator/page_allocator_internals_win.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h b/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h
new file mode 100644
index 0000000000..57a11c521b
--- /dev/null
+++ b/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_INTERNALS_WIN_H_
+#define THIRD_PARTY_BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_INTERNALS_WIN_H_
+
+#include "third_party/base/allocator/partition_allocator/page_allocator_internal.h"
+
+namespace pdfium {
+namespace base {
+
+// |VirtualAlloc| will fail if allocation at the hint address is blocked.
+constexpr bool kHintIsAdvisory = false;
+std::atomic<int32_t> s_allocPageErrorCode{ERROR_SUCCESS};
+
+int GetAccessFlags(PageAccessibilityConfiguration accessibility) {
+ switch (accessibility) {
+ case PageRead:
+ return PAGE_READONLY;
+ case PageReadWrite:
+ return PAGE_READWRITE;
+ case PageReadExecute:
+ return PAGE_EXECUTE_READ;
+ case PageReadWriteExecute:
+ return PAGE_EXECUTE_READWRITE;
+ default:
+ NOTREACHED();
+ FALLTHROUGH;
+ case PageInaccessible:
+ return PAGE_NOACCESS;
+ }
+}
+
+void* SystemAllocPagesInternal(void* hint,
+ size_t length,
+ PageAccessibilityConfiguration accessibility,
+ PageTag page_tag,
+ bool commit) {
+ DWORD access_flag = GetAccessFlags(accessibility);
+ const DWORD type_flags = commit ? (MEM_RESERVE | MEM_COMMIT) : MEM_RESERVE;
+ void* ret = VirtualAlloc(hint, length, type_flags, access_flag);
+ if (ret == nullptr) {
+ s_allocPageErrorCode = GetLastError();
+ }
+ return ret;
+}
+
+void* TrimMappingInternal(void* base,
+ size_t base_length,
+ size_t trim_length,
+ PageAccessibilityConfiguration accessibility,
+ bool commit,
+ size_t pre_slack,
+ size_t post_slack) {
+ void* ret = base;
+ if (pre_slack || post_slack) {
+ // We cannot resize the allocation run. Free it and retry at the aligned
+ // address within the freed range.
+ ret = reinterpret_cast<char*>(base) + pre_slack;
+ FreePages(base, base_length);
+ ret = SystemAllocPages(ret, trim_length, accessibility, PageTag::kChromium,
+ commit);
+ }
+ return ret;
+}
+
+bool SetSystemPagesAccessInternal(
+ void* address,
+ size_t length,
+ PageAccessibilityConfiguration accessibility) {
+ if (accessibility == PageInaccessible) {
+ return VirtualFree(address, length, MEM_DECOMMIT) != 0;
+ } else {
+ return nullptr != VirtualAlloc(address, length, MEM_COMMIT,
+ GetAccessFlags(accessibility));
+ }
+}
+
+void FreePagesInternal(void* address, size_t length) {
+ CHECK(VirtualFree(address, 0, MEM_RELEASE));
+}
+
+void DecommitSystemPagesInternal(void* address, size_t length) {
+ CHECK(SetSystemPagesAccess(address, length, PageInaccessible));
+}
+
+bool RecommitSystemPagesInternal(void* address,
+ size_t length,
+ PageAccessibilityConfiguration accessibility) {
+ return SetSystemPagesAccess(address, length, accessibility);
+}
+
+void DiscardSystemPagesInternal(void* address, size_t length) {
+ // On Windows, discarded pages are not returned to the system immediately and
+ // not guaranteed to be zeroed when returned to the application.
+ using DiscardVirtualMemoryFunction =
+ DWORD(WINAPI*)(PVOID virtualAddress, SIZE_T size);
+ static DiscardVirtualMemoryFunction discard_virtual_memory =
+ reinterpret_cast<DiscardVirtualMemoryFunction>(-1);
+ if (discard_virtual_memory ==
+ reinterpret_cast<DiscardVirtualMemoryFunction>(-1))
+ discard_virtual_memory =
+ reinterpret_cast<DiscardVirtualMemoryFunction>(GetProcAddress(
+ GetModuleHandle(L"Kernel32.dll"), "DiscardVirtualMemory"));
+ // Use DiscardVirtualMemory when available because it releases faster than
+ // MEM_RESET.
+ DWORD ret = 1;
+ if (discard_virtual_memory) {
+ ret = discard_virtual_memory(address, length);
+ }
+ // DiscardVirtualMemory is buggy in Win10 SP0, so fall back to MEM_RESET on
+ // failure.
+ if (ret) {
+ void* ptr = VirtualAlloc(address, length, MEM_RESET, PAGE_READWRITE);
+ CHECK(ptr);
+ }
+}
+
+} // namespace base
+} // namespace pdfium
+
+#endif // THIRD_PARTY_BASE_ALLOCATOR_PARTITION_ALLOCATOR_PAGE_ALLOCATOR_INTERNALS_WIN_H_