author | Gabriele Svelto <gsvelto@mozilla.com> |
Wed, 18 Apr 2018 17:07:39 +0200 | |
changeset 414952 | 9dcde577687cd5519b2156728f033c322e142a51 |
parent 414951 | 0f113bac293a677b74c6fc2ce9ecc2a7af09e0e2 |
child 414953 | dbc1cffb4a11cabf48862d5206f139dd190c94ce |
child 414980 | 5a5ca0495cda64fde9c27ca31aced494a8739e30 |
push id | 102441 |
push user | gsvelto@mozilla.com |
push date | Sat, 21 Apr 2018 18:51:39 +0000 |
treeherder | mozilla-inbound@9dcde577687c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | njn |
bugs | 1451002 |
milestone | 61.0a1 |
first release with | nightly linux32
9dcde577687c
/
61.0a1
/
20180421220102
/
files
nightly linux64
9dcde577687c
/
61.0a1
/
20180421220102
/
files
nightly mac
9dcde577687c
/
61.0a1
/
20180421220102
/
files
nightly win32
9dcde577687c
/
61.0a1
/
20180421220102
/
files
nightly win64
9dcde577687c
/
61.0a1
/
20180421220102
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
61.0a1
/
20180421220102
/
pushlog to previous
nightly linux64
61.0a1
/
20180421220102
/
pushlog to previous
nightly mac
61.0a1
/
20180421220102
/
pushlog to previous
nightly win32
61.0a1
/
20180421220102
/
pushlog to previous
nightly win64
61.0a1
/
20180421220102
/
pushlog to previous
|
--- a/xpcom/base/AvailableMemoryTracker.cpp +++ b/xpcom/base/AvailableMemoryTracker.cpp @@ -32,120 +32,135 @@ #endif // MOZ_MEMORY using namespace mozilla; namespace { #if defined(_M_IX86) && defined(XP_WIN) -// Fire a low-memory notification if we have less than this many MiB of virtual -// address space available. -static const uint32_t kLowVirtualMemoryThresholdMiB = 256; +// Fire a low-memory notification if we have less than this many bytes of +// virtual address space available. +static const size_t kLowVirtualMemoryThreshold = 256 * 1024 * 1024; -// Fire a low-memory notification if we have less than this many MiB of commit +// Fire a low-memory notification if we have less than this many bytes of commit // space (physical memory plus page file) left. -static const uint32_t kLowCommitSpaceThresholdMiB = 256; +static const size_t kLowCommitSpaceThreshold = 256 * 1024 * 1024; -// Fire a low-memory notification if we have less than this many MiB of +// Fire a low-memory notification if we have less than this many bytes of // physical memory available on the whole machine. -static const uint32_t kLowPhysicalMemoryThresholdMiB = 0; +static const size_t kLowPhysicalMemoryThreshold = 0; // Don't fire a low-memory notification because of low available physical // memory or low commit space more often than this interval. static const uint32_t kLowMemoryNotificationIntervalMS = 10000; -Atomic<uint32_t> sNumLowVirtualMemEvents; -Atomic<uint32_t> sNumLowCommitSpaceEvents; -Atomic<uint32_t> sNumLowPhysicalMemEvents; +Atomic<uint32_t, MemoryOrdering::Relaxed> sNumLowVirtualMemEvents; +Atomic<uint32_t, MemoryOrdering::Relaxed> sNumLowCommitSpaceEvents; +Atomic<uint32_t, MemoryOrdering::Relaxed> sNumLowPhysicalMemEvents; WindowsDllInterceptor sKernel32Intercept; WindowsDllInterceptor sGdi32Intercept; // Has Init() been called? bool sInitialized = false; // Has Activate() been called? The hooks don't do anything until this happens. bool sHooksActive = false; // Alas, we'd like to use mozilla::TimeStamp, but we can't, because it acquires // a lock! -volatile bool sHasScheduledOneLowMemoryNotification = false; +volatile bool sUnderMemoryPressure = false; volatile PRIntervalTime sLastLowMemoryNotificationTime; // These are function pointers to the functions we wrap in Init(). void* (WINAPI* sVirtualAllocOrig)(LPVOID aAddress, SIZE_T aSize, DWORD aAllocationType, DWORD aProtect); void* (WINAPI* sMapViewOfFileOrig)(HANDLE aFileMappingObject, DWORD aDesiredAccess, DWORD aFileOffsetHigh, DWORD aFileOffsetLow, SIZE_T aNumBytesToMap); HBITMAP(WINAPI* sCreateDIBSectionOrig)(HDC aDC, const BITMAPINFO* aBitmapInfo, UINT aUsage, VOID** aBits, HANDLE aSection, DWORD aOffset); /** - * Fire a memory pressure event if it's been long enough since the last one we + * Fire a memory pressure event if we were not under memory pressure yet, or + * fire an ongoing one if it's been long enough since the last one we * fired. */ bool MaybeScheduleMemoryPressureEvent() { + MemoryPressureState state = MemPressure_New; + PRIntervalTime now = PR_IntervalNow(); + // If this interval rolls over, we may fire an extra memory pressure // event, but that's not a big deal. - PRIntervalTime interval = PR_IntervalNow() - sLastLowMemoryNotificationTime; - if (sHasScheduledOneLowMemoryNotification && - PR_IntervalToMilliseconds(interval) < kLowMemoryNotificationIntervalMS) { + PRIntervalTime interval = now - sLastLowMemoryNotificationTime; + if (sUnderMemoryPressure) { + if (PR_IntervalToMilliseconds(interval) < + kLowMemoryNotificationIntervalMS) { + return false; + } - return false; + state = MemPressure_Ongoing; } // There's a bit of a race condition here, since an interval may be a // 64-bit number, and 64-bit writes aren't atomic on x86-32. But let's // not worry about it -- the races only happen when we're already // experiencing memory pressure and firing notifications, so the worst // thing that can happen is that we fire two notifications when we // should have fired only one. - sHasScheduledOneLowMemoryNotification = true; - sLastLowMemoryNotificationTime = PR_IntervalNow(); + sUnderMemoryPressure = true; + sLastLowMemoryNotificationTime = now; + + NS_DispatchEventualMemoryPressure(state); + return true; +} - NS_DispatchEventualMemoryPressure(MemPressure_New); - return true; +static bool +CheckLowMemory(DWORDLONG available, size_t threshold, + Atomic<uint32_t, MemoryOrdering::Relaxed>& counter) +{ + if (available < threshold) { + if (MaybeScheduleMemoryPressureEvent()) { + counter++; + } + + return true; + } + + return false; } void CheckMemAvailable() { if (!sHooksActive) { return; } MEMORYSTATUSEX stat; stat.dwLength = sizeof(stat); bool success = GlobalMemoryStatusEx(&stat); if (success) { - // kLowVirtualMemoryThresholdMiB is in MiB, but ullAvailVirtual is in bytes. - if (stat.ullAvailVirtual < kLowVirtualMemoryThresholdMiB * 1024 * 1024) { - // If we're running low on virtual memory, unconditionally schedule the - // notification. We'll probably crash if we run out of virtual memory, - // so don't worry about firing this notification too often. - ++sNumLowVirtualMemEvents; - NS_DispatchEventualMemoryPressure(MemPressure_New); - } else if (stat.ullAvailPageFile < kLowCommitSpaceThresholdMiB * 1024 * 1024) { - if (MaybeScheduleMemoryPressureEvent()) { - ++sNumLowCommitSpaceEvents; - } - } else if (stat.ullAvailPhys < kLowPhysicalMemoryThresholdMiB * 1024 * 1024) { - if (MaybeScheduleMemoryPressureEvent()) { - ++sNumLowPhysicalMemEvents; - } - } + bool lowMemory = CheckLowMemory(stat.ullAvailVirtual, + kLowVirtualMemoryThreshold, + sNumLowVirtualMemEvents); + lowMemory |= CheckLowMemory(stat.ullAvailPageFile, kLowCommitSpaceThreshold, + sNumLowCommitSpaceEvents); + lowMemory |= CheckLowMemory(stat.ullAvailPhys, kLowPhysicalMemoryThreshold, + sNumLowPhysicalMemEvents); + + sUnderMemoryPressure = lowMemory; } } LPVOID WINAPI VirtualAllocHook(LPVOID aAddress, SIZE_T aSize, DWORD aAllocationType, DWORD aProtect) { @@ -161,18 +176,19 @@ VirtualAllocHook(LPVOID aAddress, SIZE_T // afterwards how much free virtual address space we have. If we're running // low, we schedule a low-memory notification to run as soon as possible. LPVOID result = sVirtualAllocOrig(aAddress, aSize, aAllocationType, aProtect); // Don't call CheckMemAvailable for MEM_RESERVE if we're not tracking low // virtual memory. Similarly, don't call CheckMemAvailable for MEM_COMMIT if // we're not tracking low physical memory. - if ((kLowVirtualMemoryThresholdMiB != 0 && aAllocationType & MEM_RESERVE) || - (kLowPhysicalMemoryThresholdMiB != 0 && aAllocationType & MEM_COMMIT)) { + if ((kLowVirtualMemoryThreshold != 0 && aAllocationType & MEM_RESERVE) || + ((kLowCommitSpaceThreshold != 0 || kLowPhysicalMemoryThreshold != 0) && + aAllocationType & MEM_COMMIT)) { CheckMemAvailable(); } return result; } LPVOID WINAPI MapViewOfFileHook(HANDLE aFileMappingObject,