void Init() { // On 64-bit systems, hardcode sLowVirtualMemoryThreshold to 0 -- we assume // we're not going to run out of virtual memory! if (sizeof(void*) > 4) { sLowVirtualMemoryThreshold = 0; } else { Preferences::AddUintVarCache(&sLowVirtualMemoryThreshold, "memory.low_virtual_mem_threshold_mb", 128); } Preferences::AddUintVarCache(&sLowPhysicalMemoryThreshold, "memory.low_physical_memory_threshold_mb", 0); Preferences::AddUintVarCache(&sLowCommitSpaceThreshold, "memory.low_commit_space_threshold_mb", 128); Preferences::AddUintVarCache(&sLowMemoryNotificationIntervalMS, "memory.low_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)) { sHooksInstalled = true; 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); } else { sHooksInstalled = false; } NS_RegisterMemoryReporter(new NumLowCommitSpaceEventsMemoryReporter()); NS_RegisterMemoryReporter(new NumLowPhysicalMemoryEventsMemoryReporter()); if (sizeof(void*) == 4) { NS_RegisterMemoryReporter(new NumLowVirtualMemoryEventsMemoryReporter()); } }
GrallocBufferActor::GrallocBufferActor() : mAllocBytes(0) { static bool registered; if (!registered) { // We want to be sure that the first call here will always run on // the main thread. NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(GrallocBufferActor)); registered = true; } }
void gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType, PRInt32 aBytes) { if (aType < 0 || aType >= SurfaceTypeMax) { NS_WARNING("Invalid type to RecordMemoryUsedForSurfaceType!"); return; } if (gSurfaceMemoryReporters[aType] == 0) { gSurfaceMemoryReporters[aType] = new SurfaceMemoryReporter(aType); NS_RegisterMemoryReporter(gSurfaceMemoryReporters[aType]); } gSurfaceMemoryUsed[aType] += aBytes; }
nsresult mozHunspell::Init() { mDictionaries.Init(); LoadDictionaryList(); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(this, "profile-do-change", true); obs->AddObserver(this, "profile-after-change", true); } mHunspellReporter = new NS_MEMORY_REPORTER_NAME(Hunspell); NS_RegisterMemoryReporter(mHunspellReporter); return NS_OK; }
nsLayoutStylesheetCache::nsLayoutStylesheetCache() { nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService(); NS_ASSERTION(obsSvc, "No global observer service?"); if (obsSvc) { obsSvc->AddObserver(this, "profile-before-change", false); obsSvc->AddObserver(this, "profile-do-change", false); obsSvc->AddObserver(this, "chrome-flush-skin-caches", false); obsSvc->AddObserver(this, "chrome-flush-caches", false); } InitFromProfile(); // And make sure that we load our UA sheets. No need to do this // per-profile, since they're profile-invariant. nsCOMPtr<nsIURI> uri; NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/ua.css"); if (uri) { LoadSheet(uri, mUASheet, true); } NS_ASSERTION(mUASheet, "Could not load ua.css"); NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/quirk.css"); if (uri) { LoadSheet(uri, mQuirkSheet, true); } NS_ASSERTION(mQuirkSheet, "Could not load quirk.css"); NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/full-screen-override.css"); if (uri) { LoadSheet(uri, mFullScreenOverrideSheet, true); } NS_ASSERTION(mFullScreenOverrideSheet, "Could not load full-screen-override.css"); mReporter = new LayoutStyleSheetCacheReporter(); NS_RegisterMemoryReporter(mReporter); }
nsresult StartupCache::Init() { // workaround for bug 653936 nsCOMPtr<nsIProtocolHandler> jarInitializer(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar")); nsresult rv; mTable.Init(); #ifdef DEBUG mWriteObjectMap.Init(); #endif // This allows to override the startup cache filename // which is useful from xpcshell, when there is no ProfLDS directory to keep cache in. char *env = PR_GetEnv("MOZ_STARTUP_CACHE"); if (env) { rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(env), false, getter_AddRefs(mFile)); } else { nsCOMPtr<nsIFile> file; rv = NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(file)); if (NS_FAILED(rv)) { // return silently, this will fail in mochitests's xpcshell process. return rv; } nsCOMPtr<nsIFile> profDir; NS_GetSpecialDirectory("ProfDS", getter_AddRefs(profDir)); if (profDir) { bool same; if (NS_SUCCEEDED(profDir->Equals(file, &same)) && !same) { // We no longer store the startup cache in the main profile // directory, so we should cleanup the old one. if (NS_SUCCEEDED( profDir->AppendNative(NS_LITERAL_CSTRING("startupCache")))) { profDir->Remove(true); } } } rv = file->AppendNative(NS_LITERAL_CSTRING("startupCache")); NS_ENSURE_SUCCESS(rv, rv); // Try to create the directory if it's not there yet rv = file->Create(nsIFile::DIRECTORY_TYPE, 0777); if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) return rv; rv = file->AppendNative(NS_LITERAL_CSTRING(sStartupCacheName)); NS_ENSURE_SUCCESS(rv, rv); mFile = do_QueryInterface(file); } NS_ENSURE_TRUE(mFile, NS_ERROR_UNEXPECTED); mObserverService = do_GetService("@mozilla.org/observer-service;1"); if (!mObserverService) { NS_WARNING("Could not get observerService."); return NS_ERROR_UNEXPECTED; } mListener = new StartupCacheListener(); rv = mObserverService->AddObserver(mListener, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); NS_ENSURE_SUCCESS(rv, rv); rv = mObserverService->AddObserver(mListener, "startupcache-invalidate", false); NS_ENSURE_SUCCESS(rv, rv); rv = LoadArchive(RECORD_AGE); // Sometimes we don't have a cache yet, that's ok. // If it's corrupted, just remove it and start over. if (gIgnoreDiskCache || (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)) { NS_WARNING("Failed to load startupcache file correctly, removing!"); InvalidateCache(); } mMappingReporter = new StartupCacheMappingReporter(); mDataReporter = new StartupCacheDataReporter(); NS_RegisterMemoryReporter(mMappingReporter); NS_RegisterMemoryReporter(mDataReporter); return NS_OK; }
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) : mXPConnect(aXPConnect), mJSRuntime(nsnull), mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)), mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)), mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)), mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_SIZE)), mNativeSetMap(NativeSetMap::newMap(XPC_NATIVE_SET_MAP_SIZE)), mThisTranslatorMap(IID2ThisTranslatorMap::newMap(XPC_THIS_TRANSLATOR_MAP_SIZE)), mNativeScriptableSharedMap(XPCNativeScriptableSharedMap::newMap(XPC_NATIVE_JSCLASS_MAP_SIZE)), mDyingWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DYING_NATIVE_PROTO_MAP_SIZE)), mDetachedWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DETACHED_NATIVE_PROTO_MAP_SIZE)), mExplicitNativeWrapperMap(XPCNativeWrapperMap::newMap(XPC_NATIVE_WRAPPER_MAP_SIZE)), mMapLock(XPCAutoLock::NewLock("XPCJSRuntime::mMapLock")), mThreadRunningGC(nsnull), mWrappedJSToReleaseArray(), mNativesToReleaseArray(), mDoingFinalization(JS_FALSE), mVariantRoots(nsnull), mWrappedJSRoots(nsnull), mObjectHolderRoots(nsnull), mUnrootedGlobalCount(0), mWatchdogWakeup(nsnull), mWatchdogThread(nsnull) { #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN DEBUG_WrappedNativeHashtable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull, sizeof(JSDHashEntryStub), 128); #endif NS_TIME_FUNCTION; DOM_InitInterfaces(); // these jsids filled in later when we have a JSContext to work with. mStrIDs[0] = 0; mJSRuntime = JS_NewRuntime(32L * 1024L * 1024L); // pref ? if(mJSRuntime) { // Unconstrain the runtime's threshold on nominal heap size, to avoid // triggering GC too often if operating continuously near an arbitrary // finite threshold (0xffffffff is infinity for uint32 parameters). // This leaves the maximum-JS_malloc-bytes threshold still in effect // to cause period, and we hope hygienic, last-ditch GCs from within // the GC's allocator. JS_SetGCParameter(mJSRuntime, JSGC_MAX_BYTES, 0xffffffff); JS_SetContextCallback(mJSRuntime, ContextCallback); JS_SetGCCallbackRT(mJSRuntime, GCCallback); JS_SetExtraGCRoots(mJSRuntime, TraceJS, this); mWatchdogWakeup = JS_NEW_CONDVAR(mJSRuntime->gcLock); mJSRuntime->setCustomGCChunkAllocator(&gXPCJSChunkAllocator); NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(XPConnectJSRuntimeGCChunks)); } if(!JS_DHashTableInit(&mJSHolders, JS_DHashGetStubOps(), nsnull, sizeof(ObjectHolder), 512)) mJSHolders.ops = nsnull; // Install a JavaScript 'debugger' keyword handler in debug builds only #ifdef DEBUG if(mJSRuntime && !JS_GetGlobalDebugHooks(mJSRuntime)->debuggerHandler) xpc_InstallJSDebuggerKeywordHandler(mJSRuntime); #endif if (mWatchdogWakeup) { AutoLockJSGC lock(mJSRuntime); mWatchdogThread = PR_CreateThread(PR_USER_THREAD, WatchdogMain, this, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); } }
/* static */ void nsDOMMemoryReporter::Init() { // The memory reporter manager is going to own this object. NS_RegisterMemoryReporter(new nsDOMMemoryReporter()); }