commit 8ca067765f0d78cb542e121bfb1a52718ec83458
parent 9868f6c13635c8311585f6adc3e82d9bf4d0f71e
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Mon, 1 Dec 2025 15:43:46 +0000
Bug 2003227 - Use unordered removal in StyleSheetInner. r=tlouw
The list of shared sheets is not order-dependent, neither is the
StyleSet set, so in order to avoid pathological performance with lots of
shared sheets, use unordered removal.
Differential Revision: https://phabricator.services.mozilla.com/D274597
Diffstat:
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/layout/style/StyleSheet.cpp b/layout/style/StyleSheet.cpp
@@ -407,7 +407,7 @@ void StyleSheetInfo::RemoveSheet(StyleSheet* aSheet) {
return;
}
- mSheets.RemoveElement(aSheet);
+ mSheets.UnorderedRemoveElement(aSheet);
}
void StyleSheet::GetType(nsAString& aType) { aType.AssignLiteral("text/css"); }
@@ -454,7 +454,7 @@ void StyleSheet::AddStyleSet(ServoStyleSet* aStyleSet) {
}
void StyleSheet::DropStyleSet(ServoStyleSet* aStyleSet) {
- bool found = mStyleSets.RemoveElement(aStyleSet);
+ bool found = mStyleSets.UnorderedRemoveElement(aStyleSet);
MOZ_DIAGNOSTIC_ASSERT(found, "didn't find style set");
#ifndef MOZ_DIAGNOSTIC_ASSERT_ENABLED
(void)found;
@@ -467,7 +467,7 @@ void StyleSheet::DropStyleSet(ServoStyleSet* aStyleSet) {
do { \
StyleSheet* current = this; \
do { \
- for (ServoStyleSet * set : current->mStyleSets) { \
+ for (ServoStyleSet* set : current->mStyleSets) { \
set->function_ args_; \
} \
if (auto* docOrShadow = current->mDocumentOrShadowRoot) { \
diff --git a/xpcom/ds/nsTArray.h b/xpcom/ds/nsTArray.h
@@ -1845,7 +1845,6 @@ class nsTArray_Impl
if (i == NoIndex) {
return false;
}
-
RemoveElementsAtUnsafe(i, 1);
return true;
}
@@ -1857,6 +1856,23 @@ class nsTArray_Impl
return RemoveElement(aItem, nsDefaultComparator<value_type, Item>());
}
+ // Variations for RemoveElement that uses unordered removal.
+ template <class Item, class Comparator>
+ bool UnorderedRemoveElement(const Item& aItem, const Comparator& aComp) {
+ index_type i = IndexOf(aItem, 0, aComp);
+ if (i == NoIndex) {
+ return false;
+ }
+ UnorderedRemoveElementAt(i);
+ return true;
+ }
+
+ template <class Item>
+ bool UnorderedRemoveElement(const Item& aItem) {
+ return UnorderedRemoveElement(aItem,
+ nsDefaultComparator<value_type, Item>());
+ }
+
// This helper function combines IndexOfFirstElementGt with
// RemoveElementAt to "search and destroy" the last element that
// is equal to the given element.