mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1814798 - pt 1. Add bool to enable/disable PHC at runtime r=glandium
Add the ability to enable and disable PHC at runtime through the malloc bridge. Differential Revision: https://phabricator.services.mozilla.com/D178753
This commit is contained in:
parent
9e5ceff322
commit
accac535a0
@ -116,6 +116,19 @@ struct DMDFuncs;
|
||||
} // namespace dmd
|
||||
|
||||
namespace phc {
|
||||
|
||||
// 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,
|
||||
};
|
||||
|
||||
class AddrInfo;
|
||||
|
||||
struct MemoryUsage {
|
||||
@ -139,7 +152,7 @@ struct DebugFdRegistry {
|
||||
} // namespace mozilla
|
||||
|
||||
struct ReplaceMallocBridge {
|
||||
ReplaceMallocBridge() : mVersion(5) {}
|
||||
ReplaceMallocBridge() : mVersion(6) {}
|
||||
|
||||
// This method was added in version 1 of the bridge.
|
||||
virtual mozilla::dmd::DMDFuncs* GetDMDFuncs() { return nullptr; }
|
||||
@ -195,6 +208,11 @@ struct ReplaceMallocBridge {
|
||||
// This method was added in version 5 of the bridge.
|
||||
virtual void PHCMemoryUsage(mozilla::phc::MemoryUsage& aMemoryUsage) {}
|
||||
|
||||
// Set PHC's state. See the comments above on `PHCState` for the meaning of
|
||||
// each state.
|
||||
// This method was added in version 6 of the bridge.
|
||||
virtual void SetPHCState(mozilla::phc::PHCState aState) {}
|
||||
|
||||
# ifndef REPLACE_MALLOC_IMPL
|
||||
// Returns the replace-malloc bridge if its version is at least the
|
||||
// requested one.
|
||||
@ -269,6 +287,13 @@ struct ReplaceMalloc {
|
||||
singleton->PHCMemoryUsage(aMemoryUsage);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetPHCState(mozilla::phc::PHCState aPHCState) {
|
||||
auto singleton = ReplaceMallocBridge::Get(/* minimumVersion */ 6);
|
||||
if (singleton) {
|
||||
singleton->SetPHCState(aPHCState);
|
||||
}
|
||||
}
|
||||
};
|
||||
# endif
|
||||
|
||||
|
@ -323,6 +323,9 @@ static const size_t kAllPagesSize = kNumAllPages * kPageSize;
|
||||
// AllocAllPages() for more information.
|
||||
static const size_t kAllPagesJemallocSize = kAllPagesSize - kPageSize;
|
||||
|
||||
// The default state for PHC. Either Enabled or OnlyFree.
|
||||
#define DEFAULT_STATE mozilla::phc::Enabled
|
||||
|
||||
// The junk value used to fill new allocation in debug builds. It's same value
|
||||
// as the one used by mozjemalloc. PHC applies it unconditionally in debug
|
||||
// builds. Unlike mozjemalloc, PHC doesn't consult the MALLOC_OPTIONS
|
||||
@ -874,6 +877,14 @@ class GMut {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Should we make new PHC allocations?
|
||||
bool ShouldMakeNewAllocations() const {
|
||||
return mPhcState == mozilla::phc::Enabled;
|
||||
}
|
||||
|
||||
using PHCState = mozilla::phc::PHCState;
|
||||
void SetState(PHCState aState) { mPhcState = aState; }
|
||||
|
||||
private:
|
||||
template <int N>
|
||||
uint64_t RandomSeed() {
|
||||
@ -933,6 +944,11 @@ class GMut {
|
||||
size_t mPageAllocHits = 0;
|
||||
size_t mPageAllocMisses = 0;
|
||||
#endif
|
||||
|
||||
// This will only ever be updated from one thread. The other threads should
|
||||
// eventually get the update.
|
||||
Atomic<PHCState, Relaxed> mPhcState =
|
||||
Atomic<PHCState, Relaxed>(DEFAULT_STATE);
|
||||
};
|
||||
|
||||
Mutex GMut::sMutex;
|
||||
@ -1074,6 +1090,11 @@ static void* MaybePageAlloc(const Maybe<arena_id_t>& aArenaId, size_t aReqSize,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(gMut);
|
||||
if (!gMut->ShouldMakeNewAllocations()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GAtomic::IncrementNow();
|
||||
|
||||
// Decrement the delay. If it's zero, we do a page allocation and reset the
|
||||
@ -1344,7 +1365,7 @@ MOZ_ALWAYS_INLINE static void* PageRealloc(const Maybe<arena_id_t>& aArenaId,
|
||||
// Check for realloc() of a freed block.
|
||||
gMut->EnsureValidAndInUse(lock, aOldPtr, index);
|
||||
|
||||
if (aNewSize <= kPageSize) {
|
||||
if (aNewSize <= kPageSize && gMut->ShouldMakeNewAllocations()) {
|
||||
// A page-to-page transition. Just keep using the page allocation. We do
|
||||
// this even if the thread is disabled, because it doesn't create a new
|
||||
// page allocation. Note that ResizePageInUse() checks aArenaId.
|
||||
@ -1687,6 +1708,12 @@ class PHCBridge : public ReplaceMallocBridge {
|
||||
aMemoryUsage.mFragmentationBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable or Disable PHC at runtime. If PHC is disabled it will still trap
|
||||
// bad uses of previous allocations, but won't track any new allocations.
|
||||
virtual void SetPHCState(mozilla::phc::PHCState aState) override {
|
||||
gMut->SetState(aState);
|
||||
}
|
||||
};
|
||||
|
||||
// WARNING: this function runs *very* early -- before all static initializers
|
||||
|
Loading…
Reference in New Issue
Block a user