Bug 1385538 - Avoid dynamic memory allocation for EditorBase::mSelState; r=masayuki
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 29 Jul 2017 02:43:39 -0400
changeset 420844 30a16b6553d79eb6ecc3a91bfdc6fb4ffc3f4f54
parent 420843 dfb4439aa194de33421b2ebfc0b71238b975c2d5
child 420845 3377c3b7a86da2a6bcd8644b7cd4805fc2bfa22e
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1385538
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1385538 - Avoid dynamic memory allocation for EditorBase::mSelState; r=masayuki
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/PlaceholderTransaction.cpp
editor/libeditor/PlaceholderTransaction.h
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -123,17 +123,16 @@ using namespace dom;
 using namespace widget;
 
 /*****************************************************************************
  * mozilla::EditorBase
  *****************************************************************************/
 
 EditorBase::EditorBase()
   : mPlaceholderName(nullptr)
-  , mSelState(nullptr)
   , mModCount(0)
   , mFlags(0)
   , mUpdateCount(0)
   , mPlaceholderBatch(0)
   , mAction(EditAction::none)
   , mIMETextOffset(0)
   , mIMETextLength(0)
   , mDirection(eNone)
@@ -969,17 +968,17 @@ EditorBase::BeginPlaceHolderTransaction(
   if (!mPlaceholderBatch) {
     NotifyEditorObservers(eNotifyEditorObserversOfBefore);
     // time to turn on the batch
     BeginUpdateViewBatch();
     mPlaceholderTransaction = nullptr;
     mPlaceholderName = aName;
     RefPtr<Selection> selection = GetSelection();
     if (selection) {
-      mSelState = MakeUnique<SelectionState>();
+      mSelState.emplace();
       mSelState->SaveSelection(selection);
       // Composition transaction can modify multiple nodes and it merges text
       // node for ime into single text node.
       // So if current selection is into IME text node, it might be failed
       // to restore selection by UndoTransaction.
       // So we need update selection by range updater.
       if (mPlaceholderName == nsGkAtoms::IMETxnName) {
         mRangeUpdater.RegisterSelectionState(*mSelState);
@@ -1034,17 +1033,17 @@ EditorBase::EndPlaceHolderTransaction()
     }
 
     if (mSelState) {
       // we saved the selection state, but never got to hand it to placeholder
       // (else we ould have nulled out this pointer), so destroy it to prevent leaks.
       if (mPlaceholderName == nsGkAtoms::IMETxnName) {
         mRangeUpdater.DropSelectionState(*mSelState);
       }
-      mSelState = nullptr;
+      mSelState.reset();
     }
     // We might have never made a placeholder if no action took place.
     if (mPlaceholderTransaction) {
       mPlaceholderTransaction->EndPlaceHolderBatch();
       // notify editor observers of action but if composing, it's done by
       // compositionchange event handler.
       if (!mComposition) {
         NotifyEditorObservers(eNotifyEditorObserversOfEnd);
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -2,20 +2,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_EditorBase_h
 #define mozilla_EditorBase_h
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc.
+#include "mozilla/Maybe.h"              // for Maybe
 #include "mozilla/OwningNonNull.h"      // for OwningNonNull
 #include "mozilla/SelectionState.h"     // for RangeUpdater, etc.
 #include "mozilla/StyleSheet.h"         // for StyleSheet
-#include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"            // for WeakPtr
 #include "mozilla/dom/Text.h"
 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIEditor.h"                  // for nsIEditor, etc.
 #include "nsIObserver.h"                // for NS_DECL_NSIOBSERVER, etc.
@@ -1128,17 +1128,17 @@ protected:
   // The form field as an event receiver.
   nsCOMPtr<dom::EventTarget> mEventTarget;
   nsCOMPtr<nsIDOMEventListener> mEventListener;
   // Strong reference to placeholder for begin/end batch purposes.
   RefPtr<PlaceholderTransaction> mPlaceholderTransaction;
   // Name of placeholder transaction.
   nsIAtom* mPlaceholderName;
   // Saved selection state for placeholder transaction batching.
-  mozilla::UniquePtr<SelectionState> mSelState;
+  mozilla::Maybe<SelectionState> mSelState;
   // IME composition this is not null between compositionstart and
   // compositionend.
   RefPtr<TextComposition> mComposition;
 
   // Listens to all low level actions on the doc.
   typedef AutoTArray<OwningNonNull<nsIEditActionListener>, 5>
             AutoActionListenerArray;
   AutoActionListenerArray mActionListeners;
--- a/editor/libeditor/PlaceholderTransaction.cpp
+++ b/editor/libeditor/PlaceholderTransaction.cpp
@@ -14,48 +14,44 @@
 
 namespace mozilla {
 
 using namespace dom;
 
 PlaceholderTransaction::PlaceholderTransaction(
                           EditorBase& aEditorBase,
                           nsIAtom* aName,
-                          UniquePtr<SelectionState> aSelState)
+                          Maybe<SelectionState>&& aSelState)
   : mAbsorb(true)
   , mForwarding(nullptr)
   , mCompositionTransaction(nullptr)
   , mCommitted(false)
-  , mStartSel(Move(aSelState))
+  , mStartSel(Move(*aSelState))
   , mEditorBase(&aEditorBase)
 {
   mName = aName;
 }
 
 PlaceholderTransaction::~PlaceholderTransaction()
 {
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(PlaceholderTransaction)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PlaceholderTransaction,
                                                 EditAggregateTransaction)
-  if (tmp->mStartSel) {
-    ImplCycleCollectionUnlink(*tmp->mStartSel);
-  }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorBase);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mStartSel);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mEndSel);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PlaceholderTransaction,
                                                   EditAggregateTransaction)
-  if (tmp->mStartSel) {
-    ImplCycleCollectionTraverse(cb, *tmp->mStartSel, "mStartSel", 0);
-  }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorBase);
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStartSel);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEndSel);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PlaceholderTransaction)
   NS_INTERFACE_MAP_ENTRY(nsIAbsorbingTransaction)
 NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction)
 
 NS_IMPL_ADDREF_INHERITED(PlaceholderTransaction, EditAggregateTransaction)
@@ -73,22 +69,20 @@ PlaceholderTransaction::UndoTransaction(
   if (NS_WARN_IF(!mEditorBase)) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   // Undo transactions.
   nsresult rv = EditAggregateTransaction::UndoTransaction();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  NS_ENSURE_TRUE(mStartSel, NS_ERROR_NULL_POINTER);
-
   // now restore selection
   RefPtr<Selection> selection = mEditorBase->GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-  return mStartSel->RestoreSelection(selection);
+  return mStartSel.RestoreSelection(selection);
 }
 
 NS_IMETHODIMP
 PlaceholderTransaction::RedoTransaction()
 {
   if (NS_WARN_IF(!mEditorBase)) {
     return NS_ERROR_NOT_INITIALIZED;
   }
@@ -217,21 +211,21 @@ PlaceholderTransaction::GetTxnName(nsIAt
 
 NS_IMETHODIMP
 PlaceholderTransaction::StartSelectionEquals(SelectionState* aSelState,
                                              bool* aResult)
 {
   // determine if starting selection matches the given selection state.
   // note that we only care about collapsed selections.
   NS_ENSURE_TRUE(aResult && aSelState, NS_ERROR_NULL_POINTER);
-  if (!mStartSel->IsCollapsed() || !aSelState->IsCollapsed()) {
+  if (!mStartSel.IsCollapsed() || !aSelState->IsCollapsed()) {
     *aResult = false;
     return NS_OK;
   }
-  *aResult = mStartSel->IsEqual(aSelState);
+  *aResult = mStartSel.IsEqual(aSelState);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PlaceholderTransaction::EndPlaceHolderBatch()
 {
   mAbsorb = false;
 
--- a/editor/libeditor/PlaceholderTransaction.h
+++ b/editor/libeditor/PlaceholderTransaction.h
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PlaceholderTransaction_h
 #define PlaceholderTransaction_h
 
 #include "EditAggregateTransaction.h"
 #include "mozilla/EditorUtils.h"
-#include "mozilla/UniquePtr.h"
+#include "mozilla/Maybe.h"
 #include "nsIAbsorbingTransaction.h"
 #include "nsIDOMNode.h"
 #include "nsCOMPtr.h"
 #include "nsWeakPtr.h"
 
 namespace mozilla {
 
 class CompositionTransaction;
@@ -28,17 +28,17 @@ class CompositionTransaction;
 class PlaceholderTransaction final
  : public EditAggregateTransaction
  , public nsIAbsorbingTransaction
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   PlaceholderTransaction(EditorBase& aEditorBase, nsIAtom* aName,
-                         UniquePtr<SelectionState> aSelState);
+                         Maybe<SelectionState>&& aSelState);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction,
                                            EditAggregateTransaction)
 // ------------ EditAggregateTransaction -----------------------
 
   NS_DECL_EDITTRANSACTIONBASE
 
   NS_IMETHOD RedoTransaction() override;
@@ -76,18 +76,17 @@ protected:
   // Do we stop auto absorbing any matching placeholder transactions?
   bool mCommitted;
 
   // These next two members store the state of the selection in a safe way.
   // Selection at the start of the transaction is stored, as is the selection
   // at the end.  This is so that UndoTransaction() and RedoTransaction() can
   // restore the selection properly.
 
-  // Use a pointer because this is constructed before we exist.
-  UniquePtr<SelectionState> mStartSel;
+  SelectionState mStartSel;
   SelectionState mEndSel;
 
   // The editor for this transaction.
   RefPtr<EditorBase> mEditorBase;
 };
 
 } // namespace mozilla