Bug 1473634: Part 3 - Update nsDOMComputedStyle to use RegisterCallbacks. r?bz draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 04 Jul 2018 19:07:28 -0700
changeset 818470 351755c737cad4ee98ca89539c2513e550ac4e0b
parent 818469 a2575f9b76212fc713c00df90049a727dfbf051f
child 818471 9f9fc4ec95cfdb86d7b038188caaeceed01da1c6
push id116268
push usermaglione.k@gmail.com
push dateSat, 14 Jul 2018 02:10:15 +0000
reviewersbz
bugs1473634
milestone63.0a1
Bug 1473634: Part 3 - Update nsDOMComputedStyle to use RegisterCallbacks. r?bz nsComputedDOMStyle is currently one of the biggest sources of pref callback memory overhead. It currently registers about 5KB of callbacks per process. A lot of that has to do with it registering multiple callbacks for the same preference. But even with that problem fixed, we can do better by registering a single callback for all observed preferences. This patch does that, but also adds the optimization of deduplicating the list of observed preferences to avoid wasted cycles needlessly matching against many identical strings. MozReview-Commit-ID: LZNgd7cAwo2
layout/style/nsComputedDOMStyle.cpp
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -7,16 +7,17 @@
 /* DOM object returned from element.getComputedStyle() */
 
 #include "nsComputedDOMStyle.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/FontPropertyTypes.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/StaticPtr.h"
 
 #include "nsError.h"
 #include "nsIFrame.h"
 #include "nsIFrameInlines.h"
 #include "mozilla/ComputedStyle.h"
 #include "nsIScrollableFrame.h"
 #include "nsContentUtils.h"
 #include "nsIContent.h"
@@ -5487,34 +5488,47 @@ nsComputedDOMStyle::ParentChainChanged(n
 
 /* static */ ComputedStyleMap*
 nsComputedDOMStyle::GetComputedStyleMap()
 {
   static ComputedStyleMap map{};
   return &map;
 }
 
+static StaticAutoPtr<nsTArray<const char*>> gCallbackPrefs;
+
 /* static */ void
 nsComputedDOMStyle::RegisterPrefChangeCallbacks()
 {
   // Note that this will register callbacks for all properties with prefs, not
   // just those that are implemented on computed style objects, as it's not
   // easy to grab specific property data from ServoCSSPropList.h based on the
   // entries iterated in nsComputedDOMStylePropertyList.h.
-  ComputedStyleMap* data = GetComputedStyleMap();
+
+  AutoTArray<const char*, 64> prefs;
   for (const auto* p = nsCSSProps::kPropertyPrefTable;
        p->mPropID != eCSSProperty_UNKNOWN; p++) {
-    nsCString name;
-    name.AssignLiteral(p->mPref, strlen(p->mPref));
-    Preferences::RegisterCallback(MarkComputedStyleMapDirty, name, data);
-  }
+    // Many properties are controlled by the same preference, so de-duplicate
+    // them before adding observers.
+    if (!prefs.ContainsSorted(p->mPref)) {
+      prefs.InsertElementSorted(p->mPref);
+    }
+  }
+  prefs.AppendElement(nullptr);
+
+  MOZ_ASSERT(!gCallbackPrefs);
+  gCallbackPrefs = new nsTArray<const char*>(std::move(prefs));
+
+  Preferences::RegisterCallbacks(MarkComputedStyleMapDirty,
+                                 gCallbackPrefs->Elements(),
+                                 GetComputedStyleMap());
 }
 
 /* static */ void
 nsComputedDOMStyle::UnregisterPrefChangeCallbacks()
 {
-  ComputedStyleMap* data = GetComputedStyleMap();
-  for (const auto* p = nsCSSProps::kPropertyPrefTable;
-       p->mPropID != eCSSProperty_UNKNOWN; p++) {
-    Preferences::UnregisterCallback(MarkComputedStyleMapDirty,
-                                    nsDependentCString(p->mPref), data);
-  }
-}
+  MOZ_ASSERT(gCallbackPrefs);
+
+  Preferences::UnregisterCallbacks(MarkComputedStyleMapDirty,
+                                   gCallbackPrefs->Elements(),
+                                   GetComputedStyleMap());
+  gCallbackPrefs = nullptr;
+}