From d43e6f58e1585d3cfab327b086282c86d1e25dfa Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 30 Aug 2021 09:33:31 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - pointer style (8365db72a) - remove stackDepth check not found anywhere in official gecko (98f65d05e) - Bug 1134198 - Call Debugger::onPop at the point that caused the frame to pop before any unwinding in the JIT. (r=jandem) (5aea98ae6) - Bug 1189750 - Remove unused JM-related PCCounts counters. r=bhackett (7410480af) - Bug 1198245 - IonMonkey: Lock helperthread before finishing ionbuilder, r=jandem (0f28ef66a) - Bug 1188620 - Use PersistentRooted for asyncActivation roots; r=fitzgen (4f6ae0e92) - Bug 1190446 - Update Coverage information in Baseline. r=jandem (95935926e) - Bug 1188129 - Use a universal constructor to create and init PersistentRooted; r=jonco (75db7ea8f) - Bug 1187767 - Ensure PLDHashTable's generation is always updated when the entry store is modified. r=froydnj. (e49936dad) - Bug 1189156 (part 1) - Don't use enumeration style for PLDHashTable::SizeOf{In,Ex}cludingThis(). r=froydnj. (3152ab914) - Bug 1189156 (part 2) - Don't use enumeration style for nsTHashtable::SizeOf{In,Ex}cludingThis(). r=erahm. (de21442b7) - Bug 1189156 (part 3) - Factor out FontTable better. r=jfkthame. (afdee9bd7) - Bug 1189156 (part 4) - Don't use enumeration style for nsBaseHashtable::SizeOf{In,Ex}cludingThis(). r=erahm,jfkthame. (32d72520f) - Bug 1189156 (part 5) - Add FontEntryTable typedef and factor out some related code. r=jfkthame. (9983134a9) - Bug 1137437 - move security/apps/ cert header generation to moz.build; r=mshal,keeler (2f7abb37d) - Bug 1180993 - Part 3: Correct use sites of functions which return already_AddRefed. r=ehsan (2a6289b6a) --- dom/base/ImageEncoder.cpp | 3 +- dom/base/nsContentUtils.cpp | 4 +- dom/base/nsDOMAttributeMap.cpp | 16 +- dom/base/nsDocument.cpp | 2 +- dom/base/nsGlobalWindow.cpp | 6 +- dom/base/nsPropertyTable.cpp | 2 +- dom/base/nsScriptNameSpaceManager.cpp | 28 +- dom/base/nsScriptNameSpaceManager.h | 2 +- dom/ipc/TabParent.cpp | 2 +- dom/media/MediaCache.cpp | 3 +- dom/media/webaudio/AudioContext.cpp | 4 +- dom/storage/DOMStorageDBThread.cpp | 3 +- gfx/thebes/gfxDWriteFontList.cpp | 3 +- gfx/thebes/gfxDWriteFontList.h | 4 +- gfx/thebes/gfxDWriteFonts.cpp | 2 +- gfx/thebes/gfxFT2FontList.h | 2 +- gfx/thebes/gfxFT2Fonts.cpp | 2 +- gfx/thebes/gfxFont.cpp | 22 +- gfx/thebes/gfxFont.h | 4 - gfx/thebes/gfxGDIFont.cpp | 2 +- gfx/thebes/gfxGDIFontList.cpp | 3 +- gfx/thebes/gfxGDIFontList.h | 4 +- gfx/thebes/gfxGlyphExtents.cpp | 2 +- gfx/thebes/gfxPlatformFontList.cpp | 120 +++--- gfx/thebes/gfxPlatformFontList.h | 25 +- js/public/RootingAPI.h | 82 ++-- js/src/gc/RootMarking.cpp | 6 - js/src/jit/BaselineCompiler.cpp | 21 + js/src/jit/BaselineCompiler.h | 1 + js/src/jit/Ion.cpp | 33 +- js/src/jit/JitFrames.cpp | 382 +++++++++--------- js/src/jit/VMFunctions.cpp | 13 +- js/src/jsopcode.cpp | 162 +------- js/src/jsopcode.h | 119 +----- js/src/jsscript.cpp | 29 +- js/src/vm/Interpreter.cpp | 2 +- js/src/vm/Runtime.cpp | 4 +- js/src/vm/Runtime.h | 4 +- js/xpconnect/loader/mozJSComponentLoader.cpp | 38 +- js/xpconnect/src/XPCMaps.cpp | 79 ++-- js/xpconnect/src/XPCMaps.h | 16 +- layout/base/nsPresShell.cpp | 8 +- layout/style/CSSVariableDeclarations.cpp | 18 +- layout/style/Loader.cpp | 40 +- layout/style/nsCSSRuleProcessor.cpp | 83 ++-- layout/style/nsHTMLCSSStyleSheet.cpp | 23 +- layout/style/nsHTMLStyleSheet.cpp | 20 +- modules/libpref/Preferences.cpp | 21 +- netwerk/cache2/CacheFile.cpp | 26 +- netwerk/cache2/CacheIndex.cpp | 4 +- netwerk/cache2/CacheStorageService.cpp | 42 +- netwerk/dns/nsEffectiveTLDService.cpp | 2 +- netwerk/dns/nsHostResolver.cpp | 16 +- security/apps/Makefile.in | 48 --- security/apps/gen_cert_header.py | 61 +-- security/apps/moz.build | 19 + security/apps/trusted-app-public.der | 0 startupcache/StartupCache.cpp | 21 +- startupcache/StartupCache.h | 11 +- toolkit/components/telemetry/Telemetry.cpp | 21 +- widget/gtk/nsSound.cpp | 3 +- xpcom/base/CycleCollectedJSRuntime.cpp | 6 +- xpcom/components/nsCategoryManager.cpp | 20 +- xpcom/components/nsComponentManager.cpp | 42 +- xpcom/components/nsComponentManager.h | 2 +- xpcom/ds/nsAtomTable.cpp | 26 +- xpcom/glue/DeadlockDetector.h | 15 +- xpcom/glue/nsBaseHashtable.h | 86 +--- xpcom/glue/nsTHashtable.h | 118 ++---- xpcom/glue/pldhash.cpp | 109 ++--- xpcom/glue/pldhash.h | 80 ++-- .../xptinfo/xptiInterfaceInfoManager.cpp | 4 +- xpcom/tests/gtest/TestPLDHash.cpp | 5 +- 73 files changed, 829 insertions(+), 1432 deletions(-) delete mode 100644 security/apps/Makefile.in create mode 100644 security/apps/trusted-app-public.der diff --git a/dom/base/ImageEncoder.cpp b/dom/base/ImageEncoder.cpp index ba2d192b14..11e2ae9d14 100644 --- a/dom/base/ImageEncoder.cpp +++ b/dom/base/ImageEncoder.cpp @@ -10,6 +10,7 @@ #include "mozilla/gfx/DataSurfaceHelpers.h" #include "mozilla/RefPtr.h" #include "mozilla/SyncRunnable.h" +#include "mozilla/unused.h" #include "gfxUtils.h" #include "nsNetUtil.h" @@ -206,7 +207,7 @@ public: rv = NS_DispatchToMainThread(mEncodingCompleteEvent); if (NS_FAILED(rv)) { // Better to leak than to crash. - mEncodingCompleteEvent.forget(); + unused << mEncodingCompleteEvent.forget(); return rv; } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index bda26ad162..967c4d5b9c 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -364,8 +364,8 @@ public: // We don't measure the |EventListenerManager| objects pointed to by the // entries because those references are non-owning. int64_t amount = sEventListenerManagersHash - ? PL_DHashTableSizeOfExcludingThis( - sEventListenerManagersHash, nullptr, MallocSizeOf) + ? sEventListenerManagersHash->ShallowSizeOfIncludingThis( + MallocSizeOf) : 0; return MOZ_COLLECT_REPORT( diff --git a/dom/base/nsDOMAttributeMap.cpp b/dom/base/nsDOMAttributeMap.cpp index 1022aabdc6..344db49c6c 100644 --- a/dom/base/nsDOMAttributeMap.cpp +++ b/dom/base/nsDOMAttributeMap.cpp @@ -546,21 +546,15 @@ nsDOMAttributeMap::Enumerate(AttrCache::EnumReadFunction aFunc, return mAttributeCache.EnumerateRead(aFunc, aUserArg); } -size_t -AttrCacheSizeEnumerator(const nsAttrKey& aKey, - const nsRefPtr& aValue, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - return aMallocSizeOf(aValue.get()); -} - size_t nsDOMAttributeMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += mAttributeCache.SizeOfExcludingThis(AttrCacheSizeEnumerator, - aMallocSizeOf); + + n += mAttributeCache.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mAttributeCache.ConstIter(); !iter.Done(); iter.Next()) { + n += aMallocSizeOf(iter.Data().get()); + } // NB: mContent is non-owning and thus not counted. return n; diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index ebd14e4fc1..2de4357970 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -12819,7 +12819,7 @@ nsDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const 0; aWindowSizes->mDOMOtherSize += - mStyledLinks.SizeOfExcludingThis(nullptr, aWindowSizes->mMallocSizeOf); + mStyledLinks.ShallowSizeOfExcludingThis(aWindowSizes->mMallocSizeOf); aWindowSizes->mDOMOtherSize += mIdentifierMap.SizeOfExcludingThis(aWindowSizes->mMallocSizeOf); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 795b747118..5df2dd30ef 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -13369,12 +13369,8 @@ nsGlobalWindow::AddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const mNavigator->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf); } - // The things pointed to by the entries will be measured below, so we - // use nullptr for the callback here. aWindowSizes->mDOMEventTargetsSize += - mEventTargetObjects.SizeOfExcludingThis(nullptr, - aWindowSizes->mMallocSizeOf); - + mEventTargetObjects.ShallowSizeOfExcludingThis(aWindowSizes->mMallocSizeOf); for (auto iter = mEventTargetObjects.ConstIter(); !iter.Done(); iter.Next()) { DOMEventTargetHelper* et = iter.Get()->GetKey(); diff --git a/dom/base/nsPropertyTable.cpp b/dom/base/nsPropertyTable.cpp index 9f6c893d52..09552437f1 100644 --- a/dom/base/nsPropertyTable.cpp +++ b/dom/base/nsPropertyTable.cpp @@ -310,7 +310,7 @@ size_t nsPropertyTable::PropertyList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) { size_t n = aMallocSizeOf(this); - n += PL_DHashTableSizeOfExcludingThis(&mObjectValueMap, nullptr, aMallocSizeOf); + n += mObjectValueMap.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index 9316405ad7..32f3d20cde 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -717,14 +717,6 @@ nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor( } } -static size_t -SizeOfEntryExcludingThis(PLDHashEntryHdr *aHdr, MallocSizeOf aMallocSizeOf, - void *aArg) -{ - GlobalNameMapEntry* entry = static_cast(aHdr); - return entry->SizeOfExcludingThis(aMallocSizeOf); -} - MOZ_DEFINE_MALLOC_SIZE_OF(ScriptNameSpaceManagerMallocSizeOf) NS_IMETHODIMP @@ -738,12 +730,22 @@ nsScriptNameSpaceManager::CollectReports( } size_t -nsScriptNameSpaceManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) +nsScriptNameSpaceManager::SizeOfIncludingThis( + mozilla::MallocSizeOf aMallocSizeOf) const { size_t n = 0; - n += PL_DHashTableSizeOfExcludingThis(&mGlobalNames, - SizeOfEntryExcludingThis, aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mNavigatorNames, - SizeOfEntryExcludingThis, aMallocSizeOf); + + n += mGlobalNames.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mGlobalNames.ConstIter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->SizeOfExcludingThis(aMallocSizeOf); + } + + n += mNavigatorNames.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mNavigatorNames.ConstIter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->SizeOfExcludingThis(aMallocSizeOf); + } + return n; } diff --git a/dom/base/nsScriptNameSpaceManager.h b/dom/base/nsScriptNameSpaceManager.h index 1ea46b2669..84e10b9bb3 100644 --- a/dom/base/nsScriptNameSpaceManager.h +++ b/dom/base/nsScriptNameSpaceManager.h @@ -206,7 +206,7 @@ public: NameIterator GlobalNameIter() { return NameIterator(&mGlobalNames); } NameIterator NavigatorNameIter() { return NameIterator(&mNavigatorNames); } - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; private: virtual ~nsScriptNameSpaceManager(); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 42a5c789c1..902a2663b3 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -225,7 +225,7 @@ private: // Intentionally leak the runnable (but not the fd) rather // than crash when trying to release a main thread object // off the main thread. - mTabParent.forget(); + mozilla::unused << mTabParent.forget(); CloseFile(); } } diff --git a/dom/media/MediaCache.cpp b/dom/media/MediaCache.cpp index 9cb684b3bd..083da3f807 100644 --- a/dom/media/MediaCache.cpp +++ b/dom/media/MediaCache.cpp @@ -403,8 +403,7 @@ size_t MediaCacheStream::SizeOfExcludingThis( size_t MediaCacheStream::BlockList::SizeOfExcludingThis( MallocSizeOf aMallocSizeOf) const { - return mEntries.SizeOfExcludingThis(/* sizeOfEntryExcludingThis = */ nullptr, - aMallocSizeOf); + return mEntries.ShallowSizeOfExcludingThis(aMallocSizeOf); } void MediaCacheStream::BlockList::AddFirstBlock(int32_t aBlock) diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp index 6f285cf908..9bc6b4d6a4 100644 --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -1034,8 +1034,8 @@ AudioContext::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const for (uint32_t i = 0; i < mDecodeJobs.Length(); ++i) { amount += mDecodeJobs[i]->SizeOfIncludingThis(aMallocSizeOf); } - amount += mActiveNodes.SizeOfExcludingThis(nullptr, aMallocSizeOf); - amount += mPannerNodes.SizeOfExcludingThis(nullptr, aMallocSizeOf); + amount += mActiveNodes.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += mPannerNodes.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/storage/DOMStorageDBThread.cpp b/dom/storage/DOMStorageDBThread.cpp index ca95a1e010..7e02658c70 100644 --- a/dom/storage/DOMStorageDBThread.cpp +++ b/dom/storage/DOMStorageDBThread.cpp @@ -421,8 +421,7 @@ nsReverseStringSQLFunction::OnFunctionCall( rv = outVar->SetAsAUTF8String(result); NS_ENSURE_SUCCESS(rv, rv); - *aResult = outVar.get(); - outVar.forget(); + outVar.forget(aResult); return NS_OK; } diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 70fb1b715b..c91d7cdb9b 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -1341,8 +1341,7 @@ gfxDWriteFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, gfxPlatformFontList::AddSizeOfExcludingThis(aMallocSizeOf, aSizes); aSizes->mFontListSize += - mFontSubstitutes.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis, - aMallocSizeOf); + SizeOfFontFamilyTableExcludingThis(mFontSubstitutes, aMallocSizeOf); aSizes->mFontListSize += mNonExistingFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h index 5b183b39f5..8414d0c794 100644 --- a/gfx/thebes/gfxDWriteFontList.h +++ b/gfx/thebes/gfxDWriteFontList.h @@ -406,13 +406,11 @@ private: */ nsTArray mNonExistingFonts; - typedef nsRefPtrHashtable FontTable; - /** * Table of font substitutes, we grab this from the registry to get * alternative font names. */ - FontTable mFontSubstitutes; + FontFamilyTable mFontSubstitutes; bool mInitialized; virtual nsresult DelayedInitFontList(); diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index 2c7bc0f2a7..04e67b66fb 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -657,7 +657,7 @@ gfxDWriteFont::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, aSizes->mFontInstances += aMallocSizeOf(mMetrics); if (mGlyphWidths) { aSizes->mFontInstances += - mGlyphWidths->SizeOfIncludingThis(nullptr, aMallocSizeOf); + mGlyphWidths->ShallowSizeOfIncludingThis(aMallocSizeOf); } } diff --git a/gfx/thebes/gfxFT2FontList.h b/gfx/thebes/gfxFT2FontList.h index 3d7fdce978..adb10ebba5 100644 --- a/gfx/thebes/gfxFT2FontList.h +++ b/gfx/thebes/gfxFT2FontList.h @@ -185,7 +185,7 @@ protected: nsTHashtable mSkipSpaceLookupCheckFamilies; private: - nsRefPtrHashtable mHiddenFontFamilies; + FontFamilyTable mHiddenFontFamilies; }; #endif /* GFX_FT2FONTLIST_H */ diff --git a/gfx/thebes/gfxFT2Fonts.cpp b/gfx/thebes/gfxFT2Fonts.cpp index 0141b1505d..7339eb9ebb 100644 --- a/gfx/thebes/gfxFT2Fonts.cpp +++ b/gfx/thebes/gfxFT2Fonts.cpp @@ -218,7 +218,7 @@ gfxFT2Font::AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, { gfxFont::AddSizeOfExcludingThis(aMallocSizeOf, aSizes); aSizes->mFontInstances += - mCharGlyphCache.SizeOfExcludingThis(nullptr, aMallocSizeOf); + mCharGlyphCache.ShallowSizeOfExcludingThis(aMallocSizeOf); } void diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 3e2305f2f1..0e1c72d025 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -312,30 +312,16 @@ gfxFontCache::FlushShapedWordCaches() } } -/*static*/ -size_t -gfxFontCache::AddSizeOfFontEntryExcludingThis(HashEntry* aHashEntry, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - HashEntry *entry = static_cast(aHashEntry); - FontCacheSizes *sizes = static_cast(aUserArg); - entry->mFont->AddSizeOfExcludingThis(aMallocSizeOf, sizes); - - // The entry's size is recorded in the |sizes| parameter, so we return zero - // here to the hashtable enumerator. - return 0; -} - void gfxFontCache::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, FontCacheSizes* aSizes) const { // TODO: add the overhead of the expiration tracker (generation arrays) - aSizes->mFontInstances += - mFonts.SizeOfExcludingThis(AddSizeOfFontEntryExcludingThis, - aMallocSizeOf, aSizes); + aSizes->mFontInstances += mFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mFonts.ConstIter(); !iter.Done(); iter.Next()) { + iter.Get()->mFont->AddSizeOfExcludingThis(aMallocSizeOf, aSizes); + } } void diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 7906740b99..e578d412f1 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -387,10 +387,6 @@ protected: gfxFont* mFont; }; - static size_t AddSizeOfFontEntryExcludingThis(HashEntry* aHashEntry, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg); - nsTHashtable mFonts; static void WordCacheExpirationTimerCallback(nsITimer* aTimer, void* aCache); diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp index 3e5850788d..6e6e708290 100644 --- a/gfx/thebes/gfxGDIFont.cpp +++ b/gfx/thebes/gfxGDIFont.cpp @@ -503,7 +503,7 @@ gfxGDIFont::AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, aSizes->mFontInstances += aMallocSizeOf(mMetrics); if (mGlyphWidths) { aSizes->mFontInstances += - mGlyphWidths->SizeOfIncludingThis(nullptr, aMallocSizeOf); + mGlyphWidths->ShallowSizeOfIncludingThis(aMallocSizeOf); } } diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index 7370012f3d..b992099d62 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -943,8 +943,7 @@ gfxGDIFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, { gfxPlatformFontList::AddSizeOfExcludingThis(aMallocSizeOf, aSizes); aSizes->mFontListSize += - mFontSubstitutes.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis, - aMallocSizeOf); + SizeOfFontFamilyTableExcludingThis(mFontSubstitutes, aMallocSizeOf); aSizes->mFontListSize += mNonExistingFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mNonExistingFonts.Length(); ++i) { diff --git a/gfx/thebes/gfxGDIFontList.h b/gfx/thebes/gfxGDIFontList.h index bb6fe30b15..0a588deb7e 100644 --- a/gfx/thebes/gfxGDIFontList.h +++ b/gfx/thebes/gfxGDIFontList.h @@ -348,9 +348,7 @@ private: void ActivateBundledFonts(); #endif - typedef nsRefPtrHashtable FontTable; - - FontTable mFontSubstitutes; + FontFamilyTable mFontSubstitutes; nsTArray mNonExistingFonts; }; diff --git a/gfx/thebes/gfxGlyphExtents.cpp b/gfx/thebes/gfxGlyphExtents.cpp index 87202aaf6b..16e66353ee 100644 --- a/gfx/thebes/gfxGlyphExtents.cpp +++ b/gfx/thebes/gfxGlyphExtents.cpp @@ -143,7 +143,7 @@ size_t gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) + - mTightGlyphExtents.SizeOfExcludingThis(nullptr, aMallocSizeOf); + mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf); } size_t diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 2f4890c0b2..9f5c901b51 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -1038,72 +1038,34 @@ gfxPlatformFontList::RebuildLocalFonts() // Support for memory reporting -static size_t -SizeOfFamilyEntryExcludingThis(const nsAString& aKey, - const nsRefPtr& aFamily, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - FontListSizes *sizes = static_cast(aUserArg); - aFamily->AddSizeOfExcludingThis(aMallocSizeOf, sizes); - - sizes->mFontListSize += aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); - - // we return zero here because the measurements have been added directly - // to the relevant fields of the FontListSizes record - return 0; -} - -// this is also used by subclasses that hold additional hashes of family names +// this is also used by subclasses that hold additional font tables /*static*/ size_t -gfxPlatformFontList::SizeOfFamilyNameEntryExcludingThis - (const nsAString& aKey, - const nsRefPtr& aFamily, - MallocSizeOf aMallocSizeOf, - void* aUserArg) +gfxPlatformFontList::SizeOfFontFamilyTableExcludingThis( + const FontFamilyTable& aTable, + MallocSizeOf aMallocSizeOf) { - // we don't count the size of the family here, because this is an *extra* - // reference to a family that will have already been counted in the main list - return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) { + // We don't count the size of the family here, because this is an + // *extra* reference to a family that will have already been counted in + // the main list. + n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } + return n; } -static size_t -SizeOfFontNameEntryExcludingThis(const nsAString& aKey, - const nsRefPtr& aFont, - MallocSizeOf aMallocSizeOf, - void* aUserArg) +/*static*/ size_t +gfxPlatformFontList::SizeOfFontEntryTableExcludingThis( + const FontEntryTable& aTable, + MallocSizeOf aMallocSizeOf) { - // the font itself is counted by its owning family; here we only care about - // the name stored in the hashtable key - return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); -} - -static size_t -SizeOfPrefFontEntryExcludingThis - (const uint32_t& aKey, - const nsTArray >& aList, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - // again, we only care about the size of the array itself; we don't follow - // the refPtrs stored in it, because they point to entries already owned - // and accounted-for by the main font list - return aList.ShallowSizeOfExcludingThis(aMallocSizeOf); -} - -static size_t -SizeOfSharedCmapExcludingThis(CharMapHashKey* aHashEntry, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - FontListSizes *sizes = static_cast(aUserArg); - - uint32_t size = aHashEntry->GetKey()->SizeOfIncludingThis(aMallocSizeOf); - sizes->mCharMapsSize += size; - - // we return zero here because the measurements have been added directly - // to the relevant fields of the FontListSizes record - return 0; + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) { + // The font itself is counted by its owning family; here we only care + // about the names stored in the hashtable keys. + n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } + return n; } void @@ -1111,20 +1073,23 @@ gfxPlatformFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const { aSizes->mFontListSize += - mFontFamilies.SizeOfExcludingThis(SizeOfFamilyEntryExcludingThis, - aMallocSizeOf, aSizes); + mFontFamilies.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mFontFamilies.ConstIter(); !iter.Done(); iter.Next()) { + aSizes->mFontListSize += + iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + iter.Data()->AddSizeOfIncludingThis(aMallocSizeOf, aSizes); + } aSizes->mFontListSize += - mOtherFamilyNames.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis, - aMallocSizeOf); + SizeOfFontFamilyTableExcludingThis(mOtherFamilyNames, aMallocSizeOf); if (mExtraNames) { aSizes->mFontListSize += - mExtraNames->mFullnames.SizeOfExcludingThis(SizeOfFontNameEntryExcludingThis, - aMallocSizeOf); + SizeOfFontEntryTableExcludingThis(mExtraNames->mFullnames, + aMallocSizeOf); aSizes->mFontListSize += - mExtraNames->mPostscriptNames.SizeOfExcludingThis(SizeOfFontNameEntryExcludingThis, - aMallocSizeOf); + SizeOfFontEntryTableExcludingThis(mExtraNames->mPostscriptNames, + aMallocSizeOf); } aSizes->mFontListSize += @@ -1133,15 +1098,24 @@ gfxPlatformFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, mFontFamiliesToLoad.ShallowSizeOfExcludingThis(aMallocSizeOf); aSizes->mFontListSize += - mPrefFonts.SizeOfExcludingThis(SizeOfPrefFontEntryExcludingThis, - aMallocSizeOf); + mPrefFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mPrefFonts.ConstIter(); !iter.Done(); iter.Next()) { + // Again, we only care about the size of the array itself; we don't + // follow the refPtrs stored in it, because they point to entries + // already owned and accounted-for by the main font list. + aSizes->mFontListSize += + iter.Data().ShallowSizeOfExcludingThis(aMallocSizeOf); + } aSizes->mFontListSize += mBadUnderlineFamilyNames.SizeOfExcludingThis(aMallocSizeOf); aSizes->mFontListSize += - mSharedCmaps.SizeOfExcludingThis(SizeOfSharedCmapExcludingThis, - aMallocSizeOf, aSizes); + mSharedCmaps.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mSharedCmaps.ConstIter(); !iter.Done(); iter.Next()) { + aSizes->mCharMapsSize += + iter.Get()->GetKey()->SizeOfIncludingThis(aMallocSizeOf); + } } void diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 65d0671417..62f888c5a5 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -296,24 +296,28 @@ protected: void RebuildLocalFonts(); - // used by memory reporter to accumulate sizes of family names in the hash + typedef nsRefPtrHashtable FontFamilyTable; + typedef nsRefPtrHashtable FontEntryTable; + + // used by memory reporter to accumulate sizes of family names in the table static size_t - SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey, - const nsRefPtr& aFamily, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg); + SizeOfFontFamilyTableExcludingThis(const FontFamilyTable& aTable, + mozilla::MallocSizeOf aMallocSizeOf); + static size_t + SizeOfFontEntryTableExcludingThis(const FontEntryTable& aTable, + mozilla::MallocSizeOf aMallocSizeOf); // canonical family name ==> family entry (unique, one name per family entry) - nsRefPtrHashtable mFontFamilies; + FontFamilyTable mFontFamilies; #if defined(XP_MACOSX) // hidden system fonts used within UI elements - nsRefPtrHashtable mSystemFontFamilies; + FontFamilyTable mSystemFontFamilies; #endif // other family name ==> family entry (not unique, can have multiple names per // family entry, only names *other* than the canonical names are stored here) - nsRefPtrHashtable mOtherFamilyNames; + FontFamilyTable mOtherFamilyNames; // flag set after InitOtherFamilyNames is called upon first name lookup miss bool mOtherFamilyNamesInitialized; @@ -323,10 +327,11 @@ protected: struct ExtraNames { ExtraNames() : mFullnames(64), mPostscriptNames(64) {} + // fullname ==> font entry (unique, one name per font entry) - nsRefPtrHashtable mFullnames; + FontEntryTable mFullnames; // Postscript name ==> font entry (unique, one name per font entry) - nsRefPtrHashtable mPostscriptNames; + FontEntryTable mPostscriptNames; }; nsAutoPtr mExtraNames; diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 63a83fa313..d774717a26 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -626,6 +626,30 @@ struct GCMethods } }; +inline RootLists& +RootListsForRootingContext(JSContext* cx) +{ + return ContextFriendFields::get(cx)->roots; +} + +inline RootLists& +RootListsForRootingContext(js::ContextFriendFields* cx) +{ + return cx->roots; +} + +inline RootLists& +RootListsForRootingContext(JSRuntime* rt) +{ + return PerThreadDataFriendFields::getMainThread(rt)->roots; +} + +inline RootLists& +RootListsForRootingContext(js::PerThreadDataFriendFields* pt) +{ + return pt->roots; +} + } /* namespace js */ namespace JS { @@ -717,19 +741,6 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase *stack = reinterpret_cast*>(this); } - static js::RootLists& rootListsForRootingContext(JSContext* cx) { - return js::ContextFriendFields::get(cx)->roots; - } - static js::RootLists& rootListsForRootingContext(js::ContextFriendFields* cx) { - return cx->roots; - } - static js::RootLists& rootListsForRootingContext(JSRuntime* rt) { - return js::PerThreadDataFriendFields::getMainThread(rt)->roots; - } - static js::RootLists& rootListsForRootingContext(js::PerThreadDataFriendFields* pt) { - return pt->roots; - } - public: template explicit Rooted(const RootingContext& cx @@ -737,7 +748,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase : ptr(js::GCMethods::initial()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - registerWithRootLists(rootListsForRootingContext(cx)); + registerWithRootLists(js::RootListsForRootingContext(cx)); } template @@ -746,7 +757,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase : ptr(mozilla::Forward(initial)) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - registerWithRootLists(rootListsForRootingContext(cx)); + registerWithRootLists(js::RootListsForRootingContext(cx)); } ~Rooted() { @@ -1074,20 +1085,18 @@ class PersistentRooted : public js::PersistentRootedBase, public: PersistentRooted() : ptr(js::GCMethods::initial()) {} - explicit PersistentRooted(JSContext* cx) { - init(cx); + template + explicit PersistentRooted(const RootingContext& cx) + : ptr(js::GCMethods::initial()) + { + registerWithRootLists(js::RootListsForRootingContext(cx)); } - PersistentRooted(JSContext* cx, T initial) { - init(cx, initial); - } - - explicit PersistentRooted(JSRuntime* rt) { - init(rt); - } - - PersistentRooted(JSRuntime* rt, T initial) { - init(rt, initial); + template + PersistentRooted(const RootingContext& cx, U&& initial) + : ptr(mozilla::Forward(initial)) + { + registerWithRootLists(js::RootListsForRootingContext(cx)); } PersistentRooted(const PersistentRooted& rhs) @@ -1109,22 +1118,15 @@ class PersistentRooted : public js::PersistentRootedBase, return ListBase::isInList(); } - void init(JSContext* cx) { + template + void init(const RootingContext& cx) { init(cx, js::GCMethods::initial()); } - void init(JSContext* cx, T initial) { - ptr = initial; - registerWithRootLists(js::ContextFriendFields::get(cx)->roots); - } - - void init(JSRuntime* rt) { - init(rt, js::GCMethods::initial()); - } - - void init(JSRuntime* rt, T initial) { - ptr = initial; - registerWithRootLists(js::PerThreadDataFriendFields::getMainThread(rt)->roots); + template + void init(const RootingContext& cx, U&& initial) { + ptr = mozilla::Forward(initial); + registerWithRootLists(js::RootListsForRootingContext(cx)); } void reset() { diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 5220e4f356..4e7cd37ce2 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -349,12 +349,6 @@ js::gc::GCRuntime::markRuntime(JSTracer* trc, TraceOrMarkRuntime traceOrMark) MarkPersistentRootedChains(trc); } - if (rt->asyncStackForNewActivations) - TraceRoot(trc, &rt->asyncStackForNewActivations, "asyncStackForNewActivations"); - - if (rt->asyncCauseForNewActivations) - TraceRoot(trc, &rt->asyncCauseForNewActivations, "asyncCauseForNewActivations"); - if (rt->scriptAndCountsVector) { ScriptAndCountsVector& vec = *rt->scriptAndCountsVector; for (size_t i = 0; i < vec.length(); i++) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 91a90fcc6d..91d2a1dec1 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -803,6 +803,22 @@ BaselineCompiler::emitDebugTrap() return appendICEntry(ICEntry::Kind_DebugTrap, masm.currentOffset()); } +void +BaselineCompiler::emitCoverage(jsbytecode* pc) +{ + double* counterAddr = &script->getPCCounts(pc).numExec(); + AllocatableRegisterSet regs(RegisterSet::Volatile()); + Register counterAddrReg = R2.scratchReg(); + FloatRegister counter = regs.takeAnyFloat(); + FloatRegister one = regs.takeAnyFloat(); + + masm.movePtr(ImmPtr(counterAddr), counterAddrReg); + masm.loadDouble(Address(counterAddrReg, 0), counter); + masm.loadConstantDouble(1.0, one); + masm.addDouble(one, counter); + masm.storeDouble(counter, Address(counterAddrReg, 0)); +} + #ifdef JS_TRACE_LOGGING bool BaselineCompiler::emitTraceLoggerEnter() @@ -900,6 +916,7 @@ BaselineCompiler::emitBody() bool lastOpUnreachable = false; uint32_t emittedOps = 0; mozilla::DebugOnly prevpc = pc; + bool compileCoverage = script->hasScriptCounts(); while (true) { JSOp op = JSOp(*pc); @@ -954,6 +971,10 @@ BaselineCompiler::emitBody() if (compileDebugInstrumentation_ && !emitDebugTrap()) return Method_Error; + // Emit code coverage code, to fill the same data as the interpreter. + if (compileCoverage) + emitCoverage(pc); + switch (op) { default: JitSpew(JitSpew_BaselineAbort, "Unhandled op: %s", js_CodeName[op]); diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index a900c15d37..e0d54e33b9 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -264,6 +264,7 @@ class BaselineCompiler : public BaselineCompilerSpecific void emitIsDebuggeeCheck(); bool emitDebugPrologue(); bool emitDebugTrap(); + void emitCoverage(jsbytecode* pc); bool emitTraceLoggerEnter(); bool emitTraceLoggerExit(); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index c82afbeadd..173e1a1191 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -469,6 +469,8 @@ PrepareForDebuggerOnIonCompilationHook(JSContext* cx, jit::MIRGraph& graph, void jit::FinishOffThreadBuilder(JSContext* cx, IonBuilder* builder) { + MOZ_ASSERT(HelperThreadState().isLocked()); + // Clean the references to the pending IonBuilder, if we just finished it. if (builder->script()->baselineScript()->hasPendingIonBuilder() && builder->script()->baselineScript()->pendingIonBuilder() == builder) @@ -574,18 +576,24 @@ class AutoLazyLinkExitFrame void jit::LazyLink(JSContext* cx, HandleScript calleeScript) { - // Get the pending builder from the Ion frame. - MOZ_ASSERT(calleeScript->hasBaselineScript()); - IonBuilder* builder = calleeScript->baselineScript()->pendingIonBuilder(); - calleeScript->baselineScript()->removePendingIonBuilder(calleeScript); + IonBuilder* builder; + + { + AutoLockHelperThreadState lock; + + // Get the pending builder from the Ion frame. + MOZ_ASSERT(calleeScript->hasBaselineScript()); + builder = calleeScript->baselineScript()->pendingIonBuilder(); + calleeScript->baselineScript()->removePendingIonBuilder(calleeScript); + + // Remove from pending. + builder->removeFrom(HelperThreadState().ionLazyLinkList()); + } // See PrepareForDebuggerOnIonCompilationHook AutoScriptVector debugScripts(cx); OnIonCompilationInfo info(builder->alloc().lifoAlloc()); - // Remove from pending. - builder->removeFrom(HelperThreadState().ionLazyLinkList()); - { AutoEnterAnalysis enterTypes(cx); if (!LinkBackgroundCodeGen(cx, builder, &debugScripts, &info)) { @@ -599,7 +607,10 @@ jit::LazyLink(JSContext* cx, HandleScript calleeScript) if (info.filled()) Debugger::onIonCompilation(cx, debugScripts, info.graph); - FinishOffThreadBuilder(cx, builder); + { + AutoLockHelperThreadState lock; + FinishOffThreadBuilder(cx, builder); + } MOZ_ASSERT(calleeScript->hasBaselineScript()); MOZ_ASSERT(calleeScript->baselineOrIonRawPointer()); @@ -2592,15 +2603,15 @@ jit::SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, AutoVal ScriptFrameIter iter(cx); if (iter.isFunctionFrame()) data.calleeToken = CalleeToToken(iter.callee(cx), /* constructing = */ false); - + // Push newTarget onto the stack, as well as Argv. if (!vals.reserve(2)) return false; - + data.maxArgc = 2; data.maxArgv = vals.begin(); vals.infallibleAppend(state.asExecute()->thisv()); - if (iter.isFunctionFrame()) { + if (iter.isFunctionFrame()) { if (state.asExecute()->newTarget().isNull()) vals.infallibleAppend(iter.newTarget()); else diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index f28bd637df..bdf31ca6e6 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -68,7 +68,7 @@ ReadFrameSlot(JitFrameLayout* fp, int32_t slot) static inline void WriteFrameSlot(JitFrameLayout* fp, int32_t slot, uintptr_t value) { - *(uintptr_t*) AddressOfFrameSlot(fp, slot) = value; + *(uintptr_t*) AddressOfFrameSlot(fp, slot) = value; } static inline double @@ -362,9 +362,9 @@ JitFrameIterator::machineState() const for (GeneralRegisterBackwardIterator iter(reader.allGprSpills()); iter.more(); iter++) machine.setRegisterLocation(*iter, --spill); - uint8_t *spillAlign = alignDoubleSpillWithOffset(reinterpret_cast(spill), 0); + uint8_t* spillAlign = alignDoubleSpillWithOffset(reinterpret_cast(spill), 0); - char *floatSpill = reinterpret_cast(spillAlign); + char* floatSpill = reinterpret_cast(spillAlign); FloatRegisterSet fregs = reader.allFloatSpills().set(); fregs = fregs.reduceSetForPush(); for (FloatRegisterBackwardIterator iter(fregs); iter.more(); iter++) { @@ -389,7 +389,7 @@ NumArgAndLocalSlots(const InlineFrameIterator& frame) } static void -CloseLiveIterator(JSContext* cx, const InlineFrameIterator& frame, uint32_t stackSlot) +CloseLiveIteratorIon(JSContext* cx, const InlineFrameIterator& frame, uint32_t stackSlot) { SnapshotIterator si = frame.snapshotIterator(); @@ -408,6 +408,20 @@ CloseLiveIterator(JSContext* cx, const InlineFrameIterator& frame, uint32_t stac UnwindIteratorForUncatchableException(cx, obj); } +class IgnoreStackDepthOp +{ + public: + uint32_t operator()() { return UINT32_MAX; } +}; + +class TryNoteIterIon : public TryNoteIter +{ + public: + TryNoteIterIon(JSContext* cx, JSScript* script, jsbytecode* pc) + : TryNoteIter(cx, script, pc, IgnoreStackDepthOp()) + { } +}; + static void HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromException* rfe, bool* overrecursed) @@ -460,23 +474,8 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx if (!script->hasTrynotes()) return; - uint32_t base = NumArgAndLocalSlots(frame); - SnapshotIterator si = frame.snapshotIterator(); - MOZ_ASSERT(si.numAllocations() >= base); - const uint32_t stackDepth = si.numAllocations() - base; - - JSTryNote* tn = script->trynotes()->vector; - JSTryNote* tnEnd = tn + script->trynotes()->length; - - uint32_t pcOffset = uint32_t(pc - script->main()); - for (; tn != tnEnd; ++tn) { - if (pcOffset < tn->start) - continue; - if (pcOffset >= tn->start + tn->length) - continue; - - if (tn->stackDepth > stackDepth) - continue; + for (TryNoteIterIon tni(cx, script, pc); !tni.done(); ++tni) { + JSTryNote* tn = *tni; switch (tn->kind) { case JSTRY_FOR_IN: { @@ -484,7 +483,7 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx MOZ_ASSERT(tn->stackDepth > 0); uint32_t localSlot = tn->stackDepth; - CloseLiveIterator(cx, frame, localSlot); + CloseLiveIteratorIon(cx, frame, localSlot); break; } @@ -518,50 +517,49 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx } static void -ForcedReturn(JSContext* cx, const JitFrameIterator& frame, jsbytecode* pc, - ResumeFromException* rfe, bool* calledDebugEpilogue) +OnLeaveBaselineFrame(JSContext* cx, const JitFrameIterator& frame, jsbytecode* pc, + ResumeFromException* rfe, bool frameOk) { BaselineFrame* baselineFrame = frame.baselineFrame(); - MOZ_ASSERT(baselineFrame->hasReturnValue()); - - if (jit::DebugEpilogue(cx, baselineFrame, pc, true)) { + if (jit::DebugEpilogue(cx, baselineFrame, pc, frameOk)) { rfe->kind = ResumeFromException::RESUME_FORCED_RETURN; rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset; rfe->stackPointer = reinterpret_cast(baselineFrame); - return; } +} - // DebugEpilogue threw an exception. Propagate to the caller frame. - *calledDebugEpilogue = true; +static inline void +ForcedReturn(JSContext* cx, const JitFrameIterator& frame, jsbytecode* pc, + ResumeFromException* rfe) +{ + OnLeaveBaselineFrame(cx, frame, pc, rfe, true); +} + +static inline void +BaselineFrameAndStackPointersFromTryNote(JSTryNote* tn, const JitFrameIterator& frame, + uint8_t** framePointer, uint8_t** stackPointer) +{ + JSScript* script = frame.baselineFrame()->script(); + *framePointer = frame.fp() - BaselineFrame::FramePointerOffset; + *stackPointer = *framePointer - BaselineFrame::Size() - + (script->nfixed() + tn->stackDepth) * sizeof(Value); } static void -HandleClosingGeneratorReturn(JSContext* cx, const JitFrameIterator& frame, jsbytecode* pc, - jsbytecode* unwoundScopeToPc, ResumeFromException* rfe, - bool* calledDebugEpilogue) +SettleOnTryNote(JSContext* cx, JSTryNote *tn, const JitFrameIterator& frame, + ScopeIter& si, ResumeFromException* rfe, jsbytecode** pc) { - // If we're closing a legacy generator, we need to return to the caller - // after executing the |finally| blocks. This is very similar to a forced - // return from the debugger. + RootedScript script(cx, frame.baselineFrame()->script()); - if (!cx->isExceptionPending()) - return; - RootedValue exception(cx); - if (!cx->getPendingException(&exception)) - return; - if (!exception.isMagic(JS_GENERATOR_CLOSING)) - return; + // Unwind scope chain (pop block objects). + if (cx->isExceptionPending()) + UnwindScope(cx, si, UnwindScopeToTryPc(script, tn)); - cx->clearPendingException(); - SetReturnValueForClosingGenerator(cx, frame.baselineFrame()); + // Compute base pointer and stack pointer. + BaselineFrameAndStackPointersFromTryNote(tn, frame, &rfe->framePointer, &rfe->stackPointer); - if (unwoundScopeToPc) { - if (frame.baselineFrame()->isDebuggee()) - frame.baselineFrame()->setOverridePc(unwoundScopeToPc); - pc = unwoundScopeToPc; - } - - ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue); + // Compute the pc. + *pc = script->main() + tn->start + tn->length; } struct AutoBaselineHandlingException @@ -579,122 +577,101 @@ struct AutoBaselineHandlingException } }; -static void -HandleExceptionBaseline(JSContext* cx, const JitFrameIterator& frame, ResumeFromException* rfe, - jsbytecode* pc, jsbytecode** unwoundScopeToPc, bool* calledDebugEpilogue) +class BaselineFrameStackDepthOp { - MOZ_ASSERT(frame.isBaselineJS()); - MOZ_ASSERT(!*calledDebugEpilogue); - - // We may be propagating a forced return from the interrupt - // callback, which cannot easily force a return. - if (cx->isPropagatingForcedReturn()) { - cx->clearPropagatingForcedReturn(); - ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue); - return; + BaselineFrame* frame_; + public: + explicit BaselineFrameStackDepthOp(BaselineFrame* frame) + : frame_(frame) + { } + uint32_t operator()() { + MOZ_ASSERT(frame_->numValueSlots() >= frame_->script()->nfixed()); + return frame_->numValueSlots() - frame_->script()->nfixed(); } +}; - RootedValue exception(cx); - if (cx->isExceptionPending() && cx->compartment()->isDebuggee() && - !cx->isClosingGenerator()) - { - switch (Debugger::onExceptionUnwind(cx, frame.baselineFrame())) { - case JSTRAP_ERROR: - // Uncatchable exception. - MOZ_ASSERT(!cx->isExceptionPending()); - break; +class TryNoteIterBaseline : public TryNoteIter +{ + public: + TryNoteIterBaseline(JSContext* cx, BaselineFrame* frame, jsbytecode* pc) + : TryNoteIter(cx, frame->script(), pc, BaselineFrameStackDepthOp(frame)) + { } +}; - case JSTRAP_CONTINUE: - case JSTRAP_THROW: - MOZ_ASSERT(cx->isExceptionPending()); - break; +// Close all live iterators on a BaselineFrame due to exception unwinding. The +// pc parameter is updated to where the scopes have been unwound to. +static void +CloseLiveIteratorsBaselineForUncatchableException(JSContext* cx, const JitFrameIterator& frame, + jsbytecode* pc) +{ + for (TryNoteIterBaseline tni(cx, frame.baselineFrame(), pc); !tni.done(); ++tni) { + JSTryNote* tn = *tni; - case JSTRAP_RETURN: - ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue); - return; - - default: - MOZ_CRASH("Invalid trap status"); + if (tn->kind == JSTRY_FOR_IN) { + uint8_t* framePointer; + uint8_t* stackPointer; + BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer); + Value iterValue(*(Value*) stackPointer); + RootedObject iterObject(cx, &iterValue.toObject()); + UnwindIteratorForUncatchableException(cx, iterObject); } } +} +static bool +ProcessTryNotesBaseline(JSContext* cx, const JitFrameIterator& frame, ScopeIter& si, + ResumeFromException* rfe, jsbytecode** pc) +{ RootedScript script(cx, frame.baselineFrame()->script()); - if (!script->hasTrynotes()) { - HandleClosingGeneratorReturn(cx, frame, pc, *unwoundScopeToPc, rfe, calledDebugEpilogue); - return; - } - - JSTryNote* tn = script->trynotes()->vector; - JSTryNote* tnEnd = tn + script->trynotes()->length; - - uint32_t pcOffset = uint32_t(pc - script->main()); - ScopeIter si(cx, frame.baselineFrame(), pc); - for (; tn != tnEnd; ++tn) { - if (pcOffset < tn->start) - continue; - if (pcOffset >= tn->start + tn->length) - continue; - - // Skip if the try note's stack depth exceeds the frame's stack depth. - // See the big comment in TryNoteIter::settle for more info. - MOZ_ASSERT(frame.baselineFrame()->numValueSlots() >= script->nfixed()); - size_t stackDepth = frame.baselineFrame()->numValueSlots() - script->nfixed(); - if (tn->stackDepth > stackDepth) - continue; - - // Unwind scope chain (pop block objects). - if (cx->isExceptionPending()) { - *unwoundScopeToPc = UnwindScopeToTryPc(script, tn); - UnwindScope(cx, si, *unwoundScopeToPc); - } - - // Compute base pointer and stack pointer. - rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset; - rfe->stackPointer = rfe->framePointer - BaselineFrame::Size() - - (script->nfixed() + tn->stackDepth) * sizeof(Value); + for (TryNoteIterBaseline tni(cx, frame.baselineFrame(), *pc); !tni.done(); ++tni) { + JSTryNote* tn = *tni; + MOZ_ASSERT(cx->isExceptionPending()); switch (tn->kind) { - case JSTRY_CATCH: - if (cx->isExceptionPending()) { - // If we're closing a legacy generator, we have to skip catch - // blocks. - if (cx->isClosingGenerator()) - continue; + case JSTRY_CATCH: { + // If we're closing a legacy generator, we have to skip catch + // blocks. + if (cx->isClosingGenerator()) + continue; - // Ion can compile try-catch, but bailing out to catch - // exceptions is slow. Reset the warm-up counter so that if we - // catch many exceptions we won't Ion-compile the script. - script->resetWarmUpCounter(); + SettleOnTryNote(cx, tn, frame, si, rfe, pc); - // Resume at the start of the catch block. - rfe->kind = ResumeFromException::RESUME_CATCH; - jsbytecode* catchPC = script->main() + tn->start + tn->length; - rfe->target = script->baselineScript()->nativeCodeForPC(script, catchPC); - return; - } - break; + // Ion can compile try-catch, but bailing out to catch + // exceptions is slow. Reset the warm-up counter so that if we + // catch many exceptions we won't Ion-compile the script. + script->resetWarmUpCounter(); - case JSTRY_FINALLY: - if (cx->isExceptionPending()) { - rfe->kind = ResumeFromException::RESUME_FINALLY; - jsbytecode* finallyPC = script->main() + tn->start + tn->length; - rfe->target = script->baselineScript()->nativeCodeForPC(script, finallyPC); - // Drop the exception instead of leaking cross compartment data. - if (!cx->getPendingException(MutableHandleValue::fromMarkedLocation(&rfe->exception))) - rfe->exception = UndefinedValue(); - cx->clearPendingException(); - return; - } - break; + // Resume at the start of the catch block. + rfe->kind = ResumeFromException::RESUME_CATCH; + rfe->target = script->baselineScript()->nativeCodeForPC(script, *pc); + return true; + } + + case JSTRY_FINALLY: { + SettleOnTryNote(cx, tn, frame, si, rfe, pc); + rfe->kind = ResumeFromException::RESUME_FINALLY; + rfe->target = script->baselineScript()->nativeCodeForPC(script, *pc); + // Drop the exception instead of leaking cross compartment data. + if (!cx->getPendingException(MutableHandleValue::fromMarkedLocation(&rfe->exception))) + rfe->exception = UndefinedValue(); + cx->clearPendingException(); + return true; + } case JSTRY_FOR_IN: { - Value iterValue(* (Value*) rfe->stackPointer); + uint8_t* framePointer; + uint8_t* stackPointer; + BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer); + Value iterValue(*(Value*) stackPointer); RootedObject iterObject(cx, &iterValue.toObject()); - if (cx->isExceptionPending()) - UnwindIteratorForException(cx, iterObject); - else - UnwindIteratorForUncatchableException(cx, iterObject); + if (!UnwindIteratorForException(cx, iterObject)) { + // See comment in the JSTRY_FOR_IN case in Interpreter.cpp's + // ProcessTryNotes. + SettleOnTryNote(cx, tn, frame, si, rfe, pc); + MOZ_ASSERT(**pc == JSOP_ENDITER); + return false; + } break; } @@ -706,8 +683,66 @@ HandleExceptionBaseline(JSContext* cx, const JitFrameIterator& frame, ResumeFrom MOZ_CRASH("Invalid try note"); } } + return true; +} - HandleClosingGeneratorReturn(cx, frame, pc, *unwoundScopeToPc, rfe, calledDebugEpilogue); +static void +HandleExceptionBaseline(JSContext* cx, const JitFrameIterator& frame, ResumeFromException* rfe, + jsbytecode* pc) +{ + MOZ_ASSERT(frame.isBaselineJS()); + + // We may be propagating a forced return from the interrupt + // callback, which cannot easily force a return. + if (cx->isPropagatingForcedReturn()) { + cx->clearPropagatingForcedReturn(); + ForcedReturn(cx, frame, pc, rfe); + return; + } + + bool frameOk = false; + RootedScript script(cx, frame.baselineFrame()->script()); + +again: + if (cx->isExceptionPending()) { + if (!cx->isClosingGenerator()) { + switch (Debugger::onExceptionUnwind(cx, frame.baselineFrame())) { + case JSTRAP_ERROR: + // Uncatchable exception. + MOZ_ASSERT(!cx->isExceptionPending()); + goto again; + + case JSTRAP_CONTINUE: + case JSTRAP_THROW: + MOZ_ASSERT(cx->isExceptionPending()); + break; + + case JSTRAP_RETURN: + if (script->hasTrynotes()) + CloseLiveIteratorsBaselineForUncatchableException(cx, frame, pc); + ForcedReturn(cx, frame, pc, rfe); + return; + + default: + MOZ_CRASH("Invalid trap status"); + } + } + + if (script->hasTrynotes()) { + ScopeIter si(cx, frame.baselineFrame(), pc); + if (!ProcessTryNotesBaseline(cx, frame, si, rfe, &pc)) + goto again; + if (rfe->kind != ResumeFromException::RESUME_ENTRY_FRAME) + return; + } + + frameOk = HandleClosingGeneratorReturn(cx, frame.baselineFrame(), frameOk); + frameOk = Debugger::onLeaveFrame(cx, frame.baselineFrame(), frameOk); + } else if (script->hasTrynotes()) { + CloseLiveIteratorsBaselineForUncatchableException(cx, frame, pc); + } + + OnLeaveBaselineFrame(cx, frame, pc, rfe, frameOk); } struct AutoDeleteDebugModeOSRInfo @@ -832,12 +867,6 @@ HandleException(ResumeFromException* rfe) ionScript->decrementInvalidationCount(cx->runtime()->defaultFreeOp()); } else if (iter.isBaselineJS()) { - // It's invalid to call DebugEpilogue twice for the same frame. - bool calledDebugEpilogue = false; - - // Remember the pc we unwound the scope to. - jsbytecode* unwoundScopeToPc = nullptr; - // Set a flag on the frame to signal to DebugModeOSR that we're // handling an exception. Also ensure the frame has an override // pc. We clear the frame's override pc when we leave this block, @@ -854,7 +883,7 @@ HandleException(ResumeFromException* rfe) iter.baselineScriptAndPc(nullptr, &pc); AutoBaselineHandlingException handlingException(iter.baselineFrame(), pc); - HandleExceptionBaseline(cx, iter, rfe, pc, &unwoundScopeToPc, &calledDebugEpilogue); + HandleExceptionBaseline(cx, iter, rfe, pc); // If we are propagating an exception through a frame with // on-stack recompile info, we should free the allocated @@ -862,8 +891,11 @@ HandleException(ResumeFromException* rfe) // be returning to the recompile handler. AutoDeleteDebugModeOSRInfo deleteDebugModeOSRInfo(iter.baselineFrame()); - if (rfe->kind != ResumeFromException::RESUME_ENTRY_FRAME) + if (rfe->kind != ResumeFromException::RESUME_ENTRY_FRAME && + rfe->kind != ResumeFromException::RESUME_FORCED_RETURN) + { return; + } TraceLogStopEvent(logger, TraceLogger_Baseline); TraceLogStopEvent(logger, TraceLogger_Scripts); @@ -873,26 +905,8 @@ HandleException(ResumeFromException* rfe) probes::ExitScript(cx, script, script->functionNonDelazifying(), /* popSPSFrame = */ false); - if (iter.baselineFrame()->isDebuggee() && !calledDebugEpilogue) { - // If we still need to call the DebugEpilogue, we must - // remember the pc we unwound the scope chain to, as it will - // be out of sync with the frame's actual pc. - if (unwoundScopeToPc) - iter.baselineFrame()->setOverridePc(unwoundScopeToPc); - - // If DebugEpilogue returns |true|, we have to perform a forced - // return, e.g. return frame->returnValue() to the caller. - BaselineFrame* frame = iter.baselineFrame(); - jsbytecode* pc; - iter.baselineScriptAndPc(nullptr, &pc); - if (jit::DebugEpilogue(cx, frame, pc, false)) { - MOZ_ASSERT(frame->hasReturnValue()); - rfe->kind = ResumeFromException::RESUME_FORCED_RETURN; - rfe->framePointer = iter.fp() - BaselineFrame::FramePointerOffset; - rfe->stackPointer = reinterpret_cast(frame); - return; - } - } + if (rfe->kind == ResumeFromException::RESUME_FORCED_RETURN) + return; } JitFrameLayout* current = iter.isScripted() ? iter.jsFrame() : nullptr; @@ -1099,7 +1113,7 @@ MarkIonJSFrame(JSTracer* trc, const JitFrameIterator& frame) TraceRoot(trc, v, "ion-gc-slot"); } - uintptr_t *spill = frame.spillBase(); + uintptr_t* spill = frame.spillBase(); LiveGeneralRegisterSet gcRegs = safepoint.gcSpills(); LiveGeneralRegisterSet valueRegs = safepoint.valueSpills(); for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) { @@ -1184,11 +1198,11 @@ UpdateIonJSFrameForMinorGC(JSTracer* trc, const JitFrameIterator& frame) Nursery& nursery = trc->runtime()->gc.nursery; - const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp()); + const SafepointIndex* si = ionScript->getSafepointIndex(frame.returnAddressToFp()); SafepointReader safepoint(ionScript, si); LiveGeneralRegisterSet slotsRegs = safepoint.slotsOrElementsSpills(); - uintptr_t *spill = frame.spillBase(); + uintptr_t* spill = frame.spillBase(); for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) { --spill; if (slotsRegs.has(*iter)) @@ -1309,7 +1323,7 @@ MarkJitExitFrameCopiedArguments(JSTracer* trc, const VMFunction* f, ExitFooterFr #endif static void -MarkJitExitFrame(JSTracer *trc, const JitFrameIterator &frame) +MarkJitExitFrame(JSTracer* trc, const JitFrameIterator& frame) { // Ignore fake exit frames created by EnsureExitFrame. if (frame.isFakeExitFrame()) @@ -1993,7 +2007,7 @@ SnapshotIterator::allocationValue(const RValueAllocation& alloc, ReadMethod rm) } } -const FloatRegisters::RegisterContent* +const FloatRegisters::RegisterContent* SnapshotIterator::floatAllocationPointer(const RValueAllocation& alloc) const { switch (alloc.mode()) { diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 3aeb0272a9..7d15c5ba65 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -687,17 +687,18 @@ DebugEpilogueOnBaselineReturn(JSContext* cx, BaselineFrame* frame, jsbytecode* p bool DebugEpilogue(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool ok) { - // Unwind scope chain to stack depth 0. - ScopeIter si(cx, frame, pc); - UnwindAllScopesInFrame(cx, si); - jsbytecode* unwindPc = frame->script()->main(); - frame->setOverridePc(unwindPc); - // If Debugger::onLeaveFrame returns |true| we have to return the frame's // return value. If it returns |false|, the debugger threw an exception. // In both cases we have to pop debug scopes. ok = Debugger::onLeaveFrame(cx, frame, ok); + // Unwind to the outermost scope and set pc to the end of the script, + // regardless of error. + ScopeIter si(cx, frame, pc); + UnwindAllScopesInFrame(cx, si); + JSScript* script = frame->script(); + frame->setOverridePc(script->lastPC()); + if (frame->isNonEvalFunctionFrame()) { MOZ_ASSERT_IF(ok, frame->hasReturnValue()); DebugScopes::onPopCall(frame, cx); diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index c376d6d5f7..f5a842c77a 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -138,88 +138,7 @@ js::StackDefs(JSScript* script, jsbytecode* pc) return cs.ndefs; } -static const char * const countBaseNames[] = { - "interp" -}; - -JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) == PCCounts::BASE_LIMIT); - -static const char * const countAccessNames[] = { - "infer_mono", - "infer_di", - "infer_poly", - "infer_barrier", - "infer_nobarrier", - "observe_undefined", - "observe_null", - "observe_boolean", - "observe_int32", - "observe_double", - "observe_string", - "observe_object" -}; - -JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) + - JS_ARRAY_LENGTH(countAccessNames) == PCCounts::ACCESS_LIMIT); - -static const char * const countElementNames[] = { - "id_int", - "id_double", - "id_other", - "id_unknown", - "elem_typed", - "elem_packed", - "elem_dense", - "elem_other" -}; - -JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) + - JS_ARRAY_LENGTH(countAccessNames) + - JS_ARRAY_LENGTH(countElementNames) == PCCounts::ELEM_LIMIT); - -static const char * const countPropertyNames[] = { - "prop_static", - "prop_definite", - "prop_other" -}; - -JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) + - JS_ARRAY_LENGTH(countAccessNames) + - JS_ARRAY_LENGTH(countPropertyNames) == PCCounts::PROP_LIMIT); - -static const char * const countArithNames[] = { - "arith_int", - "arith_double", - "arith_other", - "arith_unknown", -}; - -JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) + - JS_ARRAY_LENGTH(countArithNames) == PCCounts::ARITH_LIMIT); - -/* static */ const char* -PCCounts::countName(JSOp op, size_t which) -{ - MOZ_ASSERT(which < numCounts(op)); - - if (which < BASE_LIMIT) - return countBaseNames[which]; - - if (accessOp(op)) { - if (which < ACCESS_LIMIT) - return countAccessNames[which - BASE_LIMIT]; - if (elementOp(op)) - return countElementNames[which - ACCESS_LIMIT]; - if (propertyOp(op)) - return countPropertyNames[which - ACCESS_LIMIT]; - MOZ_CRASH("bad op"); - } - - if (arithOp(op)) - return countArithNames[which - BASE_LIMIT]; - - MOZ_CRASH("bad op"); -} +const char * PCCounts::numExecName = "interp"; void js::DumpIonScriptCounts(Sprinter* sp, jit::IonScriptCounts* ionCounts) @@ -245,26 +164,15 @@ js::DumpPCCounts(JSContext* cx, HandleScript script, Sprinter* sp) #ifdef DEBUG jsbytecode* pc = script->code(); while (pc < script->codeEnd()) { - JSOp op = JSOp(*pc); jsbytecode* next = GetNextPc(pc); if (!Disassemble1(cx, script, pc, script->pcToOffset(pc), true, sp)) return; - size_t total = PCCounts::numCounts(op); - double* raw = script->getPCCounts(pc).rawCounts(); - Sprint(sp, " {"); - bool printed = false; - for (size_t i = 0; i < total; i++) { - double val = raw[i]; - if (val) { - if (printed) - Sprint(sp, ", "); - Sprint(sp, "\"%s\": %.0f", PCCounts::countName(op, i), val); - printed = true; - } - } + double val = script->getPCCounts(pc).numExec(); + if (val) + Sprint(sp, "\"%s\": %.0f", PCCounts::numExecName, val); Sprint(sp, "}\n"); pc = next; @@ -1851,39 +1759,13 @@ js::GetPCCountScriptSummary(JSContext* cx, size_t index) } } - double baseTotals[PCCounts::BASE_LIMIT] = {0.0}; - double accessTotals[PCCounts::ACCESS_LIMIT - PCCounts::BASE_LIMIT] = {0.0}; - double elementTotals[PCCounts::ELEM_LIMIT - PCCounts::ACCESS_LIMIT] = {0.0}; - double propertyTotals[PCCounts::PROP_LIMIT - PCCounts::ACCESS_LIMIT] = {0.0}; - double arithTotals[PCCounts::ARITH_LIMIT - PCCounts::BASE_LIMIT] = {0.0}; + double total = 0.0; - for (unsigned i = 0; i < script->length(); i++) { - PCCounts& counts = sac.getPCCounts(script->offsetToPC(i)); - if (!counts) - continue; - - JSOp op = (JSOp)script->code()[i]; - unsigned numCounts = PCCounts::numCounts(op); - - for (unsigned j = 0; j < numCounts; j++) { - double value = counts.get(j); - if (j < PCCounts::BASE_LIMIT) { - baseTotals[j] += value; - } else if (PCCounts::accessOp(op)) { - if (j < PCCounts::ACCESS_LIMIT) - accessTotals[j - PCCounts::BASE_LIMIT] += value; - else if (PCCounts::elementOp(op)) - elementTotals[j - PCCounts::ACCESS_LIMIT] += value; - else if (PCCounts::propertyOp(op)) - propertyTotals[j - PCCounts::ACCESS_LIMIT] += value; - else - MOZ_CRASH("Bad opcode"); - } else if (PCCounts::arithOp(op)) { - arithTotals[j - PCCounts::BASE_LIMIT] += value; - } else { - MOZ_CRASH("Bad opcode"); - } - } + jsbytecode* codeEnd = script->codeEnd(); + for (jsbytecode* pc = script->code(); pc < codeEnd; pc = GetNextPc(pc)) { + PCCounts& counts = sac.getPCCounts(pc); + double value = counts.numExec(); + total += value; } AppendJSONProperty(buf, "totals"); @@ -1891,16 +1773,7 @@ js::GetPCCountScriptSummary(JSContext* cx, size_t index) MaybeComma comma = NO_COMMA; - AppendArrayJSONProperties(cx, buf, baseTotals, countBaseNames, - JS_ARRAY_LENGTH(baseTotals), comma); - AppendArrayJSONProperties(cx, buf, accessTotals, countAccessNames, - JS_ARRAY_LENGTH(accessTotals), comma); - AppendArrayJSONProperties(cx, buf, elementTotals, countElementNames, - JS_ARRAY_LENGTH(elementTotals), comma); - AppendArrayJSONProperties(cx, buf, propertyTotals, countPropertyNames, - JS_ARRAY_LENGTH(propertyTotals), comma); - AppendArrayJSONProperties(cx, buf, arithTotals, countArithNames, - JS_ARRAY_LENGTH(arithTotals), comma); + AppendArrayJSONProperties(cx, buf, &total, &PCCounts::numExecName, 1, comma); uint64_t ionActivity = 0; jit::IonScriptCounts* ionCounts = sac.getIonCounts(); @@ -1991,19 +1864,14 @@ GetPCCountJSON(JSContext* cx, const ScriptAndCounts& sac, StringBuffer& buf) } PCCounts& counts = sac.getPCCounts(pc); - unsigned numCounts = PCCounts::numCounts(op); AppendJSONProperty(buf, "counts"); buf.append('{'); - MaybeComma comma = NO_COMMA; - for (unsigned i = 0; i < numCounts; i++) { - double value = counts.get(i); - if (value > 0) { - AppendJSONProperty(buf, PCCounts::countName(op, i), comma); - comma = COMMA; - NumberValueToStringBuffer(cx, DoubleValue(value), buf); - } + double value = counts.numExec(); + if (value > 0) { + AppendJSONProperty(buf, PCCounts::numExecName, NO_COMMA); + NumberValueToStringBuffer(cx, DoubleValue(value), buf); } buf.append('}'); diff --git a/js/src/jsopcode.h b/js/src/jsopcode.h index 4b9fe6fb73..cba383559a 100644 --- a/js/src/jsopcode.h +++ b/js/src/jsopcode.h @@ -772,123 +772,18 @@ GetBytecodeInteger(jsbytecode* pc) */ class PCCounts { - friend class ::JSScript; - double* counts; -#ifdef DEBUG - size_t capacity; -#elif JS_BITS_PER_WORD == 32 - void* padding; -#endif + double numExec_; public: - enum BaseCounts { - BASE_INTERP = 0, - - BASE_LIMIT - }; - - enum AccessCounts { - ACCESS_MONOMORPHIC = BASE_LIMIT, - ACCESS_DIMORPHIC, - ACCESS_POLYMORPHIC, - - ACCESS_BARRIER, - ACCESS_NOBARRIER, - - ACCESS_UNDEFINED, - ACCESS_NULL, - ACCESS_BOOLEAN, - ACCESS_INT32, - ACCESS_DOUBLE, - ACCESS_STRING, - ACCESS_OBJECT, - - ACCESS_LIMIT - }; - - static bool accessOp(JSOp op) { - /* - * Access ops include all name, element and property reads, as well as - * SETELEM and SETPROP (for ElementCounts/PropertyCounts alignment). - */ - if (op == JSOP_SETELEM || op == JSOP_SETPROP) - return true; - int format = js_CodeSpec[op].format; - return !!(format & (JOF_NAME | JOF_GNAME | JOF_ELEM | JOF_PROP)) - && !(format & JOF_SET); + double& numExec() { + return numExec_; + } + double numExec() const { + return numExec_; } - enum ElementCounts { - ELEM_ID_INT = ACCESS_LIMIT, - ELEM_ID_DOUBLE, - ELEM_ID_OTHER, - ELEM_ID_UNKNOWN, - - ELEM_OBJECT_TYPED, - ELEM_OBJECT_PACKED, - ELEM_OBJECT_DENSE, - ELEM_OBJECT_OTHER, - - ELEM_LIMIT - }; - - static bool elementOp(JSOp op) { - return accessOp(op) && (JOF_MODE(js_CodeSpec[op].format) == JOF_ELEM); - } - - enum PropertyCounts { - PROP_STATIC = ACCESS_LIMIT, - PROP_DEFINITE, - PROP_OTHER, - - PROP_LIMIT - }; - - static bool propertyOp(JSOp op) { - return accessOp(op) && (JOF_MODE(js_CodeSpec[op].format) == JOF_PROP); - } - - enum ArithCounts { - ARITH_INT = BASE_LIMIT, - ARITH_DOUBLE, - ARITH_OTHER, - ARITH_UNKNOWN, - - ARITH_LIMIT - }; - - static bool arithOp(JSOp op) { - return !!(js_CodeSpec[op].format & JOF_ARITH); - } - - static size_t numCounts(JSOp op) - { - if (accessOp(op)) { - if (elementOp(op)) - return ELEM_LIMIT; - if (propertyOp(op)) - return PROP_LIMIT; - return ACCESS_LIMIT; - } - if (arithOp(op)) - return ARITH_LIMIT; - return BASE_LIMIT; - } - - static const char* countName(JSOp op, size_t which); - - double* rawCounts() const { return counts; } - - double& get(size_t which) { - MOZ_ASSERT(which < capacity); - return counts[which]; - } - - /* Boolean conversion, for 'if (counters) ...' */ - operator void*() const { - return counts; - } + static const char* numExecName; }; /* Necessary for alignment with the script. */ diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 163780de64..bc5ee86af5 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1274,17 +1274,16 @@ JSScript::initScriptCounts(JSContext* cx) { MOZ_ASSERT(!hasScriptCounts()); - size_t n = 0; + // We allocate one PCCounts for each offset, instead of for each bytecode, + // because the pcCountsVector maps an offset to a PCCounts structure. + size_t nbytes = length() * sizeof(PCCounts); - for (jsbytecode* pc = code(); pc < codeEnd(); pc += GetBytecodeLength(pc)) - n += PCCounts::numCounts(JSOp(*pc)); - - size_t nbytes = (length() * sizeof(PCCounts)) + (n * sizeof(double)); + // Initialize all PCCounts counters to 0. uint8_t* base = zone()->pod_calloc(nbytes); if (!base) return false; - /* Create compartment's scriptCountsMap if necessary. */ + // Create compartment's scriptCountsMap if necessary. ScriptCountsMap* map = compartment()->scriptCountsMap; if (!map) { map = cx->new_(); @@ -1296,30 +1295,16 @@ JSScript::initScriptCounts(JSContext* cx) compartment()->scriptCountsMap = map; } - uint8_t* cursor = base; - ScriptCounts scriptCounts; - scriptCounts.pcCountsVector = (PCCounts*) cursor; - cursor += length() * sizeof(PCCounts); - - for (jsbytecode* pc = code(); pc < codeEnd(); pc += GetBytecodeLength(pc)) { - MOZ_ASSERT(uintptr_t(cursor) % sizeof(double) == 0); - scriptCounts.pcCountsVector[pcToOffset(pc)].counts = (double*) cursor; - size_t capacity = PCCounts::numCounts(JSOp(*pc)); -#ifdef DEBUG - scriptCounts.pcCountsVector[pcToOffset(pc)].capacity = capacity; -#endif - cursor += capacity * sizeof(double); - } + scriptCounts.pcCountsVector = (PCCounts*) base; + // Register the current ScriptCount in the compartment's map. if (!map->putNew(this, scriptCounts)) { js_free(base); return false; } hasScriptCounts_ = true; // safe to set this; we can't fail after this point - MOZ_ASSERT(size_t(cursor - base) == nbytes); - /* Enable interrupts in any interpreter frames running on this script. */ for (ActivationIterator iter(cx->runtime()); !iter.done(); ++iter) { if (iter->isInterpreter()) diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index bc14fb131e..34caaf0e2f 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -2011,7 +2011,7 @@ CASE(EnableInterruptsPseudoOpcode) if (script->hasScriptCounts()) { PCCounts counts = script->getPCCounts(REGS.pc); - counts.get(PCCounts::BASE_INTERP)++; + counts.numExec()++; moreInterrupts = true; } diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index ec93e5a5b9..935472e98d 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -126,8 +126,8 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime) profilerSampleBufferGen_(0), profilerSampleBufferLapCount_(1), asmJSActivationStack_(nullptr), - asyncStackForNewActivations(nullptr), - asyncCauseForNewActivations(nullptr), + asyncStackForNewActivations(this), + asyncCauseForNewActivations(this), asyncCallIsExplicit(false), entryMonitor(nullptr), parentRuntime(parentRuntime), diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index a6178cf047..6d254766da 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -695,12 +695,12 @@ struct JSRuntime : public JS::shadow::Runtime, * New activations will reset this to nullptr on construction after getting * the current value, and will restore the previous value on destruction. */ - js::SavedFrame* asyncStackForNewActivations; + JS::PersistentRooted asyncStackForNewActivations; /* * Value of asyncCause to be attached to asyncStackForNewActivations. */ - JSString* asyncCauseForNewActivations; + JS::PersistentRooted asyncCauseForNewActivations; /* * True if the async call was explicitly requested, e.g. via diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index c35a597a3c..d9f92aafcc 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -441,34 +441,28 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx, return NS_OK; } -/* static */ size_t -mozJSComponentLoader::DataEntrySizeOfExcludingThis(const nsACString& aKey, - ModuleEntry* const& aData, - MallocSizeOf aMallocSizeOf, void*) +// This requires that the keys be strings and the values be pointers. +template +static size_t +SizeOfTableExcludingThis(const nsBaseHashtable& aTable, + MallocSizeOf aMallocSizeOf) { - return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + - aData->SizeOfIncludingThis(aMallocSizeOf); -} - -/* static */ size_t -mozJSComponentLoader::ClassEntrySizeOfExcludingThis(const nsACString& aKey, - const nsAutoPtr& aData, - MallocSizeOf aMallocSizeOf, void*) -{ - return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + - aData->SizeOfIncludingThis(aMallocSizeOf); + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) { + n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf); + } + return n; } size_t mozJSComponentLoader::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) { - size_t amount = aMallocSizeOf(this); - - amount += mModules.SizeOfExcludingThis(DataEntrySizeOfExcludingThis, aMallocSizeOf); - amount += mImports.SizeOfExcludingThis(ClassEntrySizeOfExcludingThis, aMallocSizeOf); - amount += mInProgressImports.SizeOfExcludingThis(DataEntrySizeOfExcludingThis, aMallocSizeOf); - - return amount; + size_t n = aMallocSizeOf(this); + n += SizeOfTableExcludingThis(mModules, aMallocSizeOf); + n += SizeOfTableExcludingThis(mImports, aMallocSizeOf); + n += SizeOfTableExcludingThis(mInProgressImports, aMallocSizeOf); + return n; } // Some stack based classes for cleaning up on early return diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index 2b9dbc1f37..dec59e25b8 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -186,21 +186,17 @@ Native2WrappedNativeMap::~Native2WrappedNativeMap() } size_t -Native2WrappedNativeMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) +Native2WrappedNativeMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - size_t n = 0; - n += mallocSizeOf(this); - n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); + size_t n = mallocSizeOf(this); + n += mTable->ShallowSizeOfIncludingThis(mallocSizeOf); + for (auto iter = mTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += mallocSizeOf(entry->value); + } return n; } -/* static */ size_t -Native2WrappedNativeMap::SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, - mozilla::MallocSizeOf mallocSizeOf, void*) -{ - return mallocSizeOf(((Native2WrappedNativeMap::Entry*)hdr)->value); -} - /***************************************************************************/ // implement IID2WrappedJSClassMap... @@ -258,22 +254,17 @@ IID2NativeInterfaceMap::~IID2NativeInterfaceMap() } size_t -IID2NativeInterfaceMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) +IID2NativeInterfaceMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - size_t n = 0; - n += mallocSizeOf(this); - n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); + size_t n = mallocSizeOf(this); + n += mTable->ShallowSizeOfIncludingThis(mallocSizeOf); + for (auto iter = mTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->value->SizeOfIncludingThis(mallocSizeOf); + } return n; } -/* static */ size_t -IID2NativeInterfaceMap::SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, - mozilla::MallocSizeOf mallocSizeOf, void*) -{ - XPCNativeInterface* iface = ((IID2NativeInterfaceMap::Entry*)hdr)->value; - return iface->SizeOfIncludingThis(mallocSizeOf); -} - /***************************************************************************/ // implement ClassInfo2NativeSetMap... @@ -297,10 +288,8 @@ ClassInfo2NativeSetMap::~ClassInfo2NativeSetMap() size_t ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { - size_t n = 0; - n += mallocSizeOf(this); - // The second arg is nullptr because this is a "shallow" measurement of the map. - n += PL_DHashTableSizeOfIncludingThis(mTable, nullptr, mallocSizeOf); + size_t n = mallocSizeOf(this); + n += mTable->ShallowSizeOfIncludingThis(mallocSizeOf); return n; } @@ -333,21 +322,17 @@ ClassInfo2WrappedNativeProtoMap::~ClassInfo2WrappedNativeProtoMap() } size_t -ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) +ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - size_t n = 0; - n += mallocSizeOf(this); - n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); + size_t n = mallocSizeOf(this); + n += mTable->ShallowSizeOfIncludingThis(mallocSizeOf); + for (auto iter = mTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += mallocSizeOf(entry->value); + } return n; } -/* static */ size_t -ClassInfo2WrappedNativeProtoMap::SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, - mozilla::MallocSizeOf mallocSizeOf, void*) -{ - return mallocSizeOf(((ClassInfo2WrappedNativeProtoMap::Entry*)hdr)->value); -} - /***************************************************************************/ // implement NativeSetMap... @@ -449,21 +434,17 @@ NativeSetMap::~NativeSetMap() } size_t -NativeSetMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) +NativeSetMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - size_t n = 0; - n += mallocSizeOf(this); - n += PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf); + size_t n = mallocSizeOf(this); + n += mTable->ShallowSizeOfIncludingThis(mallocSizeOf); + for (auto iter = mTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->key_value->SizeOfIncludingThis(mallocSizeOf); + } return n; } -/* static */ size_t -NativeSetMap::SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, mozilla::MallocSizeOf mallocSizeOf, void*) -{ - XPCNativeSet* set = ((NativeSetMap::Entry*)hdr)->key_value; - return set->SizeOfIncludingThis(mallocSizeOf); -} - /***************************************************************************/ // implement IID2ThisTranslatorMap... diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 6963ee08cb..ecff46e4ee 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -149,15 +149,13 @@ public: inline uint32_t Count() { return mTable->EntryCount(); } PLDHashTable::Iterator Iter() const { return PLDHashTable::Iterator(mTable); } - size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; ~Native2WrappedNativeMap(); private: Native2WrappedNativeMap(); // no implementation explicit Native2WrappedNativeMap(int size); - static size_t SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, mozilla::MallocSizeOf mallocSizeOf, void*); - private: PLDHashTable* mTable; }; @@ -260,15 +258,13 @@ public: PLDHashTable::Iterator Iter() { return PLDHashTable::Iterator(mTable); } - size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; ~IID2NativeInterfaceMap(); private: IID2NativeInterfaceMap(); // no implementation explicit IID2NativeInterfaceMap(int size); - static size_t SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, mozilla::MallocSizeOf mallocSizeOf, void*); - private: PLDHashTable* mTable; }; @@ -372,15 +368,13 @@ public: PLDHashTable::Iterator Iter() const { return PLDHashTable::Iterator(mTable); } PLDHashTable::Iterator Iter() { return PLDHashTable::Iterator(mTable); } - size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; ~ClassInfo2WrappedNativeProtoMap(); private: ClassInfo2WrappedNativeProtoMap(); // no implementation explicit ClassInfo2WrappedNativeProtoMap(int size); - static size_t SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, mozilla::MallocSizeOf mallocSizeOf, void*); - private: PLDHashTable* mTable; }; @@ -442,15 +436,13 @@ public: PLDHashTable::Iterator Iter() const { return PLDHashTable::Iterator(mTable); } PLDHashTable::Iterator Iter() { return PLDHashTable::Iterator(mTable); } - size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; ~NativeSetMap(); private: NativeSetMap(); // no implementation explicit NativeSetMap(int size); - static size_t SizeOfEntryExcludingThis(PLDHashEntryHdr* hdr, mozilla::MallocSizeOf mallocSizeOf, void*); - private: PLDHashTable* mTable; }; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 82bae0ff5e..9e080df095 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -10662,12 +10662,8 @@ PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, if (mCaret) { *aPresShellSize += mCaret->SizeOfIncludingThis(aMallocSizeOf); } - *aPresShellSize += mVisibleImages.SizeOfExcludingThis(nullptr, - aMallocSizeOf, - nullptr); - *aPresShellSize += mFramesToDirty.SizeOfExcludingThis(nullptr, - aMallocSizeOf, - nullptr); + *aPresShellSize += mVisibleImages.ShallowSizeOfExcludingThis(aMallocSizeOf); + *aPresShellSize += mFramesToDirty.ShallowSizeOfExcludingThis(aMallocSizeOf); *aPresShellSize += aArenaObjectsSize->mOther; *aStyleSetsSize += StyleSet()->SizeOfIncludingThis(aMallocSizeOf); diff --git a/layout/style/CSSVariableDeclarations.cpp b/layout/style/CSSVariableDeclarations.cpp index 28c08b83af..86f42b1ac7 100644 --- a/layout/style/CSSVariableDeclarations.cpp +++ b/layout/style/CSSVariableDeclarations.cpp @@ -204,24 +204,16 @@ CSSVariableDeclarations::AddVariablesToResolver( aResolver); } -static size_t -SizeOfTableEntry(const nsAString& aKey, - const nsString& aValue, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - size_t n = 0; - n += aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); - n += aValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf); - return n; -} - size_t CSSVariableDeclarations::SizeOfIncludingThis( mozilla::MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += mVariables.SizeOfExcludingThis(SizeOfTableEntry, aMallocSizeOf); + n += mVariables.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mVariables.ConstIter(); !iter.Done(); iter.Next()) { + n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + n += iter.Data().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } return n; } diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index c3177aae54..83044cbed3 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -2589,36 +2589,26 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Loader, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Loader, Release) -struct SheetMemoryCounter { - size_t size; - mozilla::MallocSizeOf mallocSizeOf; -}; - -static size_t -CountSheetMemory(URIPrincipalReferrerPolicyAndCORSModeHashKey* /* unused */, - const nsRefPtr& aSheet, - mozilla::MallocSizeOf aMallocSizeOf, - void* /* unused */) -{ - // If aSheet has a parent, then its parent will report it so we don't - // have to worry about it here. - // Likewise, if aSheet has an owning node, then the document that - // node is in will report it. - if (aSheet->GetOwnerNode() || aSheet->GetParentSheet()) { - return 0; - } - return aSheet->SizeOfIncludingThis(aMallocSizeOf); -} - size_t Loader::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - size_t s = aMallocSizeOf(this); + size_t n = aMallocSizeOf(this); if (mSheets) { - s += mSheets->mCompleteSheets.SizeOfExcludingThis(CountSheetMemory, aMallocSizeOf); + n += mSheets->mCompleteSheets.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mSheets->mCompleteSheets.ConstIter(); + !iter.Done(); + iter.Next()) { + // If aSheet has a parent, then its parent will report it so we don't + // have to worry about it here. Likewise, if aSheet has an owning node, + // then the document that node is in will report it. + const nsRefPtr& aSheet = iter.Data(); + n += (aSheet->GetOwnerNode() || aSheet->GetParentSheet()) + ? 0 + : aSheet->SizeOfIncludingThis(aMallocSizeOf); + } } - s += mObservers.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mObservers.ShallowSizeOfExcludingThis(aMallocSizeOf); // Measurement of the following members may be added later if DMD finds it is // worthwhile: @@ -2631,7 +2621,7 @@ Loader::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const // - mDocument, because it's a weak backpointer // - mPreferredSheet, because it can be a shared string - return s; + return n; } } // namespace css diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index d7901c8457..a4450dcff2 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -172,7 +172,7 @@ private: // Uses any of the sets of ops below. struct RuleHashTableEntry : public PLDHashEntryHdr { // If you add members that have heap allocated memory be sure to change the - // logic in SizeOfRuleHashTableEntry(). + // logic in SizeOfRuleHashTable(). // Auto length 1, because we always have at least one entry in mRules. nsAutoTArray mRules; }; @@ -743,10 +743,14 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso } static size_t -SizeOfRuleHashTableEntry(PLDHashEntryHdr* aHdr, MallocSizeOf aMallocSizeOf, void *) +SizeOfRuleHashTable(const PLDHashTable& aTable, MallocSizeOf aMallocSizeOf) { - RuleHashTableEntry* entry = static_cast(aHdr); - return entry->mRules.ShallowSizeOfExcludingThis(aMallocSizeOf); + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->mRules.ShallowSizeOfExcludingThis(aMallocSizeOf); + } + return n; } size_t @@ -754,21 +758,13 @@ RuleHash::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = 0; - n += PL_DHashTableSizeOfExcludingThis(&mIdTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); + n += SizeOfRuleHashTable(mIdTable, aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mClassTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); + n += SizeOfRuleHashTable(mClassTable, aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mTagTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); + n += SizeOfRuleHashTable(mTagTable, aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mNameSpaceTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); + n += SizeOfRuleHashTable(mNameSpaceTable, aMallocSizeOf); n += mUniversalRules.ShallowSizeOfExcludingThis(aMallocSizeOf); @@ -947,26 +943,14 @@ struct RuleCascadeData { }; static size_t -SizeOfSelectorsEntry(PLDHashEntryHdr* aHdr, MallocSizeOf aMallocSizeOf, void *) +SizeOfSelectorsHashTable(const PLDHashTable& aTable, MallocSizeOf aMallocSizeOf) { - AtomSelectorEntry* entry = static_cast(aHdr); - return entry->mSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); -} - -static size_t -SizeOfKeyframesRuleEntryExcludingThis(nsStringHashKey::KeyType aKey, - nsCSSKeyframesRule* const& aData, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - // We don't own the nsCSSKeyframesRule objects so we don't count them. We do - // care about the size of the keys' nsAString members' buffers though. - // - // Note that we depend on nsStringHashKey::GetKey() returning a reference, - // since otherwise aKey would be a copy of the string key and we would not be - // measuring the right object here. - - return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->mSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); + } + return n; } size_t @@ -982,21 +966,16 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const n += mStateSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mIdSelectors, - SizeOfSelectorsEntry, aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mClassSelectors, - SizeOfSelectorsEntry, aMallocSizeOf); + n += SizeOfSelectorsHashTable(mIdSelectors, aMallocSizeOf); + n += SizeOfSelectorsHashTable(mClassSelectors, aMallocSizeOf); n += mPossiblyNegatedClassSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mPossiblyNegatedIDSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mAttributeSelectors, - SizeOfSelectorsEntry, aMallocSizeOf); - n += PL_DHashTableSizeOfExcludingThis(&mAnonBoxRules, - SizeOfRuleHashTableEntry, aMallocSizeOf); + n += SizeOfSelectorsHashTable(mAttributeSelectors, aMallocSizeOf); + n += SizeOfRuleHashTable(mAnonBoxRules, aMallocSizeOf); #ifdef MOZ_XUL - n += PL_DHashTableSizeOfExcludingThis(&mXULTreeRules, - SizeOfRuleHashTableEntry, aMallocSizeOf); + n += SizeOfRuleHashTable(mXULTreeRules, aMallocSizeOf); #endif n += mFontFaceRules.ShallowSizeOfExcludingThis(aMallocSizeOf); @@ -1004,9 +983,17 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const n += mFontFeatureValuesRules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mPageRules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mCounterStyleRules.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += mKeyframesRuleTable.SizeOfExcludingThis(SizeOfKeyframesRuleEntryExcludingThis, - aMallocSizeOf, - nullptr); + + n += mKeyframesRuleTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mKeyframesRuleTable.ConstIter(); !iter.Done(); iter.Next()) { + // We don't own the nsCSSKeyframesRule objects so we don't count them. We + // do care about the size of the keys' nsAString members' buffers though. + // + // Note that we depend on nsStringHashKey::GetKey() returning a reference, + // since otherwise aKey would be a copy of the string key and we would not + // be measuring the right object here. + n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } return n; } diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index 769a7dd4eb..9cde112e2b 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -161,26 +161,21 @@ nsHTMLCSSStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext) return false; } -size_t -SizeOfCachedStyleAttrsEntryExcludingThis(nsStringHashKey::KeyType& aKey, - MiscContainer* const& aData, - mozilla::MallocSizeOf aMallocSizeOf, - void* userArg) -{ - // We don't own the MiscContainers so we don't count them. We do care about - // the size of the nsString members in the keys though. - return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); -} - /* virtual */ size_t nsHTMLCSSStyleSheet::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { // The size of mCachedStyleAttrs's mTable member (a PLDHashTable) is // significant in itself, but more significant is the size of the nsString // members of the nsStringHashKeys. - return mCachedStyleAttrs.SizeOfExcludingThis(SizeOfCachedStyleAttrsEntryExcludingThis, - aMallocSizeOf, - nullptr); + size_t n = 0; + n += mCachedStyleAttrs.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mCachedStyleAttrs.ConstIter(); !iter.Done(); iter.Next()) { + // We don't own the MiscContainers (the hash table values) so we don't + // count them. We do care about the size of the nsString members in the + // keys though. + n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } + return n; } /* virtual */ size_t diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 121d0c8c57..d47902efa1 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -500,26 +500,16 @@ nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage) return entry->mRule; } -static size_t -SizeOfAttributesEntryExcludingThis(PLDHashEntryHdr* aEntry, - MallocSizeOf aMallocSizeOf, - void* aArg) -{ - NS_PRECONDITION(aEntry, "The entry should not be null!"); - - MappedAttrTableEntry* entry = static_cast(aEntry); - NS_ASSERTION(entry->mAttributes, "entry->mAttributes should not be null!"); - return entry->mAttributes->SizeOfIncludingThis(aMallocSizeOf); -} - size_t nsHTMLStyleSheet::DOMSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += PL_DHashTableSizeOfExcludingThis(&mMappedAttrTable, - SizeOfAttributesEntryExcludingThis, - aMallocSizeOf); + n += mMappedAttrTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mMappedAttrTable.ConstIter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->mAttributes->SizeOfIncludingThis(aMallocSizeOf); + } // Measurement of the following members may be added later if DMD finds it is // worthwhile: diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index d71e473306..18a1efee17 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -218,18 +218,6 @@ AssertNotAlreadyCached(const char* aPrefType, } #endif -static size_t -SizeOfObserverEntryExcludingThis(ValueObserverHashKey* aKey, - const nsRefPtr& aData, - mozilla::MallocSizeOf aMallocSizeOf, - void*) -{ - size_t n = 0; - n += aKey->mPrefName.SizeOfExcludingThisIfUnshared(aMallocSizeOf); - n += aData->mClosures.ShallowSizeOfExcludingThis(aMallocSizeOf); - return n; -} - // Although this is a member of Preferences, it measures sPreferences and // several other global structures. /* static */ int64_t @@ -241,7 +229,7 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO if (gHashTable) { // pref keys are allocated in a private arena, which we count elsewhere. // pref stringvals are allocated out of the same private arena. - n += PL_DHashTableSizeOfExcludingThis(gHashTable, nullptr, aMallocSizeOf); + n += gHashTable->ShallowSizeOfIncludingThis(aMallocSizeOf); } if (gCacheData) { n += gCacheData->ShallowSizeOfIncludingThis(aMallocSizeOf); @@ -251,8 +239,11 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO } if (gObserverTable) { n += aMallocSizeOf(gObserverTable); - n += gObserverTable->SizeOfExcludingThis(SizeOfObserverEntryExcludingThis, - aMallocSizeOf); + n += gObserverTable->ShallowSizeOfIncludingThis(aMallocSizeOf); + for (auto iter = gObserverTable->Iter(); !iter.Done(); iter.Next()) { + n += iter.Key()->mPrefName.SizeOfExcludingThisIfUnshared(aMallocSizeOf); + n += iter.Data()->mClosures.ShallowSizeOfExcludingThis(aMallocSizeOf); + } } // We don't measure sRootBranch and sDefaultRootBranch here because // DMD indicates they are not significant. diff --git a/netwerk/cache2/CacheFile.cpp b/netwerk/cache2/CacheFile.cpp index 805cc46266..82b73dee44 100644 --- a/netwerk/cache2/CacheFile.cpp +++ b/netwerk/cache2/CacheFile.cpp @@ -1947,20 +1947,6 @@ CacheFile::InitIndexEntry() return NS_OK; } -// Memory reporting - -namespace { - -size_t -CollectChunkSize(uint32_t const & aIdx, - nsRefPtr const & aChunk, - mozilla::MallocSizeOf mallocSizeOf, void* aClosure) -{ - return aChunk->SizeOfIncludingThis(mallocSizeOf); -} - -} // namespace - size_t CacheFile::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { @@ -1968,8 +1954,14 @@ CacheFile::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const size_t n = 0; n += mKey.SizeOfExcludingThisIfUnshared(mallocSizeOf); - n += mChunks.SizeOfExcludingThis(CollectChunkSize, mallocSizeOf); - n += mCachedChunks.SizeOfExcludingThis(CollectChunkSize, mallocSizeOf); + n += mChunks.ShallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mChunks.ConstIter(); !iter.Done(); iter.Next()) { + n += iter.Data()->SizeOfIncludingThis(mallocSizeOf); + } + n += mCachedChunks.ShallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mCachedChunks.ConstIter(); !iter.Done(); iter.Next()) { + n += iter.Data()->SizeOfIncludingThis(mallocSizeOf); + } if (mMetadata) { n += mMetadata->SizeOfIncludingThis(mallocSizeOf); } @@ -1986,7 +1978,7 @@ CacheFile::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const } // The listeners are usually classes reported just above. - n += mChunkListeners.SizeOfExcludingThis(nullptr, mallocSizeOf); + n += mChunkListeners.ShallowSizeOfExcludingThis(mallocSizeOf); n += mObjsToRelease.ShallowSizeOfExcludingThis(mallocSizeOf); // mHandle reported directly from CacheFileIOManager. diff --git a/netwerk/cache2/CacheIndex.cpp b/netwerk/cache2/CacheIndex.cpp index 86dcab3928..bb99599f14 100644 --- a/netwerk/cache2/CacheIndex.cpp +++ b/netwerk/cache2/CacheIndex.cpp @@ -20,6 +20,8 @@ #include "nsITimer.h" #include "mozilla/AutoRestore.h" #include +#include "mozilla/Telemetry.h" +#include "mozilla/unused.h" #define kMinUnwrittenChanges 300 @@ -2956,7 +2958,7 @@ CacheIndex::FinishUpdate(bool aSucceeded) NS_WARNING(("CacheIndex::FinishUpdate() - Leaking mDirEnumerator!")); // This can happen only in case dispatching event to IO thread failed in // CacheIndex::PreShutdown(). - mDirEnumerator.forget(); // Leak it since dir enumerator is not threadsafe + unused << mDirEnumerator.forget(); // Leak it since dir enumerator is not threadsafe } else { mDirEnumerator->Close(); mDirEnumerator = nullptr; diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp index a3b2c9d0b1..071e42becf 100644 --- a/netwerk/cache2/CacheStorageService.cpp +++ b/netwerk/cache2/CacheStorageService.cpp @@ -1865,7 +1865,7 @@ CacheStorageService::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) con n += Pool(false).mExpirationArray.ShallowSizeOfExcludingThis(mallocSizeOf); // Entries reported manually in CacheStorageService::CollectReports callback if (sGlobalEntryTables) { - n += sGlobalEntryTables->SizeOfIncludingThis(nullptr, mallocSizeOf); + n += sGlobalEntryTables->ShallowSizeOfIncludingThis(mallocSizeOf); } return n; @@ -1886,36 +1886,28 @@ public: nsISupports *mData; }; -size_t CollectEntryMemory(nsACString const & aKey, - nsRefPtr const & aEntry, - mozilla::MallocSizeOf mallocSizeOf, - void * aClosure) -{ - CacheStorageService::Self()->Lock().AssertCurrentThreadOwns(); - - CacheEntryTable* aTable = static_cast(aClosure); - - size_t n = 0; - n += aKey.SizeOfExcludingThisIfUnshared(mallocSizeOf); - - // Bypass memory-only entries, those will be reported when iterating - // the memory only table. Memory-only entries are stored in both ALL_ENTRIES - // and MEMORY_ONLY hashtables. - if (aTable->Type() == CacheEntryTable::MEMORY_ONLY || aEntry->IsUsingDisk()) - n += aEntry->SizeOfIncludingThis(mallocSizeOf); - - return n; -} - PLDHashOperator ReportStorageMemory(const nsACString& aKey, CacheEntryTable* aTable, void* aClosure) { CacheStorageService::Self()->Lock().AssertCurrentThreadOwns(); - size_t size = aTable->SizeOfIncludingThis(&CollectEntryMemory, - CacheStorageService::MallocSizeOf, - aTable); + size_t size = 0; + mozilla::MallocSizeOf mallocSizeOf = CacheStorageService::MallocSizeOf; + + size += aTable->ShallowSizeOfIncludingThis(mallocSizeOf); + for (auto iter = aTable->Iter(); !iter.Done(); iter.Next()) { + size += iter.Key().SizeOfExcludingThisIfUnshared(mallocSizeOf); + + // Bypass memory-only entries, those will be reported when iterating + // the memory only table. Memory-only entries are stored in both ALL_ENTRIES + // and MEMORY_ONLY hashtables. + nsRefPtr const& entry = iter.Data(); + if (aTable->Type() == CacheEntryTable::MEMORY_ONLY || + entry->IsUsingDisk()) { + size += entry->SizeOfIncludingThis(mallocSizeOf); + } + } ReportStorageMemoryData& data = *static_cast(aClosure); diff --git a/netwerk/dns/nsEffectiveTLDService.cpp b/netwerk/dns/nsEffectiveTLDService.cpp index 306546bfe8..d3a75bd28b 100644 --- a/netwerk/dns/nsEffectiveTLDService.cpp +++ b/netwerk/dns/nsEffectiveTLDService.cpp @@ -122,7 +122,7 @@ size_t nsEffectiveTLDService::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) { size_t n = aMallocSizeOf(this); - n += mHash.SizeOfExcludingThis(nullptr, aMallocSizeOf); + n += mHash.ShallowSizeOfExcludingThis(aMallocSizeOf); // Measurement of the following members may be added later if DMD finds it is // worthwhile: diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index d173408787..7578ac00f1 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -1321,22 +1321,18 @@ nsHostResolver::CancelAsyncRequest(const char *host, } } -static size_t -SizeOfHostDBEntExcludingThis(PLDHashEntryHdr* hdr, MallocSizeOf mallocSizeOf, - void*) -{ - nsHostDBEnt* ent = static_cast(hdr); - return ent->rec->SizeOfIncludingThis(mallocSizeOf); -} - size_t nsHostResolver::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const { MutexAutoLock lock(mLock); size_t n = mallocSizeOf(this); - n += PL_DHashTableSizeOfExcludingThis(&mDB, SizeOfHostDBEntExcludingThis, - mallocSizeOf); + + n += mDB.ShallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mDB.ConstIter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + n += entry->rec->SizeOfIncludingThis(mallocSizeOf); + } // The following fields aren't measured. // - mHighQ, mMediumQ, mLowQ, mEvictionQ, because they just point to diff --git a/security/apps/Makefile.in b/security/apps/Makefile.in deleted file mode 100644 index 9d65c6d778..0000000000 --- a/security/apps/Makefile.in +++ /dev/null @@ -1,48 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -GEN_CERT_HEADER = $(srcdir)/gen_cert_header.py -TEST_SSL_PATH = $(srcdir)/../manager/ssl/tests/unit/test_signed_manifest/ - -marketplace-prod-public.inc: marketplace-prod-public.crt $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) marketplaceProdPublicRoot $< > $@ - -marketplace-prod-reviewers.inc: marketplace-prod-reviewers.crt $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) marketplaceProdReviewersRoot $< > $@ - -marketplace-dev-public.inc: marketplace-dev-public.crt $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) marketplaceDevPublicRoot $< > $@ - -marketplace-dev-reviewers.inc: marketplace-dev-reviewers.crt $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) marketplaceDevReviewersRoot $< > $@ - -marketplace-stage.inc: marketplace-stage.crt $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) marketplaceStageRoot $< > $@ - -ifeq ($(shell test -s trusted-app-public.der; echo $$?),0) -TRUSTED_APP_PUBLIC=trusted-app-public.der -else -TRUSTED_APP_PUBLIC= -endif - -manifest-signing-root.inc: $(TRUSTED_APP_PUBLIC) $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) trustedAppPublicRoot $(TRUSTED_APP_PUBLIC) > $@ - -manifest-signing-test-root.inc: $(TEST_SSL_PATH)trusted_ca1.der $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) trustedAppTestRoot $< > $@ - -xpcshell.inc: $(srcdir)/../manager/ssl/tests/unit/test_signed_apps/trusted_ca1.der $(GEN_CERT_HEADER) - $(PYTHON) $(GEN_CERT_HEADER) xpcshellRoot $< > $@ - -export:: \ - marketplace-prod-public.inc \ - marketplace-prod-reviewers.inc \ - marketplace-dev-public.inc \ - marketplace-dev-reviewers.inc \ - marketplace-stage.inc \ - manifest-signing-root.inc \ - manifest-signing-test-root.inc \ - xpcshell.inc \ - $(NULL) diff --git a/security/apps/gen_cert_header.py b/security/apps/gen_cert_header.py index f77e5ccf1a..0f5ad58396 100644 --- a/security/apps/gen_cert_header.py +++ b/security/apps/gen_cert_header.py @@ -2,38 +2,41 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -import sys import binascii -def file_byte_generator(filename, block_size = 512): +def _file_byte_generator(filename): with open(filename, "rb") as f: - while True: - block = f.read(block_size) - if block: - for byte in block: - yield byte - else: - break + contents = f.read() -def create_header(array_name, in_filename): - hexified = ["0x" + binascii.hexlify(byte) for byte in file_byte_generator(in_filename)] - print "const uint8_t " + array_name + "[] = {" - print ", ".join(hexified) - print "};" - return 0 + # Treat empty files the same as a file containing a lone 0; + # a single-element array will fail cert verifcation just as an + # empty array would. + if not contents: + return ['\0'] -def create_empty_header(array_name): - # mfbt/ArrayUtils.h will not be able to pick up the - # correct specialization for ArrayLength(const array[0]) - # so add a value of 0 which will fail cert verification - # just the same as an empty array - print "const uint8_t " + array_name + "[] = { 0x0 };" - return 0 + return contents -if __name__ == '__main__': - if len(sys.argv) < 2: - print 'ERROR: usage: gen_cert_header.py array_name in_filename' - sys.exit(1); - if len(sys.argv) == 2: - sys.exit(create_empty_header(sys.argv[1])) - sys.exit(create_header(sys.argv[1], sys.argv[2])) +def _create_header(array_name, cert_bytes): + hexified = ["0x" + binascii.hexlify(byte) for byte in cert_bytes] + substs = { 'array_name': array_name, 'bytes': ', '.join(hexified) } + return "const uint8_t %(array_name)s[] = {\n%(bytes)s\n};\n" % substs + +# Create functions named the same as the data arrays that we're going to +# write to the headers, so we don't have to duplicate the names like so: +# +# def arrayName(header, cert_filename): +# header.write(_create_header("arrayName", cert_filename)) +array_names = [ + 'marketplaceProdPublicRoot', + 'marketplaceProdReviewersRoot', + 'marketplaceDevPublicRoot', + 'marketplaceDevReviewersRoot', + 'marketplaceStageRoot', + 'trustedAppPublicRoot', + 'trustedAppTestRoot', + 'xpcshellRoot', +] + +for n in array_names: + # Make sure the lambda captures the right string. + globals()[n] = lambda header, cert_filename, name=n: header.write(_create_header(name, _file_byte_generator(cert_filename))) diff --git a/security/apps/moz.build b/security/apps/moz.build index 9be97b6c5f..47d0fb1f38 100644 --- a/security/apps/moz.build +++ b/security/apps/moz.build @@ -22,3 +22,22 @@ LOCAL_INCLUDES += [ DEFINES['NSS_ENABLE_ECC'] = 'True' for var in ('DLL_PREFIX', 'DLL_SUFFIX'): DEFINES[var] = '"%s"' % CONFIG[var] + +test_ssl_path = TOPSRCDIR + '/security/manager/ssl/tests/unit' + +headers_arrays_certs = [ + ('marketplace-prod-public.inc', 'marketplaceProdPublicRoot', 'marketplace-prod-public.crt'), + ('marketplace-prod-reviewers.inc', 'marketplaceProdReviewersRoot', 'marketplace-prod-reviewers.crt'), + ('marketplace-dev-public.inc', 'marketplaceDevPublicRoot', 'marketplace-dev-public.crt'), + ('marketplace-dev-reviewers.inc', 'marketplaceDevReviewersRoot', 'marketplace-dev-reviewers.crt'), + ('marketplace-stage.inc', 'marketplaceStageRoot', 'marketplace-stage.crt'), + ('manifest-signing-root.inc', 'trustedAppPublicRoot', 'trusted-app-public.der'), + ('manifest-signing-test-root.inc', 'trustedAppTestRoot', test_ssl_path + '/test_signed_manifest/trusted_ca1.der'), + ('xpcshell.inc', 'xpcshellRoot', test_ssl_path + '/test_signed_apps/trusted_ca1.der'), +] + +for header, array_name, cert in headers_arrays_certs: + GENERATED_FILES += [header] + h = GENERATED_FILES[header] + h.script = 'gen_cert_header.py:' + array_name + h.inputs = [cert] diff --git a/security/apps/trusted-app-public.der b/security/apps/trusted-app-public.der new file mode 100644 index 0000000000..e69de29bb2 diff --git a/startupcache/StartupCache.cpp b/startupcache/StartupCache.cpp index 779561e6fc..88bd65812d 100644 --- a/startupcache/StartupCache.cpp +++ b/startupcache/StartupCache.cpp @@ -377,20 +377,21 @@ StartupCache::SizeOfMapping() } size_t -StartupCache::HeapSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) +StartupCache::HeapSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { // This function could measure more members, but they haven't been found by // DMD to be significant. They can be added later if necessary. - return aMallocSizeOf(this) + - mTable.SizeOfExcludingThis(SizeOfEntryExcludingThis, aMallocSizeOf) + - mPendingWrites.ShallowSizeOfExcludingThis(aMallocSizeOf); -} -/* static */ size_t -StartupCache::SizeOfEntryExcludingThis(const nsACString& key, const nsAutoPtr& data, - mozilla::MallocSizeOf mallocSizeOf, void *) -{ - return data->SizeOfExcludingThis(mallocSizeOf); + size_t n = aMallocSizeOf(this); + + n += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) { + n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf); + } + + n += mPendingWrites.ShallowSizeOfExcludingThis(aMallocSizeOf); + + return n; } struct CacheWriteHolder diff --git a/startupcache/StartupCache.h b/startupcache/StartupCache.h index 42e4697555..74cab9a7bc 100644 --- a/startupcache/StartupCache.h +++ b/startupcache/StartupCache.h @@ -85,8 +85,8 @@ struct CacheEntry { } - size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { - return mallocSizeOf(data); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { + return mallocSizeOf(this) + mallocSizeOf(data); } }; @@ -135,7 +135,7 @@ public: // This measures all the heap memory used by the StartupCache, i.e. it // excludes the mapping. - size_t HeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + size_t HeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; size_t SizeOfMapping(); @@ -159,11 +159,6 @@ private: static void WriteTimeout(nsITimer *aTimer, void *aClosure); static void ThreadedWrite(void *aClosure); - static size_t SizeOfEntryExcludingThis(const nsACString& key, - const nsAutoPtr& data, - mozilla::MallocSizeOf mallocSizeOf, - void *); - nsClassHashtable mTable; nsTArray mPendingWrites; nsRefPtr mArchive; diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index 48c7758c78..259c425468 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -396,10 +396,12 @@ public: } size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - size_t size; - size = mFileStats.SizeOfExcludingThis(SizeOfFileIOEntryTypeExcludingThis, - aMallocSizeOf) + - mSafeDirs.ShallowSizeOfExcludingThis(aMallocSizeOf); + size_t size = 0; + size += mFileStats.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mFileStats.ConstIter(); !iter.Done(); iter.Next()) { + size += iter.Get()->GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } + size += mSafeDirs.ShallowSizeOfExcludingThis(aMallocSizeOf); uint32_t safeDirsLen = mSafeDirs.Length(); for (uint32_t i = 0; i < safeDirsLen; ++i) { size += mSafeDirs[i].SizeOfExcludingThis(aMallocSizeOf); @@ -448,13 +450,6 @@ private: */ static bool ReflectFileStats(FileIOEntryType* entry, JSContext *cx, JS::Handle obj); - - static size_t SizeOfFileIOEntryTypeExcludingThis(FileIOEntryType* aEntry, - mozilla::MallocSizeOf mallocSizeOf, - void*) - { - return aEntry->GetKey().SizeOfExcludingThisIfUnshared(mallocSizeOf); - } }; TelemetryIOInterposeObserver::TelemetryIOInterposeObserver(nsIFile* aXreDir) @@ -3293,8 +3288,8 @@ TelemetryImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) size_t n = aMallocSizeOf(this); // Ignore the hashtables in mAddonMap; they are not significant. - n += mAddonMap.SizeOfExcludingThis(nullptr, aMallocSizeOf); - n += mHistogramMap.SizeOfExcludingThis(nullptr, aMallocSizeOf); + n += mAddonMap.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mHistogramMap.ShallowSizeOfExcludingThis(aMallocSizeOf); { // Scope for mHashMutex lock MutexAutoLock lock(mHashMutex); n += mPrivateSQL.SizeOfExcludingThis(aMallocSizeOf); diff --git a/widget/gtk/nsSound.cpp b/widget/gtk/nsSound.cpp index 360f1dc304..f745cc1863 100644 --- a/widget/gtk/nsSound.cpp +++ b/widget/gtk/nsSound.cpp @@ -24,6 +24,7 @@ #include "nsDirectoryServiceDefs.h" #include "mozilla/FileUtils.h" #include "mozilla/Services.h" +#include "mozilla/unused.h" #include "nsIStringBundle.h" #include "nsIXULAppInfo.h" #include "nsContentUtils.h" @@ -80,7 +81,7 @@ struct ScopedCanberraFile { } void forget() { - mFile.forget(); + mozilla::unused << mFile.forget(); } nsIFile* operator->() { return mFile; } operator nsIFile*() { return mFile; } diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 42629af075..fff4b838b9 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -475,9 +475,9 @@ CycleCollectedJSRuntime::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = 0; - // nullptr for the second arg; we're not measuring anything hanging off the - // entries in mJSHolders. - n += mJSHolders.SizeOfExcludingThis(nullptr, aMallocSizeOf); + // We're deliberately not measuring anything hanging off the entries in + // mJSHolders. + n += mJSHolders.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/xpcom/components/nsCategoryManager.cpp b/xpcom/components/nsCategoryManager.cpp index 46e5bd6b19..29800c1b37 100644 --- a/xpcom/components/nsCategoryManager.cpp +++ b/xpcom/components/nsCategoryManager.cpp @@ -318,7 +318,7 @@ CategoryNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) { // We don't measure the strings pointed to by the entries because the // pointers are non-owning. - return mTable.SizeOfExcludingThis(nullptr, aMallocSizeOf); + return mTable.ShallowSizeOfExcludingThis(aMallocSizeOf); } // @@ -455,17 +455,6 @@ nsCategoryManager::CollectReports(nsIHandleReportCallback* aHandleReport, "Memory used for the XPCOM category manager."); } -static size_t -SizeOfCategoryManagerTableEntryExcludingThis(nsDepCharHashKey::KeyType aKey, - const nsAutoPtr& aData, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - // We don't measure the string pointed to by aKey because it's a non-owning - // pointer. - return aData.get()->SizeOfExcludingThis(aMallocSizeOf); -} - size_t nsCategoryManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) { @@ -473,8 +462,11 @@ nsCategoryManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf); - n += mTable.SizeOfExcludingThis(SizeOfCategoryManagerTableEntryExcludingThis, - aMallocSizeOf); + n += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) { + // We don't measure the key string because it's a non-owning pointer. + n += iter.Data().get()->SizeOfExcludingThis(aMallocSizeOf); + } return n; } diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index 8fc2ceb3c6..6b5fb469c2 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -1810,26 +1810,6 @@ nsComponentManagerImpl::ContractIDToCID(const char* aContractID, return NS_ERROR_FACTORY_NOT_REGISTERED; } -static size_t -SizeOfFactoriesEntryExcludingThis(nsIDHashKey::KeyType aKey, - nsFactoryEntry* const& aData, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - return aData->SizeOfIncludingThis(aMallocSizeOf); -} - -static size_t -SizeOfContractIDsEntryExcludingThis(nsCStringHashKey::KeyType aKey, - nsFactoryEntry* const& aData, - MallocSizeOf aMallocSizeOf, - void* aUserArg) -{ - // We don't measure the nsFactoryEntry data because its owned by mFactories - // (which measures them in SizeOfFactoriesEntryExcludingThis). - return aKey.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf); -} - MOZ_DEFINE_MALLOC_SIZE_OF(ComponentManagerMallocSizeOf) NS_IMETHODIMP @@ -1844,19 +1824,29 @@ nsComponentManagerImpl::CollectReports(nsIHandleReportCallback* aHandleReport, size_t nsComponentManagerImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) + const { size_t n = aMallocSizeOf(this); - n += mLoaderMap.SizeOfExcludingThis(nullptr, aMallocSizeOf); - n += mFactories.SizeOfExcludingThis(SizeOfFactoriesEntryExcludingThis, - aMallocSizeOf); - n += mContractIDs.SizeOfExcludingThis(SizeOfContractIDsEntryExcludingThis, - aMallocSizeOf); + + n += mLoaderMap.ShallowSizeOfExcludingThis(aMallocSizeOf); + + n += mFactories.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mFactories.ConstIter(); !iter.Done(); iter.Next()) { + n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf); + } + + n += mContractIDs.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mContractIDs.ConstIter(); !iter.Done(); iter.Next()) { + // We don't measure the nsFactoryEntry data because it's owned by + // mFactories (which is measured above). + n += iter.Key().SizeOfExcludingThisMustBeUnshared(aMallocSizeOf); + } n += sStaticModules->ShallowSizeOfIncludingThis(aMallocSizeOf); n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf); n += mKnownStaticModules.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += mKnownModules.SizeOfExcludingThis(nullptr, aMallocSizeOf); + n += mKnownModules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf); diff --git a/xpcom/components/nsComponentManager.h b/xpcom/components/nsComponentManager.h index 319b0ff600..b9bcfc1e11 100644 --- a/xpcom/components/nsComponentManager.h +++ b/xpcom/components/nsComponentManager.h @@ -336,7 +336,7 @@ public: nsTArray mPendingServices; - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; #ifdef MOZ_B2G_LOADER // Preload XPT interface info for B2G loader. diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 12c7d8ef56..43e77c2a6b 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -502,29 +502,23 @@ AtomImpl::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) //---------------------------------------------------------------------- -static size_t -SizeOfAtomTableEntryExcludingThis(PLDHashEntryHdr* aHdr, - MallocSizeOf aMallocSizeOf, - void* aArg) -{ - AtomTableEntry* entry = static_cast(aHdr); - return entry->mAtom->SizeOfIncludingThis(aMallocSizeOf); -} - void NS_SizeOfAtomTablesIncludingThis(MallocSizeOf aMallocSizeOf, size_t* aMain, size_t* aStatic) { - *aMain = gAtomTable - ? PL_DHashTableSizeOfExcludingThis(gAtomTable, - SizeOfAtomTableEntryExcludingThis, - aMallocSizeOf) - : 0; + *aMain = 0; + if (gAtomTable) { + *aMain += gAtomTable->ShallowSizeOfIncludingThis(aMallocSizeOf); + for (auto iter = gAtomTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + *aMain += entry->mAtom->SizeOfIncludingThis(aMallocSizeOf); + } + } // The atoms in the this table are almost certainly stored in static data, so - // we don't need a SizeOfEntry function. + // we don't need to measure entries separately. *aStatic = gStaticAtomTable - ? gStaticAtomTable->SizeOfIncludingThis(nullptr, aMallocSizeOf) + ? gStaticAtomTable->ShallowSizeOfIncludingThis(aMallocSizeOf) : 0; } diff --git a/xpcom/glue/DeadlockDetector.h b/xpcom/glue/DeadlockDetector.h index 93855ac4f0..382e4ef4a7 100644 --- a/xpcom/glue/DeadlockDetector.h +++ b/xpcom/glue/DeadlockDetector.h @@ -144,15 +144,6 @@ public: PR_DestroyLock(mLock); } - static size_t - SizeOfEntryExcludingThis(const T* aKey, const nsAutoPtr& aEntry, - MallocSizeOf aMallocSizeOf, void* aUserArg) - { - // NB: Key is accounted for in the entry. - size_t n = aEntry->SizeOfIncludingThis(aMallocSizeOf); - return n; - } - size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { @@ -160,7 +151,11 @@ public: { PRAutoLock _(mLock); - n += mOrdering.SizeOfExcludingThis(SizeOfEntryExcludingThis, aMallocSizeOf); + n += mOrdering.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = mOrdering.ConstIter(); !iter.Done(); iter.Next()) { + // NB: Key is accounted for in the entry. + n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf); + } } return n; diff --git a/xpcom/glue/nsBaseHashtable.h b/xpcom/glue/nsBaseHashtable.h index de2489f2d2..61b6f8e946 100644 --- a/xpcom/glue/nsBaseHashtable.h +++ b/xpcom/glue/nsBaseHashtable.h @@ -267,80 +267,28 @@ public: void Clear() { nsTHashtable::Clear(); } /** - * client must provide a SizeOfEntryExcludingThisFun function for - * SizeOfExcludingThis. - * @param aKey the key being enumerated - * @param aData Reference to data being enumerated. - * @param aMallocSizeOf the function used to measure heap-allocated blocks - * @param aUserArg passed unchanged from SizeOf{In,Ex}cludingThis - * @return summed size of the things pointed to by the entries - */ - typedef size_t - (*SizeOfEntryExcludingThisFun)(KeyType aKey, - const DataType& aData, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg); - - /** - * Measure the size of the table's entry storage and the table itself. - * If |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things - * pointed to by entries. + * Measure the size of the table's entry storage. The size of things pointed + * to by entries must be measured separately; hence the "Shallow" prefix. * - * @param aSizeOfEntryExcludingThis - * the SizeOfEntryExcludingThisFun function to call - * @param aMallocSizeOf the function used to meeasure heap-allocated blocks - * @param aUserArg a point to pass to the - * SizeOfEntryExcludingThisFun function - * @return the summed size of the entries, the table, and the table's storage + * @param aMallocSizeOf the function used to measure heap-allocated blocks + * @return the summed size of the table's storage */ - size_t SizeOfIncludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg = nullptr) + size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return aMallocSizeOf(this) + - this->SizeOfExcludingThis(aSizeOfEntryExcludingThis, aMallocSizeOf, - aUserArg); + return this->mTable.ShallowSizeOfExcludingThis(aMallocSizeOf); } /** - * Measure the size of the table's entry storage, and if - * |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things - * pointed to by entries. - * - * @param aSizeOfEntryExcludingThis the - * SizeOfEntryExcludingThisFun function to call - * @param aMallocSizeOf the function used to measure heap-allocated blocks - * @param aUserArg a pointer to pass to the - * SizeOfEntryExcludingThisFun function - * @return the summed size of all the entries + * Like ShallowSizeOfExcludingThis, but includes sizeof(*this). */ - size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg = nullptr) const + size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - if (aSizeOfEntryExcludingThis) { - s_SizeOfArgs args = { aSizeOfEntryExcludingThis, aUserArg }; - return PL_DHashTableSizeOfExcludingThis(&this->mTable, s_SizeOfStub, - aMallocSizeOf, &args); - } - return PL_DHashTableSizeOfExcludingThis(&this->mTable, nullptr, - aMallocSizeOf); + return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf); } #ifdef DEBUG using nsTHashtable::MarkImmutable; #endif - -protected: - struct s_SizeOfArgs - { - SizeOfEntryExcludingThisFun func; - void* userArg; - }; - - static size_t s_SizeOfStub(PLDHashEntryHdr* aEntry, - mozilla::MallocSizeOf aMallocSizeOf, - void* aArg); }; // @@ -366,20 +314,4 @@ nsBaseHashtableET::~nsBaseHashtableET() { } - -// -// nsBaseHashtable definitions -// - -template -size_t -nsBaseHashtable::s_SizeOfStub( - PLDHashEntryHdr* aHdr, mozilla::MallocSizeOf aMallocSizeOf, void* aArg) -{ - EntryType* ent = static_cast(aHdr); - s_SizeOfArgs* eargs = static_cast(aArg); - - return (eargs->func)(ent->GetKey(), ent->mData, aMallocSizeOf, eargs->userArg); -} - #endif // nsBaseHashtable_h__ diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index 9669e96d6c..7e640e64f0 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -270,68 +270,47 @@ public: } /** - * client must provide a SizeOfEntryExcludingThisFun function for - * SizeOfExcludingThis. - * @param aEntry the entry being enumerated - * @param mallocSizeOf the function used to measure heap-allocated blocks - * @param arg passed unchanged from SizeOf{In,Ex}cludingThis - * @return summed size of the things pointed to by the entries - */ - typedef size_t (*SizeOfEntryExcludingThisFun)(EntryType* aEntry, - mozilla::MallocSizeOf aMallocSizeOf, - void* aArg); - - /** - * Measure the size of the table's entry storage, and if - * |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things - * pointed to by entries. + * Measure the size of the table's entry storage. Does *not* measure anything + * hanging off table entries; hence the "Shallow" prefix. To measure that, + * either use SizeOfExcludingThis() or iterate manually over the entries, + * calling SizeOfExcludingThis() on each one. * - * @param sizeOfEntryExcludingThis the - * SizeOfEntryExcludingThisFun function to call - * @param mallocSizeOf the function used to measure heap-allocated blocks - * @param userArg a pointer to pass to the - * SizeOfEntryExcludingThisFun function - * @return the summed size of all the entries + * @param aMallocSizeOf the function used to measure heap-allocated blocks + * @return the measured shallow size of the table */ - size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg = nullptr) const + size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - if (aSizeOfEntryExcludingThis) { - s_SizeOfArgs args = { aSizeOfEntryExcludingThis, aUserArg }; - return PL_DHashTableSizeOfExcludingThis(&mTable, s_SizeOfStub, - aMallocSizeOf, &args); - } - return PL_DHashTableSizeOfExcludingThis(&mTable, nullptr, aMallocSizeOf); + return mTable.ShallowSizeOfExcludingThis(aMallocSizeOf); } /** - * If the EntryType defines SizeOfExcludingThis, there's no need to define a new - * SizeOfEntryExcludingThisFun. + * Like ShallowSizeOfExcludingThis, but includes sizeof(*this). + */ + size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf); + } + + /** + * This is a "deep" measurement of the table. To use it, |EntryType| must + * define SizeOfExcludingThis, and that method will be called on all live + * entries. */ size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return SizeOfExcludingThis(BasicSizeOfEntryExcludingThisFun, aMallocSizeOf); + size_t n = ShallowSizeOfExcludingThis(aMallocSizeOf); + for (auto iter = ConstIter(); !iter.Done(); iter.Next()) { + n += (*iter.Get()).SizeOfExcludingThis(aMallocSizeOf); + } + return n; } /** * Like SizeOfExcludingThis, but includes sizeof(*this). */ - size_t SizeOfIncludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, - void* aUserArg = nullptr) const - { - return aMallocSizeOf(this) + - SizeOfExcludingThis(aSizeOfEntryExcludingThis, aMallocSizeOf, aUserArg); - } - - /** - * If the EntryType defines SizeOfExcludingThis, there's no need to define a new - * SizeOfEntryExcludingThisFun. - */ size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return SizeOfIncludingThis(BasicSizeOfEntryExcludingThisFun, aMallocSizeOf); + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); } /** @@ -374,22 +353,6 @@ protected: static void s_InitEntry(PLDHashEntryHdr* aEntry, const void* aKey); - /** - * passed internally during sizeOf counting. Allocated on the stack. - * - * @param userFunc the SizeOfEntryExcludingThisFun passed to - * SizeOf{In,Ex}cludingThis by the client - * @param userArg the userArg passed unaltered - */ - struct s_SizeOfArgs - { - SizeOfEntryExcludingThisFun userFunc; - void* userArg; - }; - - static size_t s_SizeOfStub(PLDHashEntryHdr* aEntry, - mozilla::MallocSizeOf aMallocSizeOf, void* aArg); - private: // copy constructor, not implemented nsTHashtable(nsTHashtable& aToCopy) = delete; @@ -399,14 +362,6 @@ private: */ static const PLDHashTableOps* Ops(); - /** - * An implementation of SizeOfEntryExcludingThisFun that calls SizeOfExcludingThis() - * on each entry. - */ - static size_t BasicSizeOfEntryExcludingThisFun(EntryType* aEntry, - mozilla::MallocSizeOf aMallocSizeOf, - void*); - // assignment operator, not implemented nsTHashtable& operator=(nsTHashtable& aToEqual) = delete; }; @@ -447,16 +402,6 @@ nsTHashtable::Ops() return &sOps; } -// static -template -size_t -nsTHashtable::BasicSizeOfEntryExcludingThisFun(EntryType* aEntry, - mozilla::MallocSizeOf aMallocSizeOf, - void*) -{ - return aEntry->SizeOfExcludingThis(aMallocSizeOf); -} - // static definitions template @@ -506,19 +451,6 @@ nsTHashtable::s_InitEntry(PLDHashEntryHdr* aEntry, new (aEntry) EntryType(reinterpret_cast(aKey)); } -template -size_t -nsTHashtable::s_SizeOfStub(PLDHashEntryHdr* aEntry, - mozilla::MallocSizeOf aMallocSizeOf, - void* aArg) -{ - // dereferences the function-pointer to the user's enumeration function - return (*reinterpret_cast(aArg)->userFunc)( - static_cast(aEntry), - aMallocSizeOf, - reinterpret_cast(aArg)->userArg); -} - class nsCycleCollectionTraversalCallback; template diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 4b29519be7..e68e6ac8e8 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -218,8 +218,7 @@ PLDHashTable::PLDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize, , mEntrySize(aEntrySize) , mEntryCount(0) , mRemovedCount(0) - , mGeneration(0) - , mEntryStore(nullptr) + , mEntryStore() #ifdef DEBUG , mChecker() #endif @@ -248,7 +247,6 @@ PLDHashTable::operator=(PLDHashTable&& aOther) mHashShift = Move(aOther.mHashShift); mEntryCount = Move(aOther.mEntryCount); mRemovedCount = Move(aOther.mRemovedCount); - mGeneration = Move(aOther.mGeneration); mEntryStore = Move(aOther.mEntryStore); #ifdef DEBUG mChecker = Move(aOther.mChecker); @@ -259,7 +257,7 @@ PLDHashTable::operator=(PLDHashTable&& aOther) #ifdef DEBUG AutoDestructorOp op(mChecker); #endif - aOther.mEntryStore = nullptr; + aOther.mEntryStore.Set(nullptr); } return *this; @@ -327,7 +325,8 @@ PLDHashTable::MatchEntryKeyhash(PLDHashEntryHdr* aEntry, PLDHashNumber aKeyHash) PLDHashEntryHdr* PLDHashTable::AddressEntry(uint32_t aIndex) { - return reinterpret_cast(mEntryStore + aIndex * mEntrySize); + return reinterpret_cast( + mEntryStore.Get() + aIndex * mEntrySize); } PLDHashTable::~PLDHashTable() @@ -336,12 +335,12 @@ PLDHashTable::~PLDHashTable() AutoDestructorOp op(mChecker); #endif - if (!mEntryStore) { + if (!mEntryStore.Get()) { return; } // Clear any remaining live entries. - char* entryAddr = mEntryStore; + char* entryAddr = mEntryStore.Get(); char* entryLimit = entryAddr + Capacity() * mEntrySize; while (entryAddr < entryLimit) { PLDHashEntryHdr* entry = (PLDHashEntryHdr*)entryAddr; @@ -351,9 +350,7 @@ PLDHashTable::~PLDHashTable() entryAddr += mEntrySize; } - // Free entry storage last. - free(mEntryStore); - mEntryStore = nullptr; + // Entry storage is freed last, by ~EntryStore(). } void @@ -382,7 +379,7 @@ template PLDHashEntryHdr* PL_DHASH_FASTCALL PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash) { - MOZ_ASSERT(mEntryStore); + MOZ_ASSERT(mEntryStore.Get()); NS_ASSERTION(!(aKeyHash & kCollisionFlag), "!(aKeyHash & kCollisionFlag)"); @@ -451,7 +448,7 @@ PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash) PLDHashEntryHdr* PL_DHASH_FASTCALL PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash) { - MOZ_ASSERT(mEntryStore); + MOZ_ASSERT(mEntryStore.Get()); NS_ASSERTION(!(aKeyHash & kCollisionFlag), "!(aKeyHash & kCollisionFlag)"); @@ -490,7 +487,7 @@ PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash) bool PLDHashTable::ChangeTable(int32_t aDeltaLog2) { - MOZ_ASSERT(mEntryStore); + MOZ_ASSERT(mEntryStore.Get()); // Look, but don't touch, until we succeed in getting new entry store. int32_t oldLog2 = kHashBits - mHashShift; @@ -513,14 +510,13 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2) // We can't fail from here on, so update table parameters. mHashShift = kHashBits - newLog2; mRemovedCount = 0; - mGeneration++; // Assign the new entry store to table. memset(newEntryStore, 0, nbytes); char* oldEntryStore; char* oldEntryAddr; - oldEntryAddr = oldEntryStore = mEntryStore; - mEntryStore = newEntryStore; + oldEntryAddr = oldEntryStore = mEntryStore.Get(); + mEntryStore.Set(newEntryStore); PLDHashMoveEntry moveEntry = mOps->moveEntry; // Copy only live entries, leaving removed ones behind. @@ -544,7 +540,7 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2) MOZ_ALWAYS_INLINE PLDHashNumber PLDHashTable::ComputeKeyHash(const void* aKey) { - MOZ_ASSERT(mEntryStore); + MOZ_ASSERT(mEntryStore.Get()); PLDHashNumber keyHash = mOps->hashKey(this, aKey); keyHash *= kGoldenRatio; @@ -565,10 +561,10 @@ PLDHashTable::Search(const void* aKey) AutoReadOp op(mChecker); #endif - PLDHashEntryHdr* entry = - mEntryStore ? SearchTable(aKey, ComputeKeyHash(aKey)) - : nullptr; - + PLDHashEntryHdr* entry = mEntryStore.Get() + ? SearchTable(aKey, + ComputeKeyHash(aKey)) + : nullptr; return entry; } @@ -580,16 +576,16 @@ PLDHashTable::Add(const void* aKey, const mozilla::fallible_t&) #endif // Allocate the entry storage if it hasn't already been allocated. - if (!mEntryStore) { + if (!mEntryStore.Get()) { uint32_t nbytes; // We already checked this in the constructor, so it must still be true. MOZ_RELEASE_ASSERT(SizeOfEntryStore(CapacityFromHashShift(), mEntrySize, &nbytes)); - mEntryStore = (char*)malloc(nbytes); - if (!mEntryStore) { + mEntryStore.Set((char*)malloc(nbytes)); + if (!mEntryStore.Get()) { return nullptr; } - memset(mEntryStore, 0, nbytes); + memset(mEntryStore.Get(), 0, nbytes); } // If alpha is >= .75, grow or compress the table. If aKey is already in the @@ -638,7 +634,7 @@ PLDHashTable::Add(const void* aKey) { PLDHashEntryHdr* entry = Add(aKey, fallible); if (!entry) { - if (!mEntryStore) { + if (!mEntryStore.Get()) { // We OOM'd while allocating the initial entry storage. uint32_t nbytes; (void) SizeOfEntryStore(CapacityFromHashShift(), mEntrySize, &nbytes); @@ -661,9 +657,10 @@ PLDHashTable::Remove(const void* aKey) AutoWriteOp op(mChecker); #endif - PLDHashEntryHdr* entry = - mEntryStore ? SearchTable(aKey, ComputeKeyHash(aKey)) - : nullptr; + PLDHashEntryHdr* entry = mEntryStore.Get() + ? SearchTable(aKey, + ComputeKeyHash(aKey)) + : nullptr; if (entry) { RawRemove(entry); ShrinkIfAppropriate(); @@ -689,7 +686,7 @@ PLDHashTable::RawRemove(PLDHashEntryHdr* aEntry) // active, which doesn't fit well into how Checker's mState variable works. MOZ_ASSERT(mChecker.IsWritable()); - MOZ_ASSERT(mEntryStore); + MOZ_ASSERT(mEntryStore.Get()); MOZ_ASSERT(EntryIsLive(aEntry), "EntryIsLive(aEntry)"); @@ -730,56 +727,20 @@ PLDHashTable::ShrinkIfAppropriate() } } -MOZ_ALWAYS_INLINE size_t -PLDHashTable::SizeOfExcludingThis( - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) const +size_t +PLDHashTable::ShallowSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { #ifdef DEBUG AutoReadOp op(mChecker); #endif - if (!mEntryStore) { - return 0; - } - - size_t n = aMallocSizeOf(mEntryStore); - if (aSizeOfEntryExcludingThis) { - for (auto iter = ConstIter(); !iter.Done(); iter.Next()) { - n += aSizeOfEntryExcludingThis(iter.Get(), aMallocSizeOf, aArg); - } - } - - return n; -} - -MOZ_ALWAYS_INLINE size_t -PLDHashTable::SizeOfIncludingThis( - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) const -{ - return aMallocSizeOf(this) + - SizeOfExcludingThis(aSizeOfEntryExcludingThis, aMallocSizeOf, aArg); + return aMallocSizeOf(mEntryStore.Get()); } size_t -PL_DHashTableSizeOfExcludingThis( - const PLDHashTable* aTable, - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) +PLDHashTable::ShallowSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { - return aTable->SizeOfExcludingThis(aSizeOfEntryExcludingThis, - aMallocSizeOf, aArg); -} - -size_t -PL_DHashTableSizeOfIncludingThis( - const PLDHashTable* aTable, - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) -{ - return aTable->SizeOfIncludingThis(aSizeOfEntryExcludingThis, - aMallocSizeOf, aArg); + return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf); } PLDHashTable::Iterator::Iterator(Iterator&& aOther) @@ -803,9 +764,9 @@ PLDHashTable::Iterator::Iterator(Iterator&& aOther) PLDHashTable::Iterator::Iterator(PLDHashTable* aTable) : mTable(aTable) - , mStart(mTable->mEntryStore) - , mLimit(mTable->mEntryStore + mTable->Capacity() * mTable->mEntrySize) - , mCurrent(mTable->mEntryStore) + , mStart(mTable->mEntryStore.Get()) + , mLimit(mTable->mEntryStore.Get() + mTable->Capacity() * mTable->mEntrySize) + , mCurrent(mTable->mEntryStore.Get()) , mNexts(0) , mNextsLimit(mTable->EntryCount()) , mHaveRemoved(false) diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index 3727986126..44d4a4b3ba 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -52,9 +52,6 @@ private: PLDHashNumber mKeyHash; }; -typedef size_t (*PLDHashSizeOfEntryExcludingThisFun)( - PLDHashEntryHdr* aHdr, mozilla::MallocSizeOf aMallocSizeOf, void* aArg); - #ifdef DEBUG // This class does three kinds of checking: @@ -212,19 +209,48 @@ private: // hashing is more space-efficient unless the element size gets large (in which // case you should keep using double hashing but switch to using pointer // elements). Also, with double hashing, you can't safely hold an entry pointer -// and use it after an ADD or REMOVE operation, unless you sample -// aTable->mGeneration before adding or removing, and compare the sample after, -// dereferencing the entry pointer only if aTable->mGeneration has not changed. +// and use it after an add or remove operation, unless you sample Generation() +// before adding or removing, and compare the sample after, dereferencing the +// entry pointer only if Generation() has not changed. class PLDHashTable { private: + // This class maintains the invariant that every time the entry store is + // changed, the generation is updated. + class EntryStore + { + private: + char* mEntryStore; + uint32_t mGeneration; + + public: + EntryStore() : mEntryStore(nullptr), mGeneration(0) {} + + ~EntryStore() + { + free(mEntryStore); + mEntryStore = nullptr; + mGeneration++; // a little paranoid, but why not be extra safe? + } + + char* Get() { return mEntryStore; } + const char* Get() const { return mEntryStore; } + + void Set(char* aEntryStore) + { + mEntryStore = aEntryStore; + mGeneration++; + } + + uint32_t Generation() const { return mGeneration; } + }; + const PLDHashTableOps* const mOps; // Virtual operations; see below. int16_t mHashShift; // Multiplicative hash shift. const uint32_t mEntrySize; // Number of bytes in an entry. uint32_t mEntryCount; // Number of entries in table. uint32_t mRemovedCount; // Removed entry sentinels in table. - uint32_t mGeneration; // Entry storage generation number. - char* mEntryStore; // Entry storage; allocated lazily. + EntryStore mEntryStore; // (Lazy) entry storage and generation. #ifdef DEBUG mutable Checker mChecker; @@ -264,9 +290,9 @@ public: // move assignment operator cannot modify them. : mOps(aOther.mOps) , mEntrySize(aOther.mEntrySize) - // Initialize these two fields because they are required for a safe call - // to the destructor, which the move assignment operator does. - , mEntryStore(nullptr) + // Initialize this field because it is required for a safe call to the + // destructor, which the move assignment operator does. + , mEntryStore() #ifdef DEBUG , mChecker() #endif @@ -286,12 +312,12 @@ public: // entry storage will not have yet been allocated. uint32_t Capacity() const { - return mEntryStore ? CapacityFromHashShift() : 0; + return mEntryStore.Get() ? CapacityFromHashShift() : 0; } uint32_t EntrySize() const { return mEntrySize; } uint32_t EntryCount() const { return mEntryCount; } - uint32_t Generation() const { return mGeneration; } + uint32_t Generation() const { return mEntryStore.Generation(); } // To search for a |key| in |table|, call: // @@ -357,17 +383,13 @@ public: // a new |aLength| argument. void ClearAndPrepareForLength(uint32_t aLength); - // Measure the size of the table's entry storage, and if - // |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things - // pointed to by entries. - size_t SizeOfIncludingThis( - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const; + // Measure the size of the table's entry storage. If the entries contain + // pointers to other heap blocks, you have to iterate over the table and + // measure those separately; hence the "Shallow" prefix. + size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; - // Like SizeOfExcludingThis(), but includes sizeof(*this). - size_t SizeOfExcludingThis( - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const; + // Like ShallowSizeOfExcludingThis(), but includes sizeof(*this). + size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; #ifdef DEBUG // Mark a table as immutable for the remainder of its lifetime. This @@ -601,18 +623,6 @@ PL_DHashGetStubOps(void); void PL_DHashTableRawRemove(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); -size_t -PL_DHashTableSizeOfExcludingThis( - const PLDHashTable* aTable, - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr); - -size_t -PL_DHashTableSizeOfIncludingThis( - const PLDHashTable* aTable, - PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, - mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr); - #ifdef DEBUG void PL_DHashMarkTableImmutable(PLDHashTable* aTable); diff --git a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp index 8a434b439b..044ef09aa6 100644 --- a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp +++ b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp @@ -36,8 +36,8 @@ XPTInterfaceInfoManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor); // The entries themselves are allocated out of an arena accounted // for elsewhere, so don't measure them - n += mWorkingSet.mIIDTable.SizeOfExcludingThis(nullptr, aMallocSizeOf); - n += mWorkingSet.mNameTable.SizeOfExcludingThis(nullptr, aMallocSizeOf); + n += mWorkingSet.mIIDTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mWorkingSet.mNameTable.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/xpcom/tests/gtest/TestPLDHash.cpp b/xpcom/tests/gtest/TestPLDHash.cpp index 83dce89084..bf4fc6e153 100644 --- a/xpcom/tests/gtest/TestPLDHash.cpp +++ b/xpcom/tests/gtest/TestPLDHash.cpp @@ -137,10 +137,7 @@ TEST(PLDHashTableTest, LazyStorage) ASSERT_TRUE(false); // shouldn't hit this on an empty table } - // Using a null |mallocSizeOf| should be fine because it shouldn't be called - // for an empty table. - mozilla::MallocSizeOf mallocSizeOf = nullptr; - ASSERT_EQ(PL_DHashTableSizeOfExcludingThis(&t, nullptr, mallocSizeOf), 0u); + ASSERT_EQ(t.ShallowSizeOfExcludingThis(moz_malloc_size_of), 0u); } // A trivial hash function is good enough here. It's also super-fast for