Bug 1338443 Part 2 - Convert nsAutoFloatManager::mNew to use UniquePtr. draft
authorTing-Yu Lin <tlin@mozilla.com>
Thu, 09 Feb 2017 17:57:16 +0800
changeset 482552 e5b26487e2a54ef54e6826366de810edbdca2650
parent 482551 dd1f194882b2e565b87cca7c74533d00482c94d0
child 545454 e173431b316cb3ef70ba31fc80a2e85b41585d60
push id45107
push userbmo:tlin@mozilla.com
push dateMon, 13 Feb 2017 05:30:58 +0000
bugs1338443
milestone54.0a1
Bug 1338443 Part 2 - Convert nsAutoFloatManager::mNew to use UniquePtr. The life cycle of nsFloatManager managed by mNew is same as nsAutoFloatManager, which lives only in nsBlockFrame::Reflow(). Therefore, other nsFloatManager pointers are all non-owning ref to the nsAutoFloatManager::mNew. MozReview-Commit-ID: B34BOcsjE2X
layout/generic/ReflowInput.h
layout/generic/nsFloatManager.cpp
layout/generic/nsFloatManager.h
layout/generic/nsLineLayout.h
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -332,17 +332,18 @@ protected:
  *
  * @see nsIFrame#Reflow()
  */
 struct ReflowInput : public SizeComputationInput {
   // the reflow states are linked together. this is the pointer to the
   // parent's reflow state
   const ReflowInput* mParentReflowInput;
 
-  // pointer to the float manager associated with this area
+  // A non-owning pointer to the float manager associated with this area,
+  // which points to the object owned by nsAutoFloatManager::mNew.
   nsFloatManager* mFloatManager;
 
   // LineLayout object (only for inline reflow; set to nullptr otherwise)
   nsLineLayout*    mLineLayout;
 
   // The appropriate reflow state for the containing block (for
   // percentage widths, etc.) of this reflow state's frame.
   MOZ_INIT_OUTSIDE_CTOR
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -974,33 +974,33 @@ nsAutoFloatManager::~nsAutoFloatManager(
     if (nsBlockFrame::gNoisyFloatManager) {
       if (mOld) {
         mReflowInput.mFrame->ListTag(stdout);
         printf(": float manager %p after reflow\n", mOld);
         mOld->List(stdout);
       }
     }
 #endif
-
-    delete mNew;
   }
 }
 
 void
 nsAutoFloatManager::CreateFloatManager(nsPresContext *aPresContext)
 {
+  MOZ_ASSERT(!mNew, "Redundant call to CreateFloatManager!");
+
   // Create a new float manager and install it in the reflow
   // input. `Remember' the old float manager so we can restore it
   // later.
-  mNew = new nsFloatManager(aPresContext->PresShell(),
-                            mReflowInput.GetWritingMode());
+  mNew = MakeUnique<nsFloatManager>(aPresContext->PresShell(),
+                                    mReflowInput.GetWritingMode());
 
 #ifdef DEBUG
   if (nsBlockFrame::gNoisyFloatManager) {
     printf("constructed new float manager %p (replacing %p)\n",
-           mNew, mReflowInput.mFloatManager);
+           mNew.get(), mReflowInput.mFloatManager);
   }
 #endif
 
   // Set the float manager in the existing reflow input.
   mOld = mReflowInput.mFloatManager;
-  mReflowInput.mFloatManager = mNew;
+  mReflowInput.mFloatManager = mNew.get();
 }
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -544,29 +544,32 @@ private:
  * nsBlockFrame::Reflow. It automatically restores the old float
  * manager in the reflow input when the object goes out of scope.
  */
 class nsAutoFloatManager {
   using ReflowInput = mozilla::ReflowInput;
 
 public:
   explicit nsAutoFloatManager(ReflowInput& aReflowInput)
-    : mReflowInput(aReflowInput),
-      mNew(nullptr),
-      mOld(nullptr) {}
+    : mReflowInput(aReflowInput)
+    , mOld(nullptr)
+  {}
 
   ~nsAutoFloatManager();
 
   /**
    * Create a new float manager for the specified frame. This will
    * `remember' the old float manager, and install the new float
    * manager in the reflow input.
    */
   void
   CreateFloatManager(nsPresContext *aPresContext);
 
 protected:
   ReflowInput &mReflowInput;
-  nsFloatManager *mNew;
-  nsFloatManager *mOld;
+  mozilla::UniquePtr<nsFloatManager> mNew;
+
+ // A non-owning pointer, which points to the object owned by
+ // nsAutoFloatManager::mNew.
+  nsFloatManager* mOld;
 };
 
 #endif /* !defined(nsFloatManager_h_) */
--- a/layout/generic/nsLineLayout.h
+++ b/layout/generic/nsLineLayout.h
@@ -376,17 +376,21 @@ public:
    * Returns the inline position where the next frame will be reflowed.
    */
   nscoord GetCurrentICoord() { return mCurrentSpan->mICoord; }
 
   void SetSuppressLineWrap(bool aEnabled) { mSuppressLineWrap = aEnabled; }
 
 protected:
   // This state is constant for a given block frame doing line layout
+
+  // A non-owning pointer, which points to the object owned by
+  // nsAutoFloatManager::mNew.
   nsFloatManager* mFloatManager;
+
   const nsStyleText* mStyleText; // for the block
   const ReflowInput* mBlockReflowInput;
 
   // The line layout for the base text.  It is usually nullptr.
   // It becomes not null when the current line layout is for ruby
   // annotations. When there is nested ruby inside annotation, it
   // forms a linked list from the inner annotation to the outermost
   // line layout. The outermost line layout, which has this member