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/. */ 6 7 #include "mozilla/MemoryInfo.h" 8 9 #include "mozilla/DebugOnly.h" 10 11 #include <algorithm> 12 #include <windows.h> 13 14 namespace mozilla { 15 16 /* static */ Get(const void * aPtr,size_t aSize)17MemoryInfo MemoryInfo::Get(const void* aPtr, size_t aSize) { 18 MemoryInfo result; 19 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; 28 } 29 30 MOZ_ASSERT_IF(base, base == basicInfo.AllocationBase); 31 base = basicInfo.AllocationBase; 32 33 size_t regionSize = 34 std::min(size_t(basicInfo.RegionSize), size_t(end - ptr)); 35 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"); 44 } 45 result.mSize += regionSize; 46 ptr += regionSize; 47 48 if (result.mType.isEmpty()) { 49 if (basicInfo.Type & MEM_IMAGE) { 50 result.mType += PageType::Image; 51 } 52 if (basicInfo.Type & MEM_MAPPED) { 53 result.mType += PageType::Mapped; 54 } 55 if (basicInfo.Type & MEM_PRIVATE) { 56 result.mType += PageType::Private; 57 } 58 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; 74 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; 84 85 default: 86 break; 87 } 88 89 if (basicInfo.AllocationProtect & PAGE_GUARD) { 90 result.mPerms += Perm::Guard; 91 } 92 if (basicInfo.AllocationProtect & PAGE_NOCACHE) { 93 result.mPerms += Perm::NoCache; 94 } 95 if (basicInfo.AllocationProtect & PAGE_WRITECOMBINE) { 96 result.mPerms += Perm::WriteCombine; 97 } 98 } 99 } 100 101 result.mEnd = uintptr_t(ptr); 102 return result; 103 } 104 105 } // namespace mozilla 106