зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1867190 - Make the PHC probability dynamic r=glandium
Differential Revision: https://phabricator.services.mozilla.com/D194364
This commit is contained in:
Родитель
48de47067e
Коммит
9f2470a841
|
@ -337,32 +337,13 @@ static const size_t kAllPagesJemallocSize = kAllPagesSize - kPageSize;
|
|||
// The maximum time.
|
||||
static const Time kMaxTime = ~(Time(0));
|
||||
|
||||
// The average delay before doing any page allocations at the start of a
|
||||
// process. Note that roughly 1 million allocations occur in the main process
|
||||
// while starting the browser. The delay range is 1..kAvgFirstAllocDelay*2.
|
||||
static const Delay kAvgFirstAllocDelay = 64 * 1024;
|
||||
|
||||
// The average delay until the next attempted page allocation, once we get past
|
||||
// the first delay. The delay range is 1..kAvgAllocDelay*2.
|
||||
static const Delay kAvgAllocDelay = 16 * 1024;
|
||||
|
||||
// The average delay before reusing a freed page. Should be significantly larger
|
||||
// than kAvgAllocDelay, otherwise there's not much point in having it. The delay
|
||||
// range is (kAvgAllocDelay / 2)..(kAvgAllocDelay / 2 * 3). This is different to
|
||||
// the other delay ranges in not having a minimum of 1, because that's such a
|
||||
// short delay that there is a high likelihood of bad stacks in any crash
|
||||
// report.
|
||||
static const Delay kAvgPageReuseDelay = 256 * 1024;
|
||||
|
||||
// Truncate aRnd to the range (1 .. AvgDelay*2). If aRnd is random, this
|
||||
// Truncate aRnd to the range (1 .. aAvgDelay*2). If aRnd is random, this
|
||||
// results in an average value of aAvgDelay + 0.5, which is close enough to
|
||||
// aAvgDelay. aAvgDelay must be a power-of-two (otherwise it will crash) for
|
||||
// speed.
|
||||
template <Delay AvgDelay>
|
||||
constexpr Delay Rnd64ToDelay(uint64_t aRnd) {
|
||||
static_assert(IsPowerOfTwo(AvgDelay), "must be a power of two");
|
||||
// aAvgDelay. aAvgDelay must be a power-of-two for speed.
|
||||
constexpr Delay Rnd64ToDelay(Delay aAvgDelay, uint64_t aRnd) {
|
||||
MOZ_ASSERT(IsPowerOfTwo(aAvgDelay), "must be a power of two");
|
||||
|
||||
return aRnd % (AvgDelay * 2) + 1;
|
||||
return (aRnd & (aAvgDelay * 2 - 1)) + 1;
|
||||
}
|
||||
|
||||
// Maps a pointer to a PHC-specific structure:
|
||||
|
@ -437,10 +418,11 @@ class GAtomic {
|
|||
|
||||
static void SetAllocDelay(Delay aAllocDelay) { sAllocDelay = aAllocDelay; }
|
||||
|
||||
static bool AllocDelayHasWrapped() {
|
||||
static bool AllocDelayHasWrapped(Delay aAvgAllocDelay,
|
||||
Delay aAvgFirstAllocDelay) {
|
||||
// Delay is unsigned so we can't test for less that zero. Instead test if
|
||||
// it has wrapped around by comparing with the maximum value we ever use.
|
||||
return sAllocDelay > 2 * std::max(kAvgAllocDelay, kAvgFirstAllocDelay);
|
||||
return sAllocDelay > 2 * std::max(aAvgAllocDelay, aAvgFirstAllocDelay);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -875,7 +857,7 @@ class GMut {
|
|||
void SetState(PHCState aState) {
|
||||
if (mPhcState != PHCState::Enabled && aState == PHCState::Enabled) {
|
||||
MutexAutoLock lock(GMut::sMutex);
|
||||
GAtomic::Init(Rnd64ToDelay<kAvgFirstAllocDelay>(Random64(lock)));
|
||||
GAtomic::Init(Rnd64ToDelay(mAvgFirstAllocDelay, Random64(lock)));
|
||||
}
|
||||
|
||||
mPhcState = aState;
|
||||
|
@ -945,6 +927,32 @@ class GMut {
|
|||
// eventually get the update.
|
||||
Atomic<PHCState, Relaxed> mPhcState =
|
||||
Atomic<PHCState, Relaxed>(DEFAULT_STATE);
|
||||
|
||||
// The average delay before doing any page allocations at the start of a
|
||||
// process. Note that roughly 1 million allocations occur in the main process
|
||||
// while starting the browser. The delay range is 1..gAvgFirstAllocDelay*2.
|
||||
Delay mAvgFirstAllocDelay = 64 * 1024;
|
||||
|
||||
// The average delay until the next attempted page allocation, once we get
|
||||
// past the first delay. The delay range is 1..kAvgAllocDelay*2.
|
||||
Delay mAvgAllocDelay = 16 * 1024;
|
||||
|
||||
// The average delay before reusing a freed page. Should be significantly
|
||||
// larger than kAvgAllocDelay, otherwise there's not much point in having it.
|
||||
// The delay range is (kAvgAllocDelay / 2)..(kAvgAllocDelay / 2 * 3). This is
|
||||
// different to the other delay ranges in not having a minimum of 1, because
|
||||
// that's such a short delay that there is a high likelihood of bad stacks in
|
||||
// any crash report.
|
||||
Delay mAvgPageReuseDelay = 256 * 1024;
|
||||
|
||||
public:
|
||||
Delay GetAvgAllocDelay(const MutexAutoLock&) { return mAvgAllocDelay; }
|
||||
Delay GetAvgFirstAllocDelay(const MutexAutoLock&) {
|
||||
return mAvgFirstAllocDelay;
|
||||
}
|
||||
Delay GetAvgPageReuseDelay(const MutexAutoLock&) {
|
||||
return mAvgPageReuseDelay;
|
||||
}
|
||||
};
|
||||
|
||||
Mutex GMut::sMutex;
|
||||
|
@ -1040,13 +1048,11 @@ class GTls {
|
|||
|
||||
static void EnableOnCurrentThread() {
|
||||
MOZ_ASSERT(GTls::tlsIsDisabled.get());
|
||||
uint64_t rand;
|
||||
if (GAtomic::AllocDelayHasWrapped()) {
|
||||
{
|
||||
MutexAutoLock lock(GMut::sMutex);
|
||||
rand = gMut->Random64(lock);
|
||||
}
|
||||
GAtomic::SetAllocDelay(Rnd64ToDelay<kAvgAllocDelay>(rand));
|
||||
MutexAutoLock lock(GMut::sMutex);
|
||||
Delay avg_delay = gMut->GetAvgAllocDelay(lock);
|
||||
Delay avg_first_delay = gMut->GetAvgFirstAllocDelay(lock);
|
||||
if (GAtomic::AllocDelayHasWrapped(avg_delay, avg_first_delay)) {
|
||||
GAtomic::SetAllocDelay(Rnd64ToDelay(avg_delay, gMut->Random64(lock)));
|
||||
}
|
||||
tlsIsDisabled.set(false);
|
||||
}
|
||||
|
@ -1185,7 +1191,8 @@ static void* MaybePageAlloc(const Maybe<arena_id_t>& aArenaId, size_t aReqSize,
|
|||
MutexAutoLock lock(GMut::sMutex);
|
||||
|
||||
Time now = GAtomic::Now();
|
||||
Delay newAllocDelay = Rnd64ToDelay<kAvgAllocDelay>(gMut->Random64(lock));
|
||||
Delay newAllocDelay =
|
||||
Rnd64ToDelay(gMut->GetAvgAllocDelay(lock), gMut->Random64(lock));
|
||||
|
||||
// We start at a random page alloc and wrap around, to ensure pages get even
|
||||
// amounts of use.
|
||||
|
@ -1312,8 +1319,9 @@ inline void* MozJemallocPHC::malloc(size_t aReqSize) {
|
|||
}
|
||||
|
||||
static Delay ReuseDelay(GMutLock aLock) {
|
||||
return (kAvgPageReuseDelay / 2) +
|
||||
Rnd64ToDelay<kAvgPageReuseDelay / 2>(gMut->Random64(aLock));
|
||||
Delay avg_reuse_delay = gMut->GetAvgPageReuseDelay(aLock);
|
||||
return (avg_reuse_delay / 2) +
|
||||
Rnd64ToDelay(avg_reuse_delay / 2, gMut->Random64(aLock));
|
||||
}
|
||||
|
||||
// This handles both calloc and moz_arena_calloc.
|
||||
|
|
Загрузка…
Ссылка в новой задаче