diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /memory/build/PHC.h | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'memory/build/PHC.h')
-rw-r--r-- | memory/build/PHC.h | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/memory/build/PHC.h b/memory/build/PHC.h new file mode 100644 index 0000000000..78820a5cf3 --- /dev/null +++ b/memory/build/PHC.h @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef PHC_h +#define PHC_h + +#include "mozilla/Assertions.h" +#include "mozilla/Maybe.h" +#include <stdint.h> +#include <stdlib.h> + +#include "mozmemory_wrap.h" + +namespace mozilla { +namespace phc { + +// Note: a stack trace may have no frames due to a collection problem. +// +// Also note: a more compact stack trace representation could be achieved with +// some effort. +struct StackTrace { + public: + static const size_t kMaxFrames = 16; + + // The number of PCs in the stack trace. + size_t mLength; + + // The PCs in the stack trace. Only the first mLength are initialized. + const void* mPcs[kMaxFrames]; + + public: + StackTrace() : mLength(0) {} +}; + +// Info from PHC about an address in memory. +class AddrInfo { + public: + enum class Kind { + // The address is not in PHC-managed memory. + Unknown = 0, + + // The address is within a PHC page that has never been allocated. A crash + // involving such an address is unlikely in practice, because it would + // require the crash to happen quite early. + NeverAllocatedPage = 1, + + // The address is within a PHC page that is in use. + InUsePage = 2, + + // The address is within a PHC page that has been allocated and then freed. + // A crash involving such an address most likely indicates a + // use-after-free. (A sufficiently wild write -- e.g. a large buffer + // overflow -- could also trigger it, but this is less likely.) + FreedPage = 3, + + // The address is within a PHC guard page. A crash involving such an + // address most likely indicates a buffer overflow. (Again, a sufficiently + // wild write could unluckily trigger it, but this is less likely.) + GuardPage = 4, + }; + + // The page kind. + Kind mKind; + + // The starting address of the allocation. + // - Unknown | NeverAllocatedPage: nullptr. + // - InUsePage | FreedPage: the address of the allocation within the page. + // - GuardPage: the mBaseAddr value from the preceding allocation page. + const void* mBaseAddr; + + // The usable size, which could be bigger than the requested size. + // - Unknown | NeverAllocatePage: 0. + // - InUsePage | FreedPage: the usable size of the allocation within the page. + // - GuardPage: the mUsableSize value from the preceding allocation page. + size_t mUsableSize; + + // The allocation stack. + // - Unknown | NeverAllocatedPage: Nothing. + // - InUsePage | FreedPage: Some. + // - GuardPage: the mAllocStack value from the preceding allocation page. + mozilla::Maybe<StackTrace> mAllocStack; + + // The free stack. + // - Unknown | NeverAllocatedPage | InUsePage: Nothing. + // - FreedPage: Some. + // - GuardPage: the mFreeStack value from the preceding allocation page. + mozilla::Maybe<StackTrace> mFreeStack; + + // True if PHC was locked and therefore we couldn't retrive some infomation. + bool mPhcWasLocked = false; + + // Default to no PHC info. + AddrInfo() : mKind(Kind::Unknown), mBaseAddr(nullptr), mUsableSize(0) {} +}; + +// Global instance that is retrieved by the process generating the crash report +extern AddrInfo gAddrInfo; + +// If this is a PHC-handled address, return true, and if an AddrInfo is +// provided, fill in all of its fields. Otherwise, return false and leave +// AddrInfo unchanged. +MOZ_JEMALLOC_API bool IsPHCAllocation(const void*, AddrInfo*); + +// Disable PHC allocations on the current thread. Only useful for tests. Note +// that PHC deallocations will still occur as needed. +MOZ_JEMALLOC_API void DisablePHCOnCurrentThread(); + +// Re-enable PHC allocations on the current thread. Only useful for tests. +MOZ_JEMALLOC_API void ReenablePHCOnCurrentThread(); + +// Test whether PHC allocations are enabled on the current thread. Only +// useful for tests. +MOZ_JEMALLOC_API bool IsPHCEnabledOnCurrentThread(); + +// PHC has three different states: +// * Not compiled in +// * OnlyFree - The memory allocator is hooked but new allocations +// requests will be forwarded to mozjemalloc, free() will +// correctly free any PHC allocations and realloc() will +// "move" PHC allocations to mozjemalloc allocations. +// * Enabled - Full use. +enum PHCState { + OnlyFree, + Enabled, +}; + +MOZ_JEMALLOC_API void SetPHCState(PHCState aState); + +MOZ_JEMALLOC_API void SetPHCProbabilities(int64_t aAvgDelayFirst, + int64_t aAvgDelayNormal, + int64_t aAvgDelayPageReuse); + +struct MemoryUsage { + // The amount of memory used for PHC metadata, eg information about each + // allocation including stacks. + size_t mMetadataBytes = 0; + + // The amount of memory lost due to rounding allocation sizes up to the + // nearest page. AKA internal fragmentation. + size_t mFragmentationBytes = 0; +}; + +MOZ_JEMALLOC_API void PHCMemoryUsage(MemoryUsage& aMemoryUsage); + +struct PHCStats { + size_t mSlotsAllocated = 0; + size_t mSlotsFreed = 0; + size_t mSlotsUnused = 0; +}; + +// Return PHC memory usage information by filling in the supplied structure. +MOZ_JEMALLOC_API void GetPHCStats(PHCStats& aStats); + +} // namespace phc +} // namespace mozilla + +#endif /* PHC_h */ |