Make nsStyleChangeList own a reference to nsIContent pointers in its list. b=399694 r+sr=dbaron a1.9=damons
authormats.palmgren@bredband.net
Sat, 15 Mar 2008 02:01:18 -0700
changeset 13115 e1625ca024da69c0d7012fd018b16f0854d400f7
parent 13114 ebc0277f5916c1aac75ae0e7bb7027a1e696ed57
child 13116 daa70bbe4331e313eac7594b7cd6522856c9a6a6
push idunknown
push userunknown
push dateunknown
bugs399694
milestone1.9b5pre
Make nsStyleChangeList own a reference to nsIContent pointers in its list. b=399694 r+sr=dbaron a1.9=damons
layout/base/nsStyleChangeList.cpp
layout/base/nsStyleChangeList.h
--- a/layout/base/nsStyleChangeList.cpp
+++ b/layout/base/nsStyleChangeList.cpp
@@ -43,25 +43,25 @@
 #include "nsStyleChangeList.h"
 #include "nsStyleConsts.h"
 #include "nsIFrame.h"
 #include "nsIContent.h"
 #include "nsCRT.h"
 
 static const PRUint32 kGrowArrayBy = 10;
 
-nsStyleChangeList::nsStyleChangeList(void)
+nsStyleChangeList::nsStyleChangeList()
   : mArray(mBuffer),
     mArraySize(kStyleChangeBufferSize),
     mCount(0)
 {
   MOZ_COUNT_CTOR(nsStyleChangeList);
 }
 
-nsStyleChangeList::~nsStyleChangeList(void)
+nsStyleChangeList::~nsStyleChangeList()
 {
   MOZ_COUNT_DTOR(nsStyleChangeList);
   Clear();
 }
 
 nsresult 
 nsStyleChangeList::ChangeAt(PRInt32 aIndex, nsIFrame*& aFrame, nsIContent*& aContent, 
                             nsChangeHint& aHint) const
@@ -92,19 +92,19 @@ nsStyleChangeList::AppendChange(nsIFrame
                "must have frame");
   NS_ASSERTION(aContent || !(aHint & nsChangeHint_ReconstructFrame),
                "must have content");
   NS_ASSERTION(!aContent || aContent->IsNodeOfType(nsINode::eELEMENT),
                "Shouldn't be trying to restyle non-elements directly");
 
   if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content
     if (aContent) {
-      PRInt32 index = mCount;
-      while (0 < index--) {
+      for (PRInt32 index = mCount - 1; index >= 0; --index) {
         if (aContent == mArray[index].mContent) { // remove this change
+          aContent->Release();
           mCount--;
           if (index < mCount) { // move later changes down
             ::memmove(&mArray[index], &mArray[index + 1], 
                       (mCount - index) * sizeof(nsStyleChangeData));
           }
         }
       }
     }
@@ -127,25 +127,34 @@ nsStyleChangeList::AppendChange(nsIFrame
         mArraySize = newSize;
       }
       else {
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
     mArray[mCount].mFrame = aFrame;
     mArray[mCount].mContent = aContent;
+    if (aContent) {
+      aContent->AddRef();
+    }
     mArray[mCount].mHint = aHint;
     mCount++;
   }
   return NS_OK;
 }
 
 void 
 nsStyleChangeList::Clear() 
 {
+  for (PRInt32 index = mCount - 1; index >= 0; --index) {
+    nsIContent* content = mArray[index].mContent;
+    if (content) {
+      content->Release();
+    }
+  }
   if (mArray != mBuffer) {
     delete [] mArray;
     mArray = mBuffer;
     mArraySize = kStyleChangeBufferSize;
   }
   mCount = 0;
 }
 
--- a/layout/base/nsStyleChangeList.h
+++ b/layout/base/nsStyleChangeList.h
@@ -53,38 +53,50 @@ class nsIContent;
 struct nsStyleChangeData {
   nsIFrame*   mFrame;
   nsIContent* mContent;
   nsChangeHint mHint;
 };
 
 static const PRUint32 kStyleChangeBufferSize = 10;
 
+// Note:  nsStyleChangeList owns a reference to
+//  nsIContent pointers in its list.
 class nsStyleChangeList {
 public:
-  nsStyleChangeList(void);
-  ~nsStyleChangeList(void);
+  nsStyleChangeList();
+  ~nsStyleChangeList();
 
   PRInt32 Count(void) const {
     return mCount;
   }
 
+  /**
+   * Fills in pointers without reference counting.  
+   */
   nsresult ChangeAt(PRInt32 aIndex, nsIFrame*& aFrame, nsIContent*& aContent,
                     nsChangeHint& aHint) const;
 
+  /**
+   * Fills in a pointer to the list entry storage (no reference counting
+   * involved).
+   */
   nsresult ChangeAt(PRInt32 aIndex, const nsStyleChangeData** aChangeData) const;
 
   nsresult AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint);
 
   void Clear(void);
 
 protected:
   nsStyleChangeList&  operator=(const nsStyleChangeList& aCopy);
   PRBool              operator==(const nsStyleChangeList& aOther) const;
 
   nsStyleChangeData*  mArray;
   PRInt32             mArraySize;
   PRInt32             mCount;
   nsStyleChangeData   mBuffer[kStyleChangeBufferSize];
+
+private:
+  nsStyleChangeList(const nsStyleChangeList&); // not implemented
 };
 
 
 #endif /* nsStyleChangeList_h___ */