Bug 1910362 - Create new Nimbus helper r=aaronmt,ohorvath
[gecko.git] / xpcom / base / MemoryInfo.cpp
blob6ce7f2b76817e6ef743ee0b67ce986829427223e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/MemoryInfo.h"
9 #include "mozilla/DebugOnly.h"
11 #include <algorithm>
12 #include <windows.h>
14 namespace mozilla {
16 /* static */
17 MemoryInfo MemoryInfo::Get(const void* aPtr, size_t aSize) {
18 MemoryInfo result;
20 result.mStart = uintptr_t(aPtr);
21 const char* ptr = reinterpret_cast<const char*>(aPtr);
22 const char* end = ptr + aSize;
23 DebugOnly<void*> base = nullptr;
24 while (ptr < end) {
25 MEMORY_BASIC_INFORMATION basicInfo;
26 if (!VirtualQuery(ptr, &basicInfo, sizeof(basicInfo))) {
27 break;
30 MOZ_ASSERT_IF(base, base == basicInfo.AllocationBase);
31 base = basicInfo.AllocationBase;
33 size_t regionSize =
34 std::min(size_t(basicInfo.RegionSize), size_t(end - ptr));
36 if (basicInfo.State == MEM_COMMIT) {
37 result.mCommitted += regionSize;
38 } else if (basicInfo.State == MEM_RESERVE) {
39 result.mReserved += regionSize;
40 } else if (basicInfo.State == MEM_FREE) {
41 result.mFree += regionSize;
42 } else {
43 MOZ_ASSERT_UNREACHABLE("Unexpected region state");
45 result.mSize += regionSize;
46 ptr += regionSize;
48 if (result.mType.isEmpty()) {
49 if (basicInfo.Type & MEM_IMAGE) {
50 result.mType += PageType::Image;
52 if (basicInfo.Type & MEM_MAPPED) {
53 result.mType += PageType::Mapped;
55 if (basicInfo.Type & MEM_PRIVATE) {
56 result.mType += PageType::Private;
59 // The first 8 bits of AllocationProtect are an enum. The remaining bits
60 // are flags.
61 switch (basicInfo.AllocationProtect & 0xff) {
62 case PAGE_EXECUTE_WRITECOPY:
63 result.mPerms += Perm::CopyOnWrite;
64 [[fallthrough]];
65 case PAGE_EXECUTE_READWRITE:
66 result.mPerms += Perm::Write;
67 [[fallthrough]];
68 case PAGE_EXECUTE_READ:
69 result.mPerms += Perm::Read;
70 [[fallthrough]];
71 case PAGE_EXECUTE:
72 result.mPerms += Perm::Execute;
73 break;
75 case PAGE_WRITECOPY:
76 result.mPerms += Perm::CopyOnWrite;
77 [[fallthrough]];
78 case PAGE_READWRITE:
79 result.mPerms += Perm::Write;
80 [[fallthrough]];
81 case PAGE_READONLY:
82 result.mPerms += Perm::Read;
83 break;
85 default:
86 break;
89 if (basicInfo.AllocationProtect & PAGE_GUARD) {
90 result.mPerms += Perm::Guard;
92 if (basicInfo.AllocationProtect & PAGE_NOCACHE) {
93 result.mPerms += Perm::NoCache;
95 if (basicInfo.AllocationProtect & PAGE_WRITECOMBINE) {
96 result.mPerms += Perm::WriteCombine;
101 result.mEnd = uintptr_t(ptr);
102 return result;
105 } // namespace mozilla