Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / memory / build / PHC.h
blob78820a5cf3f34ad1a32ad828ac410669c4a70fcd
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=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 #ifndef PHC_h
8 #define PHC_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Maybe.h"
12 #include <stdint.h>
13 #include <stdlib.h>
15 #include "mozmemory_wrap.h"
17 namespace mozilla {
18 namespace phc {
20 // Note: a stack trace may have no frames due to a collection problem.
22 // Also note: a more compact stack trace representation could be achieved with
23 // some effort.
24 struct StackTrace {
25 public:
26 static const size_t kMaxFrames = 16;
28 // The number of PCs in the stack trace.
29 size_t mLength;
31 // The PCs in the stack trace. Only the first mLength are initialized.
32 const void* mPcs[kMaxFrames];
34 public:
35 StackTrace() : mLength(0) {}
38 // Info from PHC about an address in memory.
39 class AddrInfo {
40 public:
41 enum class Kind {
42 // The address is not in PHC-managed memory.
43 Unknown = 0,
45 // The address is within a PHC page that has never been allocated. A crash
46 // involving such an address is unlikely in practice, because it would
47 // require the crash to happen quite early.
48 NeverAllocatedPage = 1,
50 // The address is within a PHC page that is in use.
51 InUsePage = 2,
53 // The address is within a PHC page that has been allocated and then freed.
54 // A crash involving such an address most likely indicates a
55 // use-after-free. (A sufficiently wild write -- e.g. a large buffer
56 // overflow -- could also trigger it, but this is less likely.)
57 FreedPage = 3,
59 // The address is within a PHC guard page. A crash involving such an
60 // address most likely indicates a buffer overflow. (Again, a sufficiently
61 // wild write could unluckily trigger it, but this is less likely.)
62 GuardPage = 4,
65 // The page kind.
66 Kind mKind;
68 // The starting address of the allocation.
69 // - Unknown | NeverAllocatedPage: nullptr.
70 // - InUsePage | FreedPage: the address of the allocation within the page.
71 // - GuardPage: the mBaseAddr value from the preceding allocation page.
72 const void* mBaseAddr;
74 // The usable size, which could be bigger than the requested size.
75 // - Unknown | NeverAllocatePage: 0.
76 // - InUsePage | FreedPage: the usable size of the allocation within the page.
77 // - GuardPage: the mUsableSize value from the preceding allocation page.
78 size_t mUsableSize;
80 // The allocation stack.
81 // - Unknown | NeverAllocatedPage: Nothing.
82 // - InUsePage | FreedPage: Some.
83 // - GuardPage: the mAllocStack value from the preceding allocation page.
84 mozilla::Maybe<StackTrace> mAllocStack;
86 // The free stack.
87 // - Unknown | NeverAllocatedPage | InUsePage: Nothing.
88 // - FreedPage: Some.
89 // - GuardPage: the mFreeStack value from the preceding allocation page.
90 mozilla::Maybe<StackTrace> mFreeStack;
92 // True if PHC was locked and therefore we couldn't retrive some infomation.
93 bool mPhcWasLocked = false;
95 // Default to no PHC info.
96 AddrInfo() : mKind(Kind::Unknown), mBaseAddr(nullptr), mUsableSize(0) {}
99 // Global instance that is retrieved by the process generating the crash report
100 extern AddrInfo gAddrInfo;
102 // If this is a PHC-handled address, return true, and if an AddrInfo is
103 // provided, fill in all of its fields. Otherwise, return false and leave
104 // AddrInfo unchanged.
105 MOZ_JEMALLOC_API bool IsPHCAllocation(const void*, AddrInfo*);
107 // Disable PHC allocations on the current thread. Only useful for tests. Note
108 // that PHC deallocations will still occur as needed.
109 MOZ_JEMALLOC_API void DisablePHCOnCurrentThread();
111 // Re-enable PHC allocations on the current thread. Only useful for tests.
112 MOZ_JEMALLOC_API void ReenablePHCOnCurrentThread();
114 // Test whether PHC allocations are enabled on the current thread. Only
115 // useful for tests.
116 MOZ_JEMALLOC_API bool IsPHCEnabledOnCurrentThread();
118 // PHC has three different states:
119 // * Not compiled in
120 // * OnlyFree - The memory allocator is hooked but new allocations
121 // requests will be forwarded to mozjemalloc, free() will
122 // correctly free any PHC allocations and realloc() will
123 // "move" PHC allocations to mozjemalloc allocations.
124 // * Enabled - Full use.
125 enum PHCState {
126 OnlyFree,
127 Enabled,
130 MOZ_JEMALLOC_API void SetPHCState(PHCState aState);
132 MOZ_JEMALLOC_API void SetPHCProbabilities(int64_t aAvgDelayFirst,
133 int64_t aAvgDelayNormal,
134 int64_t aAvgDelayPageReuse);
136 struct MemoryUsage {
137 // The amount of memory used for PHC metadata, eg information about each
138 // allocation including stacks.
139 size_t mMetadataBytes = 0;
141 // The amount of memory lost due to rounding allocation sizes up to the
142 // nearest page. AKA internal fragmentation.
143 size_t mFragmentationBytes = 0;
146 MOZ_JEMALLOC_API void PHCMemoryUsage(MemoryUsage& aMemoryUsage);
148 struct PHCStats {
149 size_t mSlotsAllocated = 0;
150 size_t mSlotsFreed = 0;
151 size_t mSlotsUnused = 0;
154 // Return PHC memory usage information by filling in the supplied structure.
155 MOZ_JEMALLOC_API void GetPHCStats(PHCStats& aStats);
157 } // namespace phc
158 } // namespace mozilla
160 #endif /* PHC_h */