Bug 1187144 (part 10) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=heycam.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 26 Jan 2016 22:21:30 -0800
changeset 305030 bf3bf9b99f51caa73938e25758b97f0479f6660a
parent 305029 275fc8ed3d86030d648262b662b3d0b12195221a
child 305031 94d4c49590a052241f51572203504b0d5f8f4494
push id9214
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:25:21 +0000
treeherdermozilla-aurora@8849dd1a4a79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1187144
milestone47.0a1
Bug 1187144 (part 10) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=heycam.
layout/base/RestyleTracker.cpp
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -58,89 +58,16 @@ RestyleTracker::Document() const {
 
 struct RestyleEnumerateData : RestyleTracker::Hints {
   RefPtr<dom::Element> mElement;
 #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
   UniquePtr<ProfilerBacktrace> mBacktrace;
 #endif
 };
 
-struct RestyleCollector {
-  RestyleTracker* tracker;
-  RestyleEnumerateData** restyleArrayPtr;
-#ifdef RESTYLE_LOGGING
-  uint32_t count;
-#endif
-};
-
-static PLDHashOperator
-CollectRestyles(nsISupports* aElement,
-                nsAutoPtr<RestyleTracker::RestyleData>& aData,
-                void* aRestyleCollector)
-{
-  dom::Element* element =
-    static_cast<dom::Element*>(aElement);
-  RestyleCollector* collector =
-    static_cast<RestyleCollector*>(aRestyleCollector);
-  // Only collect the entries that actually need restyling by us (and
-  // haven't, for example, already been restyled).
-  // It's important to not mess with the flags on entries not in our
-  // document.
-  if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() ||
-      !element->HasFlag(collector->tracker->RestyleBit())) {
-    LOG_RESTYLE_IF(collector->tracker, true,
-                   "skipping pending restyle %s, already restyled or no longer "
-                   "in the document", FrameTagToString(element).get());
-    return PL_DHASH_NEXT;
-  }
-
-  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
-               // Maybe we're just not reachable via the frame tree?
-               (element->GetFlattenedTreeParent() &&
-                (!element->GetFlattenedTreeParent()->GetPrimaryFrame() ||
-                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf() ||
-                 element->GetCrossShadowCurrentDoc()->GetShell()->FrameManager()
-                   ->GetDisplayContentsStyleFor(element))) ||
-               // Or not reachable due to an async reinsert we have
-               // pending?  If so, we'll have a reframe hint around.
-               // That incidentally makes it safe that we still have
-               // the bit, since any descendants that didn't get added
-               // to the roots list because we had the bits will be
-               // completely restyled in a moment.
-               (aData->mChangeHint & nsChangeHint_ReconstructFrame),
-               "Why did this not get handled while processing mRestyleRoots?");
-
-  // Unset the restyle bits now, so if they get readded later as we
-  // process we won't clobber that adding of the bit.
-  element->UnsetFlags(collector->tracker->RestyleBit() |
-                      collector->tracker->RootBit() |
-                      collector->tracker->ConditionalDescendantsBit());
-
-  RestyleEnumerateData** restyleArrayPtr = collector->restyleArrayPtr;
-  RestyleEnumerateData* currentRestyle = *restyleArrayPtr;
-  currentRestyle->mElement = element;
-  currentRestyle->mRestyleHint = aData->mRestyleHint;
-  currentRestyle->mChangeHint = aData->mChangeHint;
-  // We can move aData since we'll be clearing mPendingRestyles after
-  // we finish enumerating it.
-  currentRestyle->mRestyleHintData = Move(aData->mRestyleHintData);
-#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
-  currentRestyle->mBacktrace = Move(aData->mBacktrace);
-#endif
-
-#ifdef RESTYLE_LOGGING
-  collector->count++;
-#endif
-
-  // Increment to the next slot in the array
-  *restyleArrayPtr = currentRestyle + 1;
-
-  return PL_DHASH_NEXT;
-}
-
 inline void
 RestyleTracker::ProcessOneRestyle(Element* aElement,
                                   nsRestyleHint aRestyleHint,
                                   nsChangeHint aChangeHint,
                                   const RestyleHintData& aRestyleHintData)
 {
   NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0,
                   "Someone should have handled this before calling us");
@@ -352,32 +279,91 @@ RestyleTracker::DoProcessRestyles()
       // case of reentry from the handing of the change hint, use a
       // scratch array instead of calling out to ProcessOneRestyle while
       // enumerating the hashtable.  Use the stack if we can, otherwise
       // fall back on heap-allocation.
       nsAutoTArray<RestyleEnumerateData, RESTYLE_ARRAY_STACKSIZE> restyleArr;
       RestyleEnumerateData* restylesToProcess =
         restyleArr.AppendElements(mPendingRestyles.Count());
       if (restylesToProcess) {
-        RestyleEnumerateData* lastRestyle = restylesToProcess;
-        RestyleCollector collector = { this, &lastRestyle };
-        mPendingRestyles.Enumerate(CollectRestyles, &collector);
+        RestyleEnumerateData* restyle = restylesToProcess;
+#ifdef RESTYLE_LOGGING
+        uint32_t count = 0;
+#endif
+        for (auto iter = mPendingRestyles.Iter(); !iter.Done(); iter.Next()) {
+          auto element = static_cast<dom::Element*>(iter.Key());
+          RestyleTracker::RestyleData* data = iter.Data();
+
+          // Only collect the entries that actually need restyling by us (and
+          // haven't, for example, already been restyled).
+          // It's important to not mess with the flags on entries not in our
+          // document.
+          if (element->GetCrossShadowCurrentDoc() != Document() ||
+              !element->HasFlag(RestyleBit())) {
+            LOG_RESTYLE("skipping pending restyle %s, already restyled or no "
+                        "longer in the document",
+                        FrameTagToString(element).get());
+            continue;
+          }
+
+          NS_ASSERTION(
+            !element->HasFlag(RootBit()) ||
+            // Maybe we're just not reachable via the frame tree?
+            (element->GetFlattenedTreeParent() &&
+             (!element->GetFlattenedTreeParent()->GetPrimaryFrame() ||
+              element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf() ||
+              element->GetCrossShadowCurrentDoc()->GetShell()->FrameManager()
+                ->GetDisplayContentsStyleFor(element))) ||
+            // Or not reachable due to an async reinsert we have
+            // pending?  If so, we'll have a reframe hint around.
+            // That incidentally makes it safe that we still have
+            // the bit, since any descendants that didn't get added
+            // to the roots list because we had the bits will be
+            // completely restyled in a moment.
+            (data->mChangeHint & nsChangeHint_ReconstructFrame),
+            "Why did this not get handled while processing mRestyleRoots?");
+
+          // Unset the restyle bits now, so if they get readded later as we
+          // process we won't clobber that adding of the bit.
+          element->UnsetFlags(RestyleBit() |
+                              RootBit() |
+                              ConditionalDescendantsBit());
+
+          restyle->mElement = element;
+          restyle->mRestyleHint = data->mRestyleHint;
+          restyle->mChangeHint = data->mChangeHint;
+          // We can move data since we'll be clearing mPendingRestyles after
+          // we finish enumerating it.
+          restyle->mRestyleHintData = Move(data->mRestyleHintData);
+#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
+          restyle->mBacktrace = Move(data->mBacktrace);
+#endif
+
+#ifdef RESTYLE_LOGGING
+          count++;
+#endif
+
+          // Increment to the next slot in the array
+          restyle++;
+        }
+
+        RestyleEnumerateData* lastRestyle = restyle;
 
         // Clear the hashtable now that we don't need it anymore
         mPendingRestyles.Clear();
 
 #ifdef RESTYLE_LOGGING
         uint32_t index = 0;
 #endif
         for (RestyleEnumerateData* currentRestyle = restylesToProcess;
              currentRestyle != lastRestyle;
              ++currentRestyle) {
           LOG_RESTYLE("processing pending restyle %s at index %d/%d",
                       FrameTagToString(currentRestyle->mElement).get(),
-                      index++, collector.count);
+                      index++, count);
           LOG_RESTYLE_INDENT();
 
 #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
           Maybe<GeckoProfilerTracingRAII> profilerRAII;
           if (profiler_feature_active("restyle")) {
             profilerRAII.emplace("Paint", "Styles", Move(currentRestyle->mBacktrace));
           }
 #endif