Bug 1371492 - Use AutoTArray to save current listener in NotifySelectionListeners. r?mats draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 09 Jun 2017 13:15:49 +0900
changeset 591524 b2d261a7d2fbee250e2b083b01bea9ae5cbb127e
parent 591406 f4262773c4331d4ae139be536ce278ea9aad3436
child 632532 3cbb0383fb3426cc01a65889541c64420d66a177
push id63074
push userbmo:m_kato@ga2.so-net.ne.jp
push dateFri, 09 Jun 2017 04:58:05 +0000
reviewersmats
bugs1371492
milestone55.0a1
Bug 1371492 - Use AutoTArray to save current listener in NotifySelectionListeners. r?mats Actually, we use nsCOMArray for mSelectionListeners. NotifySelectionListeners saves current listeners to another nsCOMArray then use it for observing. When I debug it, array length is mostly ~5, and nsCOMArray uses malloc according to profiler. So since array length is small, we should use AutoTArray instead. MozReview-Commit-ID: As5PS1KVTt8
layout/generic/Selection.h
layout/generic/nsSelection.cpp
--- a/layout/generic/Selection.h
+++ b/layout/generic/Selection.h
@@ -432,17 +432,17 @@ private:
   // proves to be a performance concern, then an interval tree may be a
   // possible solution, allowing the calculation of the overlap interval in
   // O(log n) time, though this would require rebalancing and other overhead.
   nsTArray<RangeData> mRanges;
 
   RefPtr<nsRange> mAnchorFocusRange;
   RefPtr<nsFrameSelection> mFrameSelection;
   RefPtr<nsAutoScrollTimer> mAutoScrollTimer;
-  nsCOMArray<nsISelectionListener> mSelectionListeners;
+  FallibleTArray<nsCOMPtr<nsISelectionListener>> mSelectionListeners;
   nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
   CachedOffsetForFrame* mCachedOffsetForFrame;
   nsDirection mDirection;
   SelectionType mSelectionType;
   UniquePtr<SelectionCustomColors> mCustomColors;
 
   /**
    * True if the current selection operation was initiated by user action.
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -18,17 +18,16 @@
 #include "nsString.h"
 #include "nsFrameSelection.h"
 #include "nsISelectionListener.h"
 #include "nsContentCID.h"
 #include "nsDeviceContext.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsRange.h"
-#include "nsCOMArray.h"
 #include "nsITableCellLayout.h"
 #include "nsTArray.h"
 #include "nsTableWrapperFrame.h"
 #include "nsTableCellFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsIContentIterator.h"
 #include "nsIDocumentEncoder.h"
@@ -6360,17 +6359,17 @@ Selection::AddSelectionListener(nsISelec
   }
   return NS_OK;
 }
 
 void
 Selection::AddSelectionListener(nsISelectionListener* aNewListener,
                                 ErrorResult& aRv)
 {
-  bool result = mSelectionListeners.AppendObject(aNewListener); // AddRefs
+  bool result = mSelectionListeners.AppendElement(aNewListener, fallible); // AddRefs
   if (!result) {
     aRv.Throw(NS_ERROR_FAILURE);
   }
 }
 
 NS_IMETHODIMP
 Selection::RemoveSelectionListener(nsISelectionListener* aListenerToRemove)
 {
@@ -6383,17 +6382,17 @@ Selection::RemoveSelectionListener(nsISe
   }
   return NS_OK;
 }
 
 void
 Selection::RemoveSelectionListener(nsISelectionListener* aListenerToRemove,
                                    ErrorResult& aRv)
 {
-  bool result = mSelectionListeners.RemoveObject(aListenerToRemove); // Releases
+  bool result = mSelectionListeners.RemoveElement(aListenerToRemove); // Releases
   if (!result) {
     aRv.Throw(NS_ERROR_FAILURE);
   }
 }
 
 Element*
 Selection::GetCommonEditingHostForAllRanges()
 {
@@ -6485,31 +6484,28 @@ Selection::NotifySelectionListeners()
     }
   }
 
   RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
   if (frameSelection->GetBatching()) {
     frameSelection->SetDirty();
     return NS_OK;
   }
-  nsCOMArray<nsISelectionListener> selectionListeners(mSelectionListeners);
-  int32_t cnt = selectionListeners.Count();
-  if (cnt != mSelectionListeners.Count()) {
-    return NS_ERROR_OUT_OF_MEMORY;  // nsCOMArray is fallible
-  }
+  AutoTArray<nsCOMPtr<nsISelectionListener>, 8>
+    selectionListeners(mSelectionListeners);
 
   nsCOMPtr<nsIDOMDocument> domdoc;
   nsIPresShell* ps = GetPresShell();
   if (ps) {
     domdoc = do_QueryInterface(ps->GetDocument());
   }
 
   short reason = frameSelection->PopReason();
-  for (int32_t i = 0; i < cnt; i++) {
-    selectionListeners[i]->NotifySelectionChanged(domdoc, this, reason);
+  for (auto& listener : selectionListeners) {
+    listener->NotifySelectionChanged(domdoc, this, reason);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Selection::StartBatchChanges()
 {
   if (mFrameSelection) {