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
--- 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",