Bug 1383977 - stylo: Measure Elements and ComputedValues. r=Manishearth. draft
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 19 Jul 2017 10:30:53 +1000
changeset 620032 7cfa346cb9b1835db718493f8cc032d39a58b7d3
parent 619581 52285ea5e54c73d3ed824544cef2ee3f195f05e6
child 640567 dd43c5bd892edac903e289d082847e940e4728af
push id71895
push usernnethercote@mozilla.com
push dateWed, 02 Aug 2017 23:51:33 +0000
reviewersManishearth
bugs1383977
milestone57.0a1
Bug 1383977 - stylo: Measure Elements and ComputedValues. r=Manishearth. The patch provides FFI access to Gecko's SeenPtrs type from Rust, in order to record what has already been measured when measuring Arcs. (The SeenPtrs must be initialized on the Gecko side because the same table is reused for measuring all Elements within a window, because Elements can share ComputedValues.) I have confirmed with DMD that this is working correctly. The patch also introduces MallocSizeOfRepeats, which is like MallocSizeOf but takes a SizeOfState, which holds a SeenPtrs table. MozReview-Commit-ID: DHS8zvCsEdQ
dom/base/Element.cpp
layout/style/ServoBindingList.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4133,18 +4133,25 @@ Element::ClearServoData() {
 void
 Element::SetCustomElementData(CustomElementData* aData)
 {
   nsExtendedDOMSlots *slots = ExtendedDOMSlots();
   MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set.");
   slots->mCustomElementData = aData;
 }
 
+MOZ_DEFINE_MALLOC_SIZE_OF(ServoElementMallocSizeOf)
+
 size_t
 Element::SizeOfExcludingThis(SizeOfState& aState) const
 {
   size_t n = FragmentOrElement::SizeOfExcludingThis(aState);
 
-  // XXX: measure mServoData.
-
+  // Measure mServoData. We use ServoElementMallocSizeOf rather than
+  // |aState.mMallocSizeOf| to distinguish in DMD's output the memory
+  // measured within Servo code.
+  if (mServoData.Get()) {
+    n += Servo_Element_SizeOfExcludingThis(ServoElementMallocSizeOf,
+                                           &aState.mSeenPtrs, this);
+  }
   return n;
 }
 
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -15,16 +15,18 @@
  *
  * Users of this list should define a macro
  * SERVO_BINDING_FUNC(name_, return_, ...)
  * before including this file.
  */
 
 // Element data
 SERVO_BINDING_FUNC(Servo_Element_ClearData, void, RawGeckoElementBorrowed node)
+SERVO_BINDING_FUNC(Servo_Element_SizeOfExcludingThis, size_t, mozilla::MallocSizeOf,
+                   mozilla::SeenPtrs* seen_ptrs, RawGeckoElementBorrowed node)
 
 // Styleset and Stylesheet management
 SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes, RawServoStyleSheetContentsStrong,
                    mozilla::css::Loader* loader,
                    mozilla::ServoStyleSheet* gecko_stylesheet,
                    const nsACString* data,
                    mozilla::css::SheetParsingMode parsing_mode,
                    RawGeckoURLExtraData* extra_data,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -51,16 +51,17 @@
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/GeckoStyleContext.h"
 #include "mozilla/Keyframe.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ServoElementSnapshot.h"
 #include "mozilla/ServoRestyleManager.h"
+#include "mozilla/SizeOfState.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/SystemGroup.h"
 #include "mozilla/ServoMediaList.h"
 #include "mozilla/RWLock.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ElementInlines.h"
 #include "mozilla/dom/HTMLTableCellElement.h"
 #include "mozilla/dom/HTMLBodyElement.h"
@@ -447,16 +448,28 @@ Gecko_GetElementSnapshot(const ServoElem
                          const Element* aElement)
 {
   MOZ_ASSERT(aTable);
   MOZ_ASSERT(aElement);
 
   return aTable->Get(const_cast<Element*>(aElement));
 }
 
+bool
+Gecko_HaveSeenPtr(SeenPtrs* aTable, const void* aPtr)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aTable);
+  // Empty Rust allocations are indicated by small values up to the alignment
+  // of the relevant type. We shouldn't see anything like that here.
+  MOZ_ASSERT(uintptr_t(aPtr) > 16);
+
+  return aTable->HaveSeenPtr(aPtr);
+}
+
 RawServoDeclarationBlockStrongBorrowedOrNull
 Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
 {
   DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
   if (!decl) {
     return nullptr;
   }
   if (decl->IsGecko()) {
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -45,16 +45,17 @@ namespace mozilla {
     struct ImageValue;
     class LoaderReusableStyleSheets;
   };
   namespace dom {
     enum class IterationCompositeOperation : uint8_t;
   };
   enum class UpdateAnimationsTasks : uint8_t;
   struct LangGroupFontPrefs;
+  class SeenPtrs;
   class ServoStyleContext;
   class ServoStyleSheet;
   class ServoElementSnapshotTable;
 }
 using mozilla::FontFamilyList;
 using mozilla::FontFamilyType;
 using mozilla::ServoElementSnapshot;
 class nsCSSCounterStyleRule;
@@ -392,16 +393,20 @@ nsChangeHint Gecko_HintsHandledForDescen
 
 // Get an element snapshot for a given element from the table.
 const ServoElementSnapshot*
 Gecko_GetElementSnapshot(const mozilla::ServoElementSnapshotTable* table,
                          RawGeckoElementBorrowed element);
 
 void Gecko_DropElementSnapshot(ServoElementSnapshotOwned snapshot);
 
+// Have we seen this pointer before?
+bool
+Gecko_HaveSeenPtr(mozilla::SeenPtrs* table, const void* ptr);
+
 // `array` must be an nsTArray
 // If changing this signature, please update the
 // friend function declaration in nsTArray.h
 void Gecko_EnsureTArrayCapacity(void* array, size_t capacity, size_t elem_size);
 
 // Same here, `array` must be an nsTArray<T>, for some T.
 //
 // Important note: Only valid for POD types, since destructors won't be run
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -60,16 +60,17 @@ headers = [
     "mozilla/dom/Element.h",
     "mozilla/dom/ChildIterator.h",
     "mozilla/dom/NameSpaceConstants.h",
     "mozilla/LookAndFeel.h",
     "mozilla/StylePrefs.h",
     "mozilla/ServoBindings.h",
     "mozilla/ServoMediaList.h",
     "mozilla/ServoStyleContext.h",
+    "mozilla/SizeOfState.h",
     "nsCSSCounterStyleRule.h",
     "nsCSSFontFaceRule.h",
     "nsMediaFeatures.h",
     "nsMediaList.h",
     "nsXBLBinding.h",
 ]
 raw-lines = [
     # FIXME(emilio): Incrementally remove these "pub use"s. Probably
@@ -118,16 +119,17 @@ whitelist-vars = [
     "kPresContext_.*",
 ]
 whitelist-types = [
     "RawGecko.*",
     "mozilla::AnimationPropertySegment",
     "mozilla::ComputedTiming",
     "mozilla::ComputedTimingFunction",
     "mozilla::ComputedTimingFunction::BeforeFlag",
+    "mozilla::SeenPtrs",
     "mozilla::ServoElementSnapshot.*",
     "mozilla::ServoStyleContext",
     "mozilla::ServoStyleSheetInner",
     "mozilla::CSSPseudoClassType",
     "mozilla::css::ErrorReporter",
     "mozilla::css::LoaderReusableStyleSheets",
     "mozilla::css::SheetParsingMode",
     "mozilla::css::URLMatchingFunction",
@@ -291,16 +293,17 @@ opaque-types = [
     "mozilla::dom::OwningNodeOrString_Value",
     "mozilla::dom::Nullable",
     "RefPtr_Proxy",
     "RefPtr_Proxy_member_function",
     "nsAutoPtr_Proxy",
     "nsAutoPtr_Proxy_member_function",
     "mozilla::detail::PointerType",
     "mozilla::Pair_Base",
+    "mozilla::SeenPtrs",
     "mozilla::SupportsWeakPtr",
     "SupportsWeakPtr",
     "mozilla::detail::WeakReference",
     "mozilla::WeakPtr",
     "nsWritingIterator_reference", "nsReadingIterator_reference",
     "nsTObserverArray",  # <- Inherits from nsAutoTObserverArray<T, 0>
     "nsTHashtable",  # <- Inheriting from inner typedefs that clang
                      #    doesn't expose properly.
@@ -397,16 +400,17 @@ structs-types = [
     "CounterStylePtr",
     "FontFamilyList",
     "FontFamilyType",
     "FontSizePrefs",
     "GeckoFontMetrics",
     "IterationCompositeOperation",
     "Keyframe",
     "PropertyValuePair",
+    "SeenPtrs",
     "ServoBundledURI",
     "ServoElementSnapshot",
     "ServoElementSnapshotTable",
     "SheetParsingMode",
     "StyleBasicShape",
     "StyleBasicShapeType",
     "StyleShapeSource",
     "StyleTransition",