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
--- 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) {