Bug 1400078 - Measure the UA cache. r=emilio.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA
cache, and so the patch removes 'Stylist' from the field names.
Example output from about:memory:
> +----1,359,608 B (00.55%) -- layout
> | +----756,488 B (00.31%) -- style-sheet-cache [2]
> | +----393,968 B (00.16%) -- servo-ua-cache
> | | +--234,496 B (00.10%) -- element-and-pseudos-maps
> | | +---59,648 B (00.02%) -- revalidation-selectors
> | | +---58,320 B (00.02%) -- invalidation-map
> | | +---30,752 B (00.01%) -- other
> | | +---10,752 B (00.00%) -- precomputed-pseudos
MozReview-Commit-ID: 8oxuJO0ojp
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -371,23 +371,16 @@ CollectWindowReports(nsGlobalWindow *aWi
REPORT_SIZE("/layout/servo-style-sets/stylist/rule-tree",
windowSizes.mLayoutServoStyleSetsStylistRuleTree,
"Memory used by rule trees within Servo style sets within a "
"window.");
aWindowTotalSizes->mLayoutServoStyleSetsStylistRuleTree +=
windowSizes.mLayoutServoStyleSetsStylistRuleTree;
- REPORT_SIZE("/layout/servo-style-sets/stylist/precomputed-pseudos",
- windowSizes.mLayoutServoStyleSetsStylistPrecomputedPseudos,
- "Memory used by precomputed pseudo-element declarations within "
- "Servo style sets within a window.");
- aWindowTotalSizes->mLayoutServoStyleSetsStylistPrecomputedPseudos +=
- windowSizes.mLayoutServoStyleSetsStylistPrecomputedPseudos;
-
REPORT_SIZE("/layout/servo-style-sets/stylist/element-and-pseudos-maps",
windowSizes.mLayoutServoStyleSetsStylistElementAndPseudosMaps,
"Memory used by element and pseudos maps within Servo style "
"sets within a window.");
aWindowTotalSizes->mLayoutServoStyleSetsStylistElementAndPseudosMaps +=
windowSizes.mLayoutServoStyleSetsStylistElementAndPseudosMaps;
REPORT_SIZE("/layout/servo-style-sets/stylist/invalidation-map",
@@ -708,17 +701,16 @@ nsWindowMemoryReporter::CollectReports(n
"This is the sum of all windows' 'layout/arenas' numbers.");
REPORT("window-objects/layout/gecko-style-sets",
windowTotalSizes.mLayoutGeckoStyleSets,
"This is the sum of all windows' 'layout/gecko-style-sets' numbers.");
REPORT("window-objects/layout/servo-style-sets",
windowTotalSizes.mLayoutServoStyleSetsStylistRuleTree +
- windowTotalSizes.mLayoutServoStyleSetsStylistPrecomputedPseudos +
windowTotalSizes.mLayoutServoStyleSetsStylistElementAndPseudosMaps +
windowTotalSizes.mLayoutServoStyleSetsStylistInvalidationMap +
windowTotalSizes.mLayoutServoStyleSetsStylistRevalidationSelectors +
windowTotalSizes.mLayoutServoStyleSetsStylistOther +
windowTotalSizes.mLayoutServoStyleSetsOther,
"This is the sum of all windows' 'layout/servo-style-sets/' numbers.");
REPORT("window-objects/layout/servo-element-data-objects",
--- a/dom/base/nsWindowSizes.h
+++ b/dom/base/nsWindowSizes.h
@@ -172,17 +172,16 @@ class nsWindowSizes
macro(DOM, mDOMEventTargetsSize) \
macro(DOM, mDOMPerformanceUserEntries) \
macro(DOM, mDOMPerformanceResourceEntries) \
macro(DOM, mDOMOtherSize) \
macro(Style, mLayoutStyleSheetsSize) \
macro(Other, mLayoutPresShellSize) \
macro(Style, mLayoutGeckoStyleSets) \
macro(Style, mLayoutServoStyleSetsStylistRuleTree) \
- macro(Style, mLayoutServoStyleSetsStylistPrecomputedPseudos) \
macro(Style, mLayoutServoStyleSetsStylistElementAndPseudosMaps) \
macro(Style, mLayoutServoStyleSetsStylistInvalidationMap) \
macro(Style, mLayoutServoStyleSetsStylistRevalidationSelectors) \
macro(Style, mLayoutServoStyleSetsStylistOther) \
macro(Style, mLayoutServoStyleSetsOther) \
macro(Style, mLayoutServoElementDataObjects) \
macro(Other, mLayoutTextRunsSize) \
macro(Other, mLayoutPresContextSize) \
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -124,16 +124,20 @@ SERVO_BINDING_FUNC(Servo_StyleSet_Resolv
RawServoStyleSetBorrowed set,
ServoStyleContextBorrowedOrNull parent_style,
RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_StyleSet_AddSizeOfExcludingThis, void,
mozilla::MallocSizeOf malloc_size_of,
mozilla::MallocSizeOf malloc_enclosing_size_of,
mozilla::ServoStyleSetSizes* sizes,
RawServoStyleSetBorrowed set)
+SERVO_BINDING_FUNC(Servo_UACache_AddSizeOf, void,
+ mozilla::MallocSizeOf malloc_size_of,
+ mozilla::MallocSizeOf malloc_enclosing_size_of,
+ mozilla::ServoStyleSetSizes* sizes)
SERVO_BINDING_FUNC(Servo_StyleContext_AddRef, void, ServoStyleContextBorrowed ctx);
SERVO_BINDING_FUNC(Servo_StyleContext_Release, void, ServoStyleContextBorrowed ctx);
SERVO_BINDING_FUNC(Servo_StyleSet_MightHaveAttributeDependency, bool,
RawServoStyleSetBorrowed set,
RawGeckoElementBorrowed element,
nsIAtom* local_name)
SERVO_BINDING_FUNC(Servo_StyleSet_HasStateDependency, bool,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -2437,34 +2437,41 @@ Gecko_XBLBinding_GetRawServoStyleSet(Raw
}
bool
Gecko_XBLBinding_InheritsStyle(RawGeckoXBLBindingBorrowed aXBLBinding)
{
return aXBLBinding->InheritsStyle();
}
+static StaticRefPtr<UACacheReporter> gUACacheReporter;
+
void
InitializeServo()
{
URLExtraData::InitDummy();
Servo_Initialize(URLExtraData::Dummy());
+ gUACacheReporter = new UACacheReporter();
+ RegisterWeakMemoryReporter(gUACacheReporter);
+
sServoFontMetricsLock = new Mutex("Gecko_GetFontMetrics");
sServoWidgetLock = new Mutex("Servo::WidgetLock");
sServoLangFontPrefsLock = new RWLock("nsPresContext::GetDefaultFont");
}
void
ShutdownServo()
{
MOZ_ASSERT(sServoFontMetricsLock);
MOZ_ASSERT(sServoWidgetLock);
MOZ_ASSERT(sServoLangFontPrefsLock);
+ UnregisterWeakMemoryReporter(gUACacheReporter);
+
delete sServoFontMetricsLock;
delete sServoWidgetLock;
delete sServoLangFontPrefsLock;
Servo_Shutdown();
}
namespace mozilla {
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -5,26 +5,27 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoStyleSet.h"
#include "gfxPlatformFontList.h"
#include "mozilla/AutoRestyleTimelineMarker.h"
#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/LookAndFeel.h"
+#include "mozilla/RestyleManagerInlines.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/ServoStyleRuleMap.h"
+#include "mozilla/ServoTypes.h"
#include "mozilla/css/Loader.h"
#include "mozilla/dom/AnonymousContent.h"
#include "mozilla/dom/ChildIterator.h"
#include "mozilla/dom/FontFaceSet.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ElementInlines.h"
-#include "mozilla/RestyleManagerInlines.h"
#include "nsCSSAnonBoxes.h"
#include "nsCSSFrameConstructor.h"
#include "nsCSSPseudoElements.h"
#include "nsCSSRuleProcessor.h"
#include "nsDeviceContext.h"
#include "nsHTMLStyleSheet.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIDocumentInlines.h"
@@ -262,30 +263,29 @@ ServoStyleSet::AddSizeOfIncludingThis(ns
aSizes.mLayoutServoStyleSetsOther += mallocSizeOf(mRawSet.get());
ServoStyleSetSizes sizes;
// Measure mRawSet. We use ServoStyleSetMallocSizeOf rather than
// aMallocSizeOf to distinguish in DMD's output the memory measured within
// Servo code.
Servo_StyleSet_AddSizeOfExcludingThis(ServoStyleSetMallocSizeOf,
ServoStyleSetMallocEnclosingSizeOf,
&sizes, mRawSet.get());
- aSizes.mLayoutServoStyleSetsStylistRuleTree +=
- sizes.mStylistRuleTree;
- aSizes.mLayoutServoStyleSetsStylistPrecomputedPseudos +=
- sizes.mStylistPrecomputedPseudos;
+
+ // The StyleSet does not contain precomputed pseudos; they are in the UA
+ // cache.
+ MOZ_RELEASE_ASSERT(sizes.mPrecomputedPseudos == 0);
+
+ aSizes.mLayoutServoStyleSetsStylistRuleTree += sizes.mRuleTree;
aSizes.mLayoutServoStyleSetsStylistElementAndPseudosMaps +=
- sizes.mStylistElementAndPseudosMaps;
+ sizes.mElementAndPseudosMaps;
aSizes.mLayoutServoStyleSetsStylistInvalidationMap +=
- sizes.mStylistInvalidationMap;
+ sizes.mInvalidationMap;
aSizes.mLayoutServoStyleSetsStylistRevalidationSelectors +=
- sizes.mStylistRevalidationSelectors;
- aSizes.mLayoutServoStyleSetsStylistOther +=
- sizes.mStylistOther;
- aSizes.mLayoutServoStyleSetsOther +=
- sizes.mOther;
+ sizes.mRevalidationSelectors;
+ aSizes.mLayoutServoStyleSetsStylistOther += sizes.mOther;
}
if (mStyleRuleMap) {
aSizes.mLayoutServoStyleSetsOther +=
mStyleRuleMap->SizeOfIncludingThis(aSizes.mState.mMallocSizeOf);
}
// Measurement of the following members may be added later if DMD finds it is
@@ -1528,8 +1528,57 @@ ServoStyleSet::ReparentStyleContext(Serv
ServoStyleContext* aNewParentIgnoringFirstLine,
ServoStyleContext* aNewLayoutParent,
Element* aElement)
{
return Servo_ReparentStyle(aStyleContext, aNewParent,
aNewParentIgnoringFirstLine, aNewLayoutParent,
aElement, mRawSet.get()).Consume();
}
+
+NS_IMPL_ISUPPORTS(UACacheReporter, nsIMemoryReporter)
+
+MOZ_DEFINE_MALLOC_SIZE_OF(ServoUACacheMallocSizeOf)
+MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoUACacheMallocEnclosingSizeOf)
+
+NS_IMETHODIMP
+UACacheReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, bool aAnonymize)
+{
+ ServoStyleSetSizes sizes;
+ Servo_UACache_AddSizeOf(ServoUACacheMallocSizeOf,
+ ServoUACacheMallocEnclosingSizeOf, &sizes);
+
+#define REPORT(_path, _amount, _desc) \
+ do { \
+ size_t __amount = _amount; /* evaluate _amount only once */ \
+ if (__amount > 0) { \
+ MOZ_COLLECT_REPORT(_path, KIND_HEAP, UNITS_BYTES, __amount, _desc); \
+ } \
+ } while (0)
+
+ // The UA cache does not contain the rule tree; that's in the StyleSet.
+ MOZ_RELEASE_ASSERT(sizes.mRuleTree == 0);
+
+ REPORT("explicit/layout/servo-ua-cache/precomputed-pseudos",
+ sizes.mPrecomputedPseudos,
+ "Memory used by precomputed pseudo-element declarations within the "
+ "UA cache.");
+
+ REPORT("explicit/layout/servo-ua-cache/element-and-pseudos-maps",
+ sizes.mElementAndPseudosMaps,
+ "Memory used by element and pseudos maps within the UA cache.");
+
+ REPORT("explicit/layout/servo-ua-cache/invalidation-map",
+ sizes.mInvalidationMap,
+ "Memory used by invalidation maps within the UA cache.");
+
+ REPORT("explicit/layout/servo-ua-cache/revalidation-selectors",
+ sizes.mRevalidationSelectors,
+ "Memory used by selectors for cache revalidation within the UA "
+ "cache.");
+
+ REPORT("explicit/layout/servo-ua-cache/other",
+ sizes.mOther,
+ "Memory used by other data within the UA cache");
+
+ return NS_OK;
+}
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -17,16 +17,17 @@
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/SheetType.h"
#include "mozilla/UniquePtr.h"
#include "MainThreadUtils.h"
#include "nsCSSPseudoElements.h"
#include "nsCSSAnonBoxes.h"
#include "nsChangeHint.h"
#include "nsIAtom.h"
+#include "nsIMemoryReporter.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
class CSSStyleSheet;
class ServoRestyleManager;
@@ -609,11 +610,20 @@ private:
RefPtr<ServoStyleRuleMap> mStyleRuleMap;
// This can be null if we are used to hold XBL style sheets.
RefPtr<nsBindingManager> mBindingManager;
static ServoStyleSet* sInServoTraversal;
};
+class UACacheReporter final : public nsIMemoryReporter
+{
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMEMORYREPORTER
+
+private:
+ ~UACacheReporter() {}
+};
+
} // namespace mozilla
#endif // mozilla_ServoStyleSet_h
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -194,34 +194,34 @@ struct ServoComputedValueFlags {
};
#define STYLE_STRUCT(name_, checkdata_cb_) struct Gecko##name_;
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
+// These measurements are obtained for both the UA cache and the Stylist, but
+// not all the fields are used in both cases.
class ServoStyleSetSizes
{
public:
- size_t mStylistRuleTree;
- size_t mStylistPrecomputedPseudos;
- size_t mStylistElementAndPseudosMaps;
- size_t mStylistInvalidationMap;
- size_t mStylistRevalidationSelectors;
- size_t mStylistOther;
- size_t mOther;
+ size_t mRuleTree; // Stylist-only
+ size_t mPrecomputedPseudos; // UA cache-only
+ size_t mElementAndPseudosMaps; // Used for both
+ size_t mInvalidationMap; // Used for both
+ size_t mRevalidationSelectors; // Used for both
+ size_t mOther; // Used for both
ServoStyleSetSizes()
- : mStylistRuleTree(0)
- , mStylistPrecomputedPseudos(0)
- , mStylistElementAndPseudosMaps(0)
- , mStylistInvalidationMap(0)
- , mStylistRevalidationSelectors(0)
- , mStylistOther(0)
+ : mRuleTree(0)
+ , mPrecomputedPseudos(0)
+ , mElementAndPseudosMaps(0)
+ , mInvalidationMap(0)
+ , mRevalidationSelectors(0)
, mOther(0)
{}
};
} // namespace mozilla
class ServoComputedData;