author | Justin Lebar <justin.lebar@gmail.com> |
Thu, 15 Dec 2011 09:42:21 -0500 | |
changeset 82644 | 1385112d84f625b4e98bd1219383e36672c53b3a |
parent 82643 | dc6fc6888bd8eb524aa590ec46af2c721fa741e9 |
child 82645 | e8659eb419fbff376015ef5c4ab83c7dccbaabc5 |
push id | 4036 |
push user | jlebar@mozilla.com |
push date | Thu, 15 Dec 2011 14:42:43 +0000 |
treeherder | mozilla-inbound@1385112d84f6 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 670967 |
milestone | 11.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
client.mk | file | annotate | diff | comparison | revisions | |
modules/libpref/src/init/all.js | file | annotate | diff | comparison | revisions | |
xpcom/base/AvailableMemoryTracker.cpp | file | annotate | diff | comparison | revisions | |
xpcom/base/AvailableMemoryTracker.h | file | annotate | diff | comparison | revisions | |
xpcom/base/Makefile.in | file | annotate | diff | comparison | revisions | |
xpcom/build/nsXPComInit.cpp | file | annotate | diff | comparison | revisions | |
xpcom/threads/Makefile.in | file | annotate | diff | comparison | revisions | |
xpcom/threads/nsThread.cpp | file | annotate | diff | comparison | revisions | |
xpcom/threads/nsThread.h | file | annotate | diff | comparison | revisions |
--- a/client.mk +++ b/client.mk @@ -209,19 +209,19 @@ everything: clean build # application until all the build passes and postflight scripts have run. ifdef MOZ_OBJDIR PGO_OBJDIR = $(MOZ_OBJDIR) else PGO_OBJDIR := $(TOPSRCDIR) endif profiledbuild:: - $(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 MOZ_PGO_INSTRUMENTED=1 - $(MAKE) -C $(PGO_OBJDIR) stage-package MOZ_PGO_INSTRUMENTED=1 - MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT) + $(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 + $(MAKE) -C $(PGO_OBJDIR) stage-package + OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT) $(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild $(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1 ##################################################### # Build date unification ifdef MOZ_UNIFY_BDATE ifndef MOZ_BUILD_DATE
--- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3404,22 +3404,8 @@ pref("dom.sms.whitelist", ""); // enable JS dump() function. pref("browser.dom.window.dump.enabled", false); // SPS Profiler pref("profiler.enabled", false); pref("profiler.interval", 10); pref("profiler.entries", 100000); -#ifdef XP_WIN -// On 32-bit Windows, fire a low-memory notification if we have less than this -// many mb of virtual address space available. -pref("memory.low_virtual_memory_threshold_mb", 128); - -// On Windows 32- or 64-bit, fire a low-memory notification if we have less -// than this many mb of physical memory available on the whole machine. -pref("memory.low_physical_mem_threshold_mb", 0); - -// On Windows 32- or 64-bit, don't fire a low-memory notification because of -// low available physical memory more than once every -// low_physical_memory_notification_interval_ms. -pref("memory.low_physical_memory_notification_interval_ms", 10000); -#endif
deleted file mode 100644 --- a/xpcom/base/AvailableMemoryTracker.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 ci et: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla.org code. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Justin Lebar <justin.lebar@gmail.com> - * - * ***** END LICENSE BLOCK ***** */ - -#include "mozilla/AvailableMemoryTracker.h" -#include "nsThread.h" -#include "nsIObserverService.h" -#include "mozilla/Services.h" -#include "mozilla/Preferences.h" -#include "nsWindowsDllInterceptor.h" -#include "prinrval.h" -#include "pratom.h" -#include "prenv.h" -#include <windows.h> - -namespace mozilla { -namespace AvailableMemoryTracker { - -// We don't want our diagnostic functions to call malloc, because that could -// call VirtualAlloc, and we'd end up back in here! So here are a few simple -// debugging macros (modeled on jemalloc's), which hopefully won't allocate. - -// #define LOGGING_ENABLED - -#ifdef LOGGING_ENABLED - -#define LOG(msg) \ - do { \ - safe_write(msg); \ - safe_write("\n"); \ - } while(0) - -#define LOG2(m1, m2) \ - do { \ - safe_write(m1); \ - safe_write(m2); \ - safe_write("\n"); \ - } while(0) - -#define LOG3(m1, m2, m3) \ - do { \ - safe_write(m1); \ - safe_write(m2); \ - safe_write(m3); \ - safe_write("\n"); \ - } while(0) - -#define LOG4(m1, m2, m3, m4) \ - do { \ - safe_write(m1); \ - safe_write(m2); \ - safe_write(m3); \ - safe_write(m4); \ - safe_write("\n"); \ - } while(0) - -#else - -#define LOG(msg) -#define LOG2(m1, m2) -#define LOG3(m1, m2, m3) -#define LOG4(m1, m2, m3, m4) - -#endif - -void safe_write(const char *a) -{ - // Well, puts isn't exactly "safe", but at least it doesn't call malloc... - fputs(a, stdout); -} - -void safe_write(PRUint64 x) -{ - // 2^64 is 20 decimal digits. - const int max_len = 21; - char buf[max_len]; - buf[max_len - 1] = '\0'; - - PRUint32 i; - for (i = max_len - 2; i >= 0 && x > 0; i--) - { - buf[i] = "0123456789"[x % 10]; - x /= 10; - } - - safe_write(&buf[i + 1]); -} - -#ifdef DEBUG -#define DEBUG_WARN_IF_FALSE(cond, msg) \ - do { \ - if (!(cond)) { \ - safe_write(__FILE__); \ - safe_write(":"); \ - safe_write(__LINE__); \ - safe_write(" "); \ - safe_write(msg); \ - safe_write("\n"); \ - } \ - } while(0) -#else -#define DEBUG_WARN_IF_FALSE(cond, msg) -#endif - -PRUint32 sLowVirtualMemoryThreshold = 0; -PRUint32 sLowPhysicalMemoryThreshold = 0; -PRUint32 sLowPhysicalMemoryNotificationIntervalMS = 0; - -WindowsDllInterceptor sKernel32Intercept; -WindowsDllInterceptor sGdi32Intercept; - -// Alas, we'd like to use mozilla::TimeStamp, but we can't, because it acquires -// a lock! -volatile bool sHasScheduledOneLowMemoryNotification = 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); - -void CheckMemAvailable() -{ - MEMORYSTATUSEX stat; - stat.dwLength = sizeof(stat); - bool success = GlobalMemoryStatusEx(&stat); - - DEBUG_WARN_IF_FALSE(success, "GlobalMemoryStatusEx failed."); - - if (success) - { - // sLowVirtualMemoryThreshold is in MB, but ullAvailVirtual is in bytes. - if (stat.ullAvailVirtual < sLowVirtualMemoryThreshold * 1024 * 1024) { - // If we're running low on virtual memory, schedule the notification. - // We'll probably crash if we run out of virtual memory, so don't worry - // about firing this notification too often. - LOG("Detected low virtual memory."); - ScheduleMemoryPressureEvent(); - } - else if (stat.ullAvailPhys < sLowPhysicalMemoryThreshold * 1024 * 1024) { - LOG("Detected low physical memory."); - // If the machine is running low on physical memory and it's been long - // enough since we last fired a low-memory notification, fire a - // notification. - // - // 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) >= - sLowPhysicalMemoryNotificationIntervalMS) { - - // 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(); - - LOG("Scheduling memory pressure notification."); - ScheduleMemoryPressureEvent(); - } - else { - LOG("Not scheduling low physical memory notification, " - "because not enough time has elapsed since last one."); - } - } - } -} - -LPVOID WINAPI -VirtualAllocHook(LPVOID aAddress, SIZE_T aSize, - DWORD aAllocationType, - DWORD aProtect) -{ - // It's tempting to see whether we have enough free virtual address space for - // this allocation and, if we don't, synchronously fire a low-memory - // notification to free some before we allocate. - // - // Unfortunately that doesn't work, principally because code doesn't expect a - // call to malloc could trigger a GC (or call into the other routines which - // are triggered by a low-memory notification). - // - // I think the best we can do here is try to allocate the memory and check - // 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 ((sLowVirtualMemoryThreshold != 0 && aAllocationType & MEM_RESERVE) || - (sLowPhysicalMemoryThreshold != 0 && aAllocationType & MEM_COMMIT)) { - LOG3("VirtualAllocHook(size=", aSize, ")"); - CheckMemAvailable(); - } - - return result; -} - -LPVOID WINAPI -MapViewOfFileHook(HANDLE aFileMappingObject, - DWORD aDesiredAccess, - DWORD aFileOffsetHigh, - DWORD aFileOffsetLow, - SIZE_T aNumBytesToMap) -{ - LPVOID result = sMapViewOfFileOrig(aFileMappingObject, aDesiredAccess, - aFileOffsetHigh, aFileOffsetLow, - aNumBytesToMap); - LOG("MapViewOfFileHook"); - CheckMemAvailable(); - return result; -} - -HBITMAP WINAPI -CreateDIBSectionHook(HDC aDC, - const BITMAPINFO *aBitmapInfo, - UINT aUsage, - VOID **aBits, - HANDLE aSection, - DWORD aOffset) -{ - // There are a lot of calls to CreateDIBSection, so we make some effort not - // to CheckMemAvailable() for calls to CreateDIBSection which allocate only - // a small amount of memory. - - // If aSection is non-null, CreateDIBSection won't allocate any new memory. - PRBool doCheck = PR_FALSE; - if (!aSection && aBitmapInfo) { - PRUint16 bitCount = aBitmapInfo->bmiHeader.biBitCount; - if (bitCount == 0) { - // MSDN says bitCount == 0 means that it figures out how many bits each - // pixel gets by examining the corresponding JPEG or PNG data. We'll just - // assume the worst. - bitCount = 32; - } - - // |size| contains the expected allocation size in *bits*. Height may be - // negative (indicating the direction the DIB is drawn in), so we take the - // absolute value. - PRInt64 size = bitCount * aBitmapInfo->bmiHeader.biWidth * - aBitmapInfo->bmiHeader.biHeight; - if (size < 0) - size *= -1; - - // If we're allocating more than 1MB, check how much virtual memory is left - // after the allocation. - if (size > 1024 * 1024 * 8) { - LOG3("CreateDIBSectionHook: Large allocation (size=", size, ")"); - doCheck = PR_TRUE; - } - } - - HBITMAP result = sCreateDIBSectionOrig(aDC, aBitmapInfo, aUsage, aBits, - aSection, aOffset); - - if (doCheck) { - CheckMemAvailable(); - } - - return result; -} - -void Init() -{ - Preferences::AddUintVarCache(&sLowVirtualMemoryThreshold, - "memory.low_virtual_mem_threshold_mb", 128); - Preferences::AddUintVarCache(&sLowPhysicalMemoryThreshold, - "memory.low_physical_mem_threshold_mb", 0); - Preferences::AddUintVarCache(&sLowPhysicalMemoryNotificationIntervalMS, - "memory.low_physical_memory_notification_interval_ms", 10000); - - // Don't register the hooks if we're a build instrumented for PGO or if both - // thresholds are 0. (If we're an instrumented build, the compiler adds - // function calls all over the place which may call VirtualAlloc; this makes - // it hard to prevent VirtualAllocHook from reentering itself.) - - if (!PR_GetEnv("MOZ_PGO_INSTRUMENTED") && - (sLowVirtualMemoryThreshold != 0 || sLowPhysicalMemoryThreshold != 0)) { - sKernel32Intercept.Init("Kernel32.dll"); - sKernel32Intercept.AddHook("VirtualAlloc", - reinterpret_cast<intptr_t>(VirtualAllocHook), - (void**) &sVirtualAllocOrig); - sKernel32Intercept.AddHook("MapViewOfFile", - reinterpret_cast<intptr_t>(MapViewOfFileHook), - (void**) &sMapViewOfFileOrig); - - sGdi32Intercept.Init("Gdi32.dll"); - sGdi32Intercept.AddHook("CreateDIBSection", - reinterpret_cast<intptr_t>(CreateDIBSectionHook), - (void**) &sCreateDIBSectionOrig); - } -} - -} // namespace AvailableMemoryTracker -} // namespace mozilla
deleted file mode 100644 --- a/xpcom/base/AvailableMemoryTracker.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 ci et: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla.org code. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Justin Lebar <justin.lebar@gmail.com> - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef mozilla_AvailableMemoryTracker_h -#define mozilla_AvailableMemoryTracker_h - -namespace mozilla { -namespace AvailableMemoryTracker { - -// The AvailableMemoryTracker is implemented only on Windows. But to make -// callers' lives easier, we stub out an empty Init() call. So you can always -// initialize the AvailableMemoryTracker; it just might not do anything. - -#if defined(XP_WIN) -void Init(); -#else -void Init() {} -#endif - -} // namespace AvailableMemoryTracker -} // namespace mozilla - -#endif // ifndef mozilla_AvailableMemoryTracker_h
--- a/xpcom/base/Makefile.in +++ b/xpcom/base/Makefile.in @@ -95,36 +95,29 @@ EXPORTS = \ dmd.h \ $(NULL) EXPORTS_NAMESPACES = mozilla EXPORTS_mozilla = \ FunctionTimer.h \ MapsMemoryReporter.h \ - AvailableMemoryTracker.h \ $(NULL) ifeq (windows,$(MOZ_WIDGET_TOOLKIT)) CPPSRCS += nsCrashOnException.cpp endif ifeq ($(OS_ARCH),WINNT) - ifdef MOZ_DEBUG CSRCS += pure_api.c EXPORTS += pure.h endif - -ifeq ($(CPU_ARCH),x86) -CPPSRCS += AvailableMemoryTracker.cpp endif -endif #if OS_ARCH == WINNT - SDK_XPIDLSRCS = \ nsIDebug.idl \ nsIInterfaceRequestor.idl \ nsIMemory.idl \ nsIProgrammingLanguage.idl \ nsISupports.idl \ nsITraceRefcnt.idl \ nsIWeakReference.idl \
--- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -147,17 +147,16 @@ extern nsresult nsStringInputStreamConst #include "mozilla/scache/StartupCache.h" #include "base/at_exit.h" #include "base/command_line.h" #include "base/message_loop.h" #include "mozilla/ipc/BrowserProcessSubThread.h" #include "mozilla/MapsMemoryReporter.h" -#include "mozilla/AvailableMemoryTracker.h" using base::AtExitManager; using mozilla::ipc::BrowserProcessSubThread; namespace { static AtExitManager* sExitManager; static MessageLoop* sMessageLoop; @@ -515,18 +514,16 @@ NS_InitXPCOM2(nsIServiceManager* *result NS_TIME_FUNCTION_MARK("Next: register category providers"); // After autoreg, but before we actually instantiate any components, // add any services listed in the "xpcom-directory-providers" category // to the directory service. nsDirectoryService::gService->RegisterCategoryProviders(); mozilla::scache::StartupCache::GetSingleton(); - mozilla::AvailableMemoryTracker::Init(); - NS_TIME_FUNCTION_MARK("Next: create services from category"); // Notify observers of xpcom autoregistration start NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY, nsnull, NS_XPCOM_STARTUP_OBSERVER_ID); #ifdef XP_WIN ScheduleMediaCacheRemover();
--- a/xpcom/threads/Makefile.in +++ b/xpcom/threads/Makefile.in @@ -59,17 +59,16 @@ CPPSRCS = \ nsThreadPool.cpp \ nsProcessCommon.cpp \ nsTimerImpl.cpp \ TimerThread.cpp \ HangMonitor.cpp \ $(NULL) EXPORTS = \ - nsThread.h \ nsProcess.h \ nsEventQueue.h \ nsThreadUtilsInternal.h \ $(NULL) EXPORTS_mozilla = \ HangMonitor.h \ $(NULL)
--- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -40,19 +40,17 @@ #include "nsThread.h" #include "nsThreadManager.h" #include "nsIClassInfoImpl.h" #include "nsIProgrammingLanguage.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "prlog.h" #include "nsThreadUtilsInternal.h" -#include "nsIObserverService.h" #include "mozilla/HangMonitor.h" -#include "mozilla/Services.h" #define HAVE_UALARM _BSD_SOURCE || (_XOPEN_SOURCE >= 500 || \ _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \ !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) #if defined(XP_UNIX) && !defined(ANDROID) && !defined(DEBUG) && HAVE_UALARM \ && defined(_GNU_SOURCE) # define MOZ_CANARY @@ -78,31 +76,16 @@ using namespace mozilla; static PRLogModuleInfo *sLog = PR_NewLogModule("nsThread"); #endif #define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args) NS_DECL_CI_INTERFACE_GETTER(nsThread) nsIThreadObserver* nsThread::sGlobalObserver; -namespace mozilla { - -static volatile bool sMemoryPressurePending = false; - -/* - * It's important that this function not acquire any locks, nor do anything - * which might cause malloc to run. - */ -void ScheduleMemoryPressureEvent() -{ - PR_ATOMIC_SET(&sMemoryPressurePending, true); -} - -}; - //----------------------------------------------------------------------------- // Because we do not have our own nsIFactory, we have to implement nsIClassInfo // somewhat manually. class nsThreadClassInfo : public nsIClassInfo { public: NS_DECL_ISUPPORTS_INHERITED // no mRefCnt NS_DECL_NSICLASSINFO @@ -589,32 +572,16 @@ nsThread::ProcessNextEvent(bool mayWait, { LOG(("THRD(%p) ProcessNextEvent [%u %u]\n", this, mayWait, mRunningEvent)); NS_ENSURE_STATE(PR_GetCurrentThread() == mThread); if (MAIN_THREAD == mIsMainThread && mayWait && !ShuttingDown()) HangMonitor::Suspend(); - // Fire a memory pressure notification, if we're the main thread and one is - // pending. - if (MAIN_THREAD == mIsMainThread && !ShuttingDown()) { - bool mpPending = PR_ATOMIC_SET(&sMemoryPressurePending, false); - if (mpPending) { - nsCOMPtr<nsIObserverService> os = services::GetObserverService(); - if (os) { - os->NotifyObservers(nsnull, "memory-pressure", - NS_LITERAL_STRING("low-memory").get()); - } - else { - NS_WARNING("Can't get observer service!"); - } - } - } - bool notifyGlobalObserver = (sGlobalObserver != nsnull); if (notifyGlobalObserver) sGlobalObserver->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent); nsCOMPtr<nsIThreadObserver> obs = mObserver; if (obs) obs->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent);
--- a/xpcom/threads/nsThread.h +++ b/xpcom/threads/nsThread.h @@ -173,21 +173,9 @@ public: private: NS_DECL_NSIRUNNABLE nsCOMPtr<nsIThread> mOrigin; nsCOMPtr<nsIRunnable> mSyncTask; nsresult mResult; }; -namespace mozilla { - -/** - * This function causes the main thread to fire a memory pressure event at its - * next available opportunity. - * - * You may call this function from any thread. - */ -void ScheduleMemoryPressureEvent(); - -} // namespace mozilla - #endif // nsThread_h__