Bug 481881 - use better template arguments for nsTArray<T> after bug 474369, layout part; r+sr=roc
authorArpad Borsos <arpad.borsos@googlemail.com>
Thu, 12 Mar 2009 08:26:29 +0100
changeset 26081 9c36304c687f4ccb773989f25462987e4636016e
parent 26080 3cc2bfa0ddc1e01f53462125123ee0408a2d0480
child 26082 53c8f565f839900f049f54a65f1e7c092048a534
push id5889
push userarpad.borsos@googlemail.com
push dateThu, 12 Mar 2009 08:36:57 +0000
treeherdermozilla-central@9c36304c687f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs481881, 474369
milestone1.9.2a1pre
Bug 481881 - use better template arguments for nsTArray<T> after bug 474369, layout part; r+sr=roc
layout/generic/nsFrame.cpp
layout/generic/nsTextFrameThebes.cpp
layout/inspector/src/inDeepTreeWalker.cpp
layout/inspector/src/inDeepTreeWalker.h
layout/tables/nsCellMap.cpp
layout/tables/nsCellMap.h
layout/tables/nsTableFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -7016,17 +7016,17 @@ struct DR_State
   PRBool      mInited;
   PRBool      mActive;
   PRInt32     mCount;
   PRInt32     mAssert;
   PRInt32     mIndent;
   PRBool      mIndentUndisplayedFrames;
   PRBool      mDisplayPixelErrors;
   nsTArray<DR_Rule*>          mWildRules;
-  nsTArray<DR_FrameTypeInfo*> mFrameTypeTable;
+  nsTArray<DR_FrameTypeInfo>  mFrameTypeTable;
   // reflow specific state
   nsTArray<DR_FrameTreeNode*> mFrameTreeLeaves;
 };
 
 static DR_State *DR_state; // the one and only DR_State
 
 struct DR_RulePart 
 {
@@ -7068,38 +7068,38 @@ void DR_Rule::AddPart(nsIAtom* aFrameTyp
   mTarget = newPart;
   mLength++;
 }
 
 struct DR_FrameTypeInfo
 {
   DR_FrameTypeInfo(nsIAtom* aFrmeType, const char* aFrameNameAbbrev, const char* aFrameName);
   ~DR_FrameTypeInfo() { 
-      MOZ_COUNT_DTOR(DR_FrameTypeInfo);
       PRInt32 numElements;
       numElements = mRules.Length();
       for (PRInt32 i = numElements - 1; i >= 0; i--) {
         delete mRules.ElementAt(i);
       }
    }
 
   nsIAtom*    mType;
   char        mNameAbbrev[16];
   char        mName[32];
   nsTArray<DR_Rule*> mRules;
+private:
+  DR_FrameTypeInfo& operator=(const DR_FrameTypeInfo&); // NOT USED
 };
 
 DR_FrameTypeInfo::DR_FrameTypeInfo(nsIAtom* aFrameType, 
                                    const char* aFrameNameAbbrev, 
                                    const char* aFrameName)
 {
   mType = aFrameType;
   strcpy(mNameAbbrev, aFrameNameAbbrev);
   strcpy(mName, aFrameName);
-  MOZ_COUNT_CTOR(DR_FrameTypeInfo);
 }
 
 struct DR_FrameTreeNode
 {
   DR_FrameTreeNode(nsIFrame* aFrame, DR_FrameTreeNode* aParent) : mFrame(aFrame), mParent(aParent), mDisplay(0), mIndent(0)
   {
     MOZ_COUNT_CTOR(DR_FrameTreeNode);
   }
@@ -7171,20 +7171,16 @@ DR_State::~DR_State()
   numElements = mWildRules.Length();
   for (i = numElements - 1; i >= 0; i--) {
     delete mWildRules.ElementAt(i);
   }
   numElements = mFrameTreeLeaves.Length();
   for (i = numElements - 1; i >= 0; i--) {
     delete mFrameTreeLeaves.ElementAt(i);
   }
-  numElements = mFrameTypeTable.Length();
-  for (i = numElements - 1; i >= 0; i--) {
-    delete mFrameTypeTable.ElementAt(i);
-  }
 }
 
 PRBool DR_State::GetNumber(char*     aBuf, 
                            PRInt32&  aNumber)
 {
   if (sscanf(aBuf, "%d", &aNumber) > 0) 
     return PR_TRUE;
   else 
@@ -7305,43 +7301,43 @@ void DR_State::ParseRulesFile()
   }
 }
 
 
 void DR_State::AddFrameTypeInfo(nsIAtom* aFrameType,
                                 const char* aFrameNameAbbrev,
                                 const char* aFrameName)
 {
-  mFrameTypeTable.AppendElement(new DR_FrameTypeInfo(aFrameType, aFrameNameAbbrev, aFrameName));
+  mFrameTypeTable.AppendElement(DR_FrameTypeInfo(aFrameType, aFrameNameAbbrev, aFrameName));
 }
 
 DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(nsIAtom* aFrameType)
 {
   PRInt32 numEntries = mFrameTypeTable.Length();
   NS_ASSERTION(numEntries != 0, "empty FrameTypeTable");
   for (PRInt32 i = 0; i < numEntries; i++) {
-    DR_FrameTypeInfo* info = mFrameTypeTable.ElementAt(i);
-    if (info && (info->mType == aFrameType)) {
-      return info;
-    }
-  }
-  return mFrameTypeTable.ElementAt(numEntries - 1); // return unknown frame type
+    DR_FrameTypeInfo& info = mFrameTypeTable.ElementAt(i);
+    if (info.mType == aFrameType) {
+      return &info;
+    }
+  }
+  return &mFrameTypeTable.ElementAt(numEntries - 1); // return unknown frame type
 }
 
 DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(char* aFrameName)
 {
   PRInt32 numEntries = mFrameTypeTable.Length();
   NS_ASSERTION(numEntries != 0, "empty FrameTypeTable");
   for (PRInt32 i = 0; i < numEntries; i++) {
-    DR_FrameTypeInfo* info = mFrameTypeTable.ElementAt(i);
-    if (info && ((strcmp(aFrameName, info->mName) == 0) || (strcmp(aFrameName, info->mNameAbbrev) == 0))) {
-      return info;
-    }
-  }
-  return mFrameTypeTable.ElementAt(numEntries - 1); // return unknown frame type
+    DR_FrameTypeInfo& info = mFrameTypeTable.ElementAt(i);
+    if ((strcmp(aFrameName, info.mName) == 0) || (strcmp(aFrameName, info.mNameAbbrev) == 0)) {
+      return &info;
+    }
+  }
+  return &mFrameTypeTable.ElementAt(numEntries - 1); // return unknown frame type
 }
 
 void DR_State::InitFrameTypeTable()
 {  
   AddFrameTypeInfo(nsGkAtoms::blockFrame,            "block",     "block");
   AddFrameTypeInfo(nsGkAtoms::brFrame,               "br",        "br");
   AddFrameTypeInfo(nsGkAtoms::bulletFrame,           "bullet",    "bullet");
   AddFrameTypeInfo(nsGkAtoms::gfxButtonControlFrame, "button",    "gfxButtonControl");
@@ -7471,17 +7467,17 @@ DR_FrameTreeNode* DR_State::CreateTreeNo
     parentFrame = aFrame->GetParent();
   }
 
   // find the parent tree node leaf
   DR_FrameTreeNode* parentNode = nsnull;
   
   DR_FrameTreeNode* lastLeaf = nsnull;
   if(mFrameTreeLeaves.Length())
-    lastLeaf = (DR_FrameTreeNode*)mFrameTreeLeaves.ElementAt(mFrameTreeLeaves.Length() - 1);
+    lastLeaf = mFrameTreeLeaves.ElementAt(mFrameTreeLeaves.Length() - 1);
   if (lastLeaf) {
     for (parentNode = lastLeaf; parentNode && (parentNode->mFrame != parentFrame); parentNode = parentNode->mParent) {
     }
   }
   DR_FrameTreeNode* newNode = new DR_FrameTreeNode(aFrame, parentNode);
   FindMatchingRule(*newNode);
 
   newNode->mIndent = mIndent;
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -2749,18 +2749,25 @@ protected:
     nsIFrame*       mFrame;
 
 
     FrameData(nsPresContext* aPresContext,
               nsIFrame*       aFrame)
       : mPresContext(aPresContext), mFrame(aFrame) {}
   };
 
+  class FrameDataComparator {
+    public:
+      PRBool Equals(const FrameData& aTimer, nsIFrame* const& aFrame) const {
+        return aTimer.mFrame == aFrame;
+      }
+  };
+
   nsCOMPtr<nsITimer> mTimer;
-  nsTArray<FrameData*> mFrames;
+  nsTArray<FrameData> mFrames;
   nsPresContext* mPresContext;
 
 protected:
 
   static nsBlinkTimer* sTextBlinker;
   static PRUint32      sState; // 0-2 == on; 3 == off
   
 };
@@ -2797,36 +2804,26 @@ void nsBlinkTimer::Stop()
     mTimer->Cancel();
     mTimer = nsnull;
   }
 }
 
 NS_IMPL_ISUPPORTS1(nsBlinkTimer, nsITimerCallback)
 
 void nsBlinkTimer::AddFrame(nsPresContext* aPresContext, nsIFrame* aFrame) {
-  FrameData* frameData = new FrameData(aPresContext, aFrame);
-  mFrames.AppendElement(frameData);
+  mFrames.AppendElement(FrameData(aPresContext, aFrame));
   if (1 == mFrames.Length()) {
     Start();
   }
 }
 
 PRBool nsBlinkTimer::RemoveFrame(nsIFrame* aFrame) {
-  PRUint32 i, n = mFrames.Length();
-  for (i = 0; i < n; i++) {
-    FrameData* frameData = mFrames.ElementAt(i);
-
-    if (frameData->mFrame == aFrame) {
-      mFrames.RemoveElementAt(i);
-      delete frameData;
-      break;
-    }
-  }
+  mFrames.RemoveElement(aFrame, FrameDataComparator());
   
-  if (0 == mFrames.Length()) {
+  if (mFrames.IsEmpty()) {
     Stop();
   }
   return PR_TRUE;
 }
 
 PRInt32 nsBlinkTimer::FrameCount() {
   return PRInt32(mFrames.Length());
 }
@@ -2848,22 +2845,22 @@ NS_IMETHODIMP nsBlinkTimer::Notify(nsITi
   LL_SUB(delta, now, gLastTick);
   gLastTick = now;
   PR_snprintf(buf, sizeof(buf), "%lldusec", delta);
   printf("%s\n", buf);
 #endif
 
   PRUint32 i, n = mFrames.Length();
   for (i = 0; i < n; i++) {
-    FrameData* frameData = mFrames.ElementAt(i);
+    FrameData& frameData = mFrames.ElementAt(i);
 
     // Determine damaged area and tell view manager to redraw it
     // blink doesn't blink outline ... I hope
-    nsRect bounds(nsPoint(0, 0), frameData->mFrame->GetSize());
-    frameData->mFrame->Invalidate(bounds);
+    nsRect bounds(nsPoint(0, 0), frameData.mFrame->GetSize());
+    frameData.mFrame->Invalidate(bounds);
   }
   return NS_OK;
 }
 
 
 // static
 nsresult nsBlinkTimer::AddBlinkFrame(nsPresContext* aPresContext, nsIFrame* aFrame)
 {
--- a/layout/inspector/src/inDeepTreeWalker.cpp
+++ b/layout/inspector/src/inDeepTreeWalker.cpp
@@ -48,40 +48,25 @@
 /*****************************************************************************
  * This implementation does not currently operaate according to the W3C spec.
  * So far, only parentNode() and nextNode() are implemented, and are not
  * interoperable.  
  *****************************************************************************/
 
 ////////////////////////////////////////////////////
 
-struct DeepTreeStackItem 
-{
-  DeepTreeStackItem()  { MOZ_COUNT_CTOR(DeepTreeStackItem); }
-  ~DeepTreeStackItem() { MOZ_COUNT_DTOR(DeepTreeStackItem); }
-
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIDOMNodeList> kids;
-  PRUint32 lastIndex;
-};
-
-////////////////////////////////////////////////////
-
 inDeepTreeWalker::inDeepTreeWalker() 
   : mShowAnonymousContent(PR_FALSE),
     mShowSubDocuments(PR_FALSE),
     mWhatToShow(nsIDOMNodeFilter::SHOW_ALL)
 {
 }
 
 inDeepTreeWalker::~inDeepTreeWalker() 
 { 
-  for (PRInt32 i = mStack.Length() - 1; i >= 0; --i) {
-    delete mStack[i];
-  }
 }
 
 NS_IMPL_ISUPPORTS2(inDeepTreeWalker,
                    inIDeepTreeWalker,
                    nsIDOMTreeWalker)
 
 ////////////////////////////////////////////////////
 // inIDeepTreeWalker
@@ -223,30 +208,29 @@ inDeepTreeWalker::PreviousNode(nsIDOMNod
 NS_IMETHODIMP
 inDeepTreeWalker::NextNode(nsIDOMNode **_retval)
 {
   if (!mCurrentNode) return NS_OK;
   
   nsCOMPtr<nsIDOMNode> next;
   
   while (1) {
-    DeepTreeStackItem* top = mStack.ElementAt(mStack.Length()-1);
-    nsCOMPtr<nsIDOMNodeList> kids = top->kids;
+    DeepTreeStackItem& top = mStack.ElementAt(mStack.Length()-1);
+    nsCOMPtr<nsIDOMNodeList> kids = top.kids;
     PRUint32 childCount;
     kids->GetLength(&childCount);
 
-    if (top->lastIndex == childCount) {
+    if (top.lastIndex == childCount) {
       mStack.RemoveElementAt(mStack.Length()-1);
-      delete top;
       if (mStack.Length() == 0) {
         mCurrentNode = nsnull;
         break;
       }
     } else {
-      kids->Item(top->lastIndex++, getter_AddRefs(next));
+      kids->Item(top.lastIndex++, getter_AddRefs(next));
       PushNode(next);
       break;      
     }
   } 
   
   *_retval = next;
   NS_IF_ADDREF(*_retval);
   
@@ -254,18 +238,18 @@ inDeepTreeWalker::NextNode(nsIDOMNode **
 }
 
 void
 inDeepTreeWalker::PushNode(nsIDOMNode* aNode)
 {
   mCurrentNode = aNode;
   if (!aNode) return;
 
-  DeepTreeStackItem* item = new DeepTreeStackItem();
-  item->node = aNode;
+  DeepTreeStackItem item;
+  item.node = aNode;
 
   nsCOMPtr<nsIDOMNodeList> kids;
   if (mShowSubDocuments) {
     nsCOMPtr<nsIDOMDocument> domdoc = inLayoutUtils::GetSubDocumentFor(aNode);
     if (domdoc) {
       domdoc->GetChildNodes(getter_AddRefs(kids));
     }
   }
@@ -281,18 +265,18 @@ inDeepTreeWalker::PushNode(nsIDOMNode* a
           bindingManager->GetContentListFor(content, getter_AddRefs(kids));
       } else {
         aNode->GetChildNodes(getter_AddRefs(kids));
       }
     } else
       aNode->GetChildNodes(getter_AddRefs(kids));
   }
   
-  item->kids = kids;
-  item->lastIndex = 0;
+  item.kids = kids;
+  item.lastIndex = 0;
   mStack.AppendElement(item);
 }
 
 /*
 // This NextNode implementation does not require the use of stacks, 
 // as does the one above. However, it does not handle anonymous 
 // content and sub-documents.
 NS_IMETHODIMP
--- a/layout/inspector/src/inDeepTreeWalker.h
+++ b/layout/inspector/src/inDeepTreeWalker.h
@@ -40,17 +40,27 @@
 
 #include "inIDeepTreeWalker.h"
 
 #include "nsCOMPtr.h"
 #include "nsIDOMNode.h"
 #include "nsTArray.h"
 
 class inIDOMUtils;
-class DeepTreeStackItem;
+
+////////////////////////////////////////////////////
+
+struct DeepTreeStackItem
+{
+  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIDOMNodeList> kids;
+  PRUint32 lastIndex;
+};
+
+////////////////////////////////////////////////////
 
 class inDeepTreeWalker : public inIDeepTreeWalker
 {
 public:
 	NS_DECL_ISUPPORTS
 	NS_DECL_NSIDOMTREEWALKER
 	NS_DECL_INIDEEPTREEWALKER
 
@@ -61,17 +71,17 @@ protected:
   void PushNode(nsIDOMNode* aNode);
 
   PRBool mShowAnonymousContent;
   PRBool mShowSubDocuments;
   nsCOMPtr<nsIDOMNode> mRoot;
   nsCOMPtr<nsIDOMNode> mCurrentNode;
   PRUint32 mWhatToShow;
   
-  nsAutoTArray<DeepTreeStackItem*, 8> mStack;
+  nsAutoTArray<DeepTreeStackItem, 8> mStack;
   nsCOMPtr<inIDOMUtils> mDOMUtils;
 };
 
 // {BFCB82C2-5611-4318-90D6-BAF4A7864252}
 #define IN_DEEPTREEWALKER_CID \
 { 0xbfcb82c2, 0x5611, 0x4318, { 0x90, 0xd6, 0xba, 0xf4, 0xa7, 0x86, 0x42, 0x52 } }
 
 #endif // __inDeepTreeWalker_h___
--- a/layout/tables/nsCellMap.cpp
+++ b/layout/tables/nsCellMap.cpp
@@ -96,96 +96,60 @@ nsTableCellMap::~nsTableCellMap()
 
   nsCellMap* cellMap = mFirstMap;
   while (cellMap) {
     nsCellMap* next = cellMap->GetNextSibling();
     delete cellMap;
     cellMap = next;
   }
 
-  PRInt32 colCount = mCols.Length();
-  for (PRInt32 colX = 0; colX < colCount; colX++) {
-    nsColInfo* colInfo = mCols.ElementAt(colX);
-    if (colInfo) {
-      delete colInfo;
-    }
-  }
   if (mBCInfo) {
     DeleteRightBottomBorders();
     delete mBCInfo;
   }
 }
 
 // Get the bcData holding the border segments of the right edge of the table
 BCData*
 nsTableCellMap::GetRightMostBorder(PRInt32 aRowIndex)
 {
   if (!mBCInfo) ABORT1(nsnull);
 
   PRInt32 numRows = mBCInfo->mRightBorders.Length();
   if (aRowIndex < numRows) {
-    return mBCInfo->mRightBorders.ElementAt(aRowIndex);
+    return &mBCInfo->mRightBorders.ElementAt(aRowIndex);
   }
 
-  BCData* bcData;
-  PRInt32 rowX = numRows;
-
-  do {
-    bcData = new BCData();
-    if (!bcData) ABORT1(nsnull);
-    mBCInfo->mRightBorders.AppendElement(bcData);
-  } while (++rowX <= aRowIndex);
-
-  return bcData;
+  if (!mBCInfo->mRightBorders.SetLength(aRowIndex+1))
+    ABORT1(nsnull);
+  return &mBCInfo->mRightBorders.ElementAt(aRowIndex);
 }
 
 // Get the bcData holding the border segments of the bottom edge of the table
 BCData*
 nsTableCellMap::GetBottomMostBorder(PRInt32 aColIndex)
 {
   if (!mBCInfo) ABORT1(nsnull);
 
   PRInt32 numCols = mBCInfo->mBottomBorders.Length();
   if (aColIndex < numCols) {
-    return mBCInfo->mBottomBorders.ElementAt(aColIndex);
+    return &mBCInfo->mBottomBorders.ElementAt(aColIndex);
   }
 
-  BCData* bcData;
-  PRInt32 colX = numCols;
-
-  do {
-    bcData = new BCData();
-    if (!bcData) ABORT1(nsnull);
-    mBCInfo->mBottomBorders.AppendElement(bcData);
-  } while (++colX <= aColIndex);
-
-  return bcData;
+  if (!mBCInfo->mBottomBorders.SetLength(aColIndex+1))
+    ABORT1(nsnull);
+  return &mBCInfo->mBottomBorders.ElementAt(aColIndex);
 }
 
 // delete the borders corresponding to the right and bottom edges of the table
 void 
 nsTableCellMap::DeleteRightBottomBorders()
 {
   if (mBCInfo) {
-    PRUint32 numCols = mBCInfo->mBottomBorders.Length();
-    for (PRUint32 colX = 0; colX < numCols; colX++) {
-      BCData* bcData = mBCInfo->mBottomBorders.ElementAt(colX);
-      if (bcData) {
-        delete bcData;
-      }
-    }
     mBCInfo->mBottomBorders.Clear();
-    
-    PRUint32 numRows = mBCInfo->mRightBorders.Length();
-    for (PRUint32 rowX = 0; rowX < numRows; rowX++) {
-      BCData* bcData = mBCInfo->mRightBorders.ElementAt(rowX);
-      if (bcData) {
-        delete bcData;
-      }
-    }
     mBCInfo->mRightBorders.Clear();
   }
 }
       
 void 
 nsTableCellMap::InsertGroupCellMap(nsCellMap* aPrevMap,
                                    nsCellMap& aNewMap)
 {
@@ -425,17 +389,17 @@ nsTableCellMap::GetCellFrame(PRInt32   a
 
 nsColInfo* 
 nsTableCellMap::GetColInfoAt(PRInt32 aColIndex)
 {
   PRInt32 numColsToAdd = aColIndex + 1 - mCols.Length();
   if (numColsToAdd > 0) {
     AddColsAtEnd(numColsToAdd);  // XXX this could fail to add cols in theory
   }
-  return mCols.ElementAt(aColIndex);
+  return &mCols.ElementAt(aColIndex);
 }
 
 PRInt32 
 nsTableCellMap::GetRowCount() const
 {
   PRInt32 numRows = 0;
   nsCellMap* map = mFirstMap;
   while (map) {
@@ -459,97 +423,55 @@ nsTableCellMap::GetDataAt(PRInt32 aRowIn
     map = map->GetNextSibling();
   }
   return nsnull;
 }
 
 void 
 nsTableCellMap::AddColsAtEnd(PRUint32 aNumCols)
 {
-  PRBool added;
-  // XXX We really should have a way to say "make this voidarray at least
-  // N entries long" to avoid reallocating N times.  On the other hand, the
-  // number of likely allocations here isn't TOO gigantic, and we may not
-  // know about many of them at a time.
-  for (PRUint32 numX = 1; numX <= aNumCols; numX++) {
-    nsColInfo* colInfo = new nsColInfo();
-    if (colInfo) {
-      added = mCols.AppendElement(colInfo) != nsnull;
-      if (!added) {
-        delete colInfo;
-        NS_WARNING("Could not AppendElement");
-      }
-    }
-    if (mBCInfo) {
-      BCData* bcData = new BCData();
-      if (bcData) {
-        added = mBCInfo->mBottomBorders.AppendElement(bcData) != nsnull;
-        if (!added) {
-          delete bcData;
-          NS_WARNING("Could not AppendElement");
-        }
-      }
+  if (!mCols.AppendElements(aNumCols)) {
+    NS_WARNING("Could not AppendElement");
+  }
+  if (mBCInfo) {
+    if (!mBCInfo->mBottomBorders.AppendElements(aNumCols)) {
+      NS_WARNING("Could not AppendElement");
     }
   }
 }
 
 void 
 nsTableCellMap::RemoveColsAtEnd()
 {
   // Remove the cols at the end which don't have originating cells or cells spanning 
   // into them. Only do this if the col was created as eColAnonymousCell  
   PRInt32 numCols = GetColCount();
   PRInt32 lastGoodColIndex = mTableFrame.GetIndexOfLastRealCol();
   for (PRInt32 colX = numCols - 1; (colX >= 0) && (colX > lastGoodColIndex); colX--) {
-    nsColInfo* colInfo = mCols.ElementAt(colX);
-    if (colInfo) {
-      if ((colInfo->mNumCellsOrig <= 0) && (colInfo->mNumCellsSpan <= 0))  {
-
-        delete colInfo;
-        mCols.RemoveElementAt(colX);
+    nsColInfo& colInfo = mCols.ElementAt(colX);
+    if ((colInfo.mNumCellsOrig <= 0) && (colInfo.mNumCellsSpan <= 0))  {
+      mCols.RemoveElementAt(colX);
 
-        if (mBCInfo) { 
-          PRInt32 count = mBCInfo->mBottomBorders.Length();
-          if (colX < count) {
-            BCData* bcData = mBCInfo->mBottomBorders.ElementAt(colX);
-            if (bcData) {
-              delete bcData;
-            }
-            mBCInfo->mBottomBorders.RemoveElementAt(colX);
-          }
+      if (mBCInfo) { 
+        PRInt32 count = mBCInfo->mBottomBorders.Length();
+        if (colX < count) {
+          mBCInfo->mBottomBorders.RemoveElementAt(colX);
         }
       }
-      else break; // only remove until we encounter the 1st valid one
     }
-    else {
-      NS_ERROR("null entry in column info array");
-      mCols.RemoveElementAt(colX);
-    }
+    else break; // only remove until we encounter the 1st valid one
   }
 }
 
 void 
 nsTableCellMap::ClearCols()
 {
-  PRInt32 numCols = GetColCount();
-  for (PRInt32 colX = numCols - 1; (colX >= 0);colX--) {
-    nsColInfo* colInfo = mCols.ElementAt(colX);
-    delete colInfo;
-    mCols.RemoveElementAt(colX);
-    if (mBCInfo) { 
-      PRInt32 count = mBCInfo->mBottomBorders.Length();
-      if (colX < count) {
-        BCData* bcData = mBCInfo->mBottomBorders.ElementAt(colX);
-        if (bcData) {
-              delete bcData;
-        }
-        mBCInfo->mBottomBorders.RemoveElementAt(colX);
-      }
-    }
-  }
+  mCols.Clear();
+  if (mBCInfo)
+    mBCInfo->mBottomBorders.Clear();
 }
 void
 nsTableCellMap::InsertRows(nsTableRowGroupFrame&       aParent,
                            nsTArray<nsTableRowFrame*>& aRows,
                            PRInt32                     aFirstRowIndex,
                            PRBool                      aConsiderSpans,
                            nsRect&                     aDamageArea)
 {
@@ -563,29 +485,28 @@ nsTableCellMap::InsertRows(nsTableRowGro
     if (rg == &aParent) {
       cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans, aDamageArea);
       aDamageArea.y = PR_MIN(aFirstRowIndex, aDamageArea.y);
       aDamageArea.height = PR_MAX(0, GetRowCount() - aDamageArea.y);
 #ifdef DEBUG_TABLE_CELLMAP 
       Dump("after InsertRows");
 #endif
       if (mBCInfo) {
-        BCData* bcData;
         PRInt32 count = mBCInfo->mRightBorders.Length();
         if (aFirstRowIndex < count) {
           for (PRInt32 rowX = aFirstRowIndex; rowX < aFirstRowIndex + numNewRows; rowX++) {
-            bcData = new BCData(); if (!bcData) ABORT0();
-            mBCInfo->mRightBorders.InsertElementAt(rowX, bcData);
+            if (!mBCInfo->mRightBorders.InsertElementAt(rowX))
+              ABORT0();
           }
         }
         else {
           GetRightMostBorder(aFirstRowIndex); // this will create missing entries
           for (PRInt32 rowX = aFirstRowIndex + 1; rowX < aFirstRowIndex + numNewRows; rowX++) {
-            bcData = new BCData(); if (!bcData) ABORT0();
-            mBCInfo->mRightBorders.AppendElement(bcData);
+            if (!mBCInfo->mRightBorders.AppendElement())
+              ABORT0();
           }
         }
       }
       return;
     }
     rowIndex -= cellMap->GetRowCount();
     cellMap = cellMap->GetNextSibling();
   }
@@ -603,23 +524,18 @@ nsTableCellMap::RemoveRows(PRInt32      
   nsCellMap* cellMap = mFirstMap;
   while (cellMap) {
     if (cellMap->GetRowCount() > rowIndex) {
       cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans, aDamageArea);
       nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
       aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
       aDamageArea.height = PR_MAX(0, GetRowCount() - aFirstRowIndex);
       if (mBCInfo) {
-        BCData* bcData;
         for (PRInt32 rowX = aFirstRowIndex + aNumRowsToRemove - 1; rowX >= aFirstRowIndex; rowX--) {
           if (PRUint32(rowX) < mBCInfo->mRightBorders.Length()) {
-            bcData = mBCInfo->mRightBorders.ElementAt(rowX);
-            if (bcData) {
-              delete bcData;
-            }
             mBCInfo->mRightBorders.RemoveElementAt(rowX);
           }
         }
       }
       break;
     }
     rowIndex -= cellMap->GetRowCount();
     cellMap = cellMap->GetNextSibling();
@@ -787,17 +703,17 @@ nsTableCellMap::RebuildConsideringRows(n
   SetDamageArea(0, 0, GetColCount(), rowCount, aDamageArea);
 }
 
 PRInt32 
 nsTableCellMap::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
 {
   PRInt32 colCount = mCols.Length();
   if ((aColIndex >= 0) && (aColIndex < colCount)) {
-    return (mCols.ElementAt(aColIndex))->mNumCellsOrig;
+    return mCols.ElementAt(aColIndex).mNumCellsOrig;
   }
   else {
     NS_ERROR("nsCellMap::GetNumCellsOriginatingInCol - bad col index");
     return 0;
   }
 }
 
 #ifdef NS_DEBUG
@@ -806,18 +722,18 @@ nsTableCellMap::Dump(char* aString) cons
 {
   if (aString) 
     printf("%s \n", aString);
   printf("***** START TABLE CELL MAP DUMP ***** %p\n", (void*)this);
   // output col info
   PRInt32 colCount = mCols.Length();
   printf ("cols array orig/span-> %p", (void*)this);
   for (PRInt32 colX = 0; colX < colCount; colX++) {
-    nsColInfo* colInfo = mCols.ElementAt(colX);
-    printf ("%d=%d/%d ", colX, colInfo->mNumCellsOrig, colInfo->mNumCellsSpan);
+    const nsColInfo& colInfo = mCols.ElementAt(colX);
+    printf ("%d=%d/%d ", colX, colInfo.mNumCellsOrig, colInfo.mNumCellsSpan);
   }
   printf(" cols in cache %d\n", mTableFrame.GetColCache().Length());
   nsCellMap* cellMap = mFirstMap;
   while (cellMap) {
     cellMap->Dump(nsnull != mBCInfo);
     cellMap = cellMap->GetNextSibling();
   }
   if (nsnull != mBCInfo) {
@@ -828,47 +744,43 @@ nsTableCellMap::Dump(char* aString) cons
     PRBool        segStart;
     PRPackedBool  bevel;  
     PRInt32       colIndex;    
     PRInt32 numCols = mBCInfo->mBottomBorders.Length();
     for (PRInt32 i = 0; i <= 2; i++) {
      
       printf("\n          ");
       for (colIndex = 0; colIndex < numCols; colIndex++) {
-        BCData* cd = mBCInfo->mBottomBorders.ElementAt(colIndex);
-        if (cd) {
-          if (0 == i) {
-            size = cd->GetTopEdge(owner, segStart);
-            printf("t=%d%X%d ", size, owner, segStart);
-          }
-          else if (1 == i) {
-            size = cd->GetLeftEdge(owner, segStart);
-            printf("l=%d%X%d ", size, owner, segStart);
-          }
-          else {
-            size = cd->GetCorner(side, bevel);
-            printf("c=%d%X%d ", size, side, bevel);
-          }
-        }
-      }
-      BCData* cd = &mBCInfo->mLowerRightCorner;
-      if (cd) {
+        BCData& cd = mBCInfo->mBottomBorders.ElementAt(colIndex);
         if (0 == i) {
-           size = cd->GetTopEdge(owner, segStart);
-           printf("t=%d%X%d ", size, owner, segStart);
+          size = cd.GetTopEdge(owner, segStart);
+          printf("t=%d%X%d ", size, owner, segStart);
         }
         else if (1 == i) {
-          size = cd->GetLeftEdge(owner, segStart);
+          size = cd.GetLeftEdge(owner, segStart);
           printf("l=%d%X%d ", size, owner, segStart);
         }
         else {
-          size = cd->GetCorner(side, bevel);
+          size = cd.GetCorner(side, bevel);
           printf("c=%d%X%d ", size, side, bevel);
         }
       }
+      BCData& cd = mBCInfo->mLowerRightCorner;
+      if (0 == i) {
+         size = cd.GetTopEdge(owner, segStart);
+         printf("t=%d%X%d ", size, owner, segStart);
+      }
+      else if (1 == i) {
+        size = cd.GetLeftEdge(owner, segStart);
+        printf("l=%d%X%d ", size, owner, segStart);
+      }
+      else {
+        size = cd.GetCorner(side, bevel);
+        printf("c=%d%X%d ", size, side, bevel);
+      }
     }
     printf("\n");
   }
   printf("***** END TABLE CELL MAP DUMP *****\n");
 }
 #endif
 
 nsTableCellFrame* 
@@ -997,17 +909,17 @@ PRBool nsTableCellMap::RowHasSpanningCel
 }
 
 PRBool nsTableCellMap::ColIsSpannedInto(PRInt32 aColIndex) const
 {
   PRBool result = PR_FALSE;
 
   PRInt32 colCount = mCols.Length();
   if ((aColIndex >= 0) && (aColIndex < colCount)) {
-    result = (mCols.ElementAt(aColIndex))->mNumCellsSpan != 0;
+    result = mCols.ElementAt(aColIndex).mNumCellsSpan != 0;
   }
   return result;
 }
 
 PRBool nsTableCellMap::ColHasSpanningCells(PRInt32 aColIndex) const
 {
   NS_PRECONDITION (aColIndex < GetColCount(), "bad col index arg");
   nsCellMap* cellMap = mFirstMap;
@@ -1026,24 +938,25 @@ void nsTableCellMap::ExpandZeroColSpans(
   mTableFrame.SetHasZeroColSpans(PR_FALSE); // reset the bit, if there is a
                                             // zerospan it will be set again.
   nsCellMap* cellMap = mFirstMap;
   while (cellMap) {
     cellMap->ExpandZeroColSpans(*this);
     cellMap = cellMap->GetNextSibling();
   }
 }
-BCData* 
-nsTableCellMap::GetBCData(PRUint8     aSide, 
-                          nsCellMap&  aCellMap,
-                          PRUint32    aRowIndex, 
-                          PRUint32    aColIndex,
-                          PRBool      aIsLowerRight)
+
+void
+nsTableCellMap::SetNotTopStart(PRUint8    aSide,
+                               nsCellMap& aCellMap,
+                               PRUint32   aRowIndex,
+                               PRUint32   aColIndex,
+                               PRBool     aIsLowerRight)
 {
-  if (!mBCInfo || aIsLowerRight) ABORT1(nsnull);
+  if (!mBCInfo || aIsLowerRight) ABORT0();
 
   BCCellData* cellData;
   BCData* bcData = nsnull;
 
   switch(aSide) {
   case NS_SIDE_BOTTOM:
     aRowIndex++;
   case NS_SIDE_TOP:
@@ -1074,17 +987,19 @@ nsTableCellMap::GetBCData(PRUint8     aS
       bcData = &cellData->mData;
     }
     else {
       NS_ASSERTION(aSide == NS_SIDE_RIGHT, "program error");
       bcData = GetRightMostBorder(aRowIndex);
     }
     break;
   }
-  return bcData;
+  if (bcData) {
+    bcData->SetTopStart(PR_FALSE);
+  }
 }
 
 // store the aSide border segment at coord = (aRowIndex, aColIndex). For top/left, store
 // the info at coord. For bottom/left store it at the adjacent location so that it is 
 // top/left at that location. If the new location is at the right or bottom edge of the 
 // table, then store it one of the special arrays (right most borders, bottom most borders).  
 void 
 nsTableCellMap::SetBCBorderEdge(PRUint8       aSide, 
--- a/layout/tables/nsCellMap.h
+++ b/layout/tables/nsCellMap.h
@@ -70,19 +70,19 @@ enum Corner
   eTopLeft     = 0,
   eTopRight    = 1,
   eBottomRight = 2,
   eBottomLeft  = 3
 };
 
 struct BCInfo
 {
-  nsTArray<BCData*> mRightBorders;
-  nsTArray<BCData*> mBottomBorders;
-  BCData            mLowerRightCorner;
+  nsTArray<BCData> mRightBorders;
+  nsTArray<BCData> mBottomBorders;
+  BCData           mLowerRightCorner;
 };
 
 class nsTableCellMap
 {
 public:
   nsTableCellMap(nsTableFrame&   aTableFrame,
                  PRBool          aBorderCollapse);
 
@@ -225,21 +225,21 @@ protected:
                               nsRect&                     aDamageArea);
 
 public:
   PRBool ColIsSpannedInto(PRInt32 aColIndex) const;
   PRBool ColHasSpanningCells(PRInt32 aColIndex) const;
 
   void ExpandZeroColSpans();
 
-  BCData* GetBCData(PRUint8     aSide, 
-                    nsCellMap&  aCellMap,
-                    PRUint32    aYPos, 
-                    PRUint32    aXPos,
-                    PRBool      aIsLowerRight = PR_FALSE);
+  void SetNotTopStart(PRUint8    aSide,
+                      nsCellMap& aCellMap,
+                      PRUint32   aYPos,
+                      PRUint32   aXPos,
+                      PRBool     aIsLowerRight = PR_FALSE);
 
   void SetBCBorderEdge(PRUint8       aEdge, 
                        nsCellMap&    aCellMap,
                        PRUint32      aCellMapStart,
                        PRUint32      aYPos, 
                        PRUint32      aXPos,
                        PRUint32      aLength,
                        BCBorderOwner aOwner,
@@ -274,17 +274,17 @@ protected:
   * at the beginning, the ordering of the cellmap corresponds to the ordering of
   * rowgroups once OrderRowGroups has been called
   */
   void InsertGroupCellMap(nsCellMap* aPrevMap,
                           nsCellMap& aNewMap);
   void DeleteRightBottomBorders();
 
   nsTableFrame&               mTableFrame;
-  nsAutoTArray<nsColInfo*, 8> mCols;
+  nsAutoTArray<nsColInfo, 8>  mCols;
   nsCellMap*                  mFirstMap;
   // border collapsing info
   BCInfo*                     mBCInfo;
 };
 
 /** nsCellMap is a support class for nsTablePart.  
   * It maintains an Rows x Columns grid onto which the cells of the table are mapped.
   * This makes processing of rowspan and colspan attributes much easier.
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -5844,21 +5844,18 @@ nsTableFrame::CalcBCBorders()
       BCCornerInfo& corner = bottomCorners[cellEndColIndex + 1];
       if ((NS_SIDE_TOP != corner.ownerSide) && (NS_SIDE_BOTTOM != corner.ownerSide)) { // not a vertical owner
         BCCellBorder& thisBorder = lastBottomBorder;
         BCCellBorder& nextBorder = lastBottomBorders[info.colIndex + 1];
         if ((thisBorder.color == nextBorder.color) && (thisBorder.width == nextBorder.width) &&
             (thisBorder.style == nextBorder.style)) {
           // set the flag on the next border indicating it is not the start of a new segment
           if (iter.mCellMap) {
-            BCData* bcData = tableCellMap->GetBCData(NS_SIDE_BOTTOM, *iter.mCellMap, cellEndRowIndex, 
-                                                     cellEndColIndex + 1);
-            if (bcData) {
-              bcData->SetTopStart(PR_FALSE);
-            }
+            tableCellMap->SetNotTopStart(NS_SIDE_BOTTOM, *iter.mCellMap,
+                                         cellEndRowIndex, cellEndColIndex + 1);
           }
         }
       }
     }
   } // for (iter.First(info); info.cell; iter.Next(info)) {
 
   // reset the bc flag and damage area
   SetNeedToCalcBCBorders(PR_FALSE);
@@ -5990,21 +5987,21 @@ BCMapBorderIterator::SetNewData(PRInt32 
   y            = aY;
   prevCellData = cellData;
   if (IsRightMost() && IsBottomMost()) {
     cell = nsnull;
     bcData = &tableCellMap->mBCInfo->mLowerRightCorner;
   }
   else if (IsRightMost()) {
     cellData = nsnull;
-    bcData = (BCData*)tableCellMap->mBCInfo->mRightBorders.ElementAt(aY);
+    bcData = &tableCellMap->mBCInfo->mRightBorders.ElementAt(aY);
   }
   else if (IsBottomMost()) {
     cellData = nsnull;
-    bcData = (BCData*)tableCellMap->mBCInfo->mBottomBorders.ElementAt(aX);
+    bcData = &tableCellMap->mBCInfo->mBottomBorders.ElementAt(aX);
   }
   else {
     if (PRUint32(y - fifRowGroupStart) < cellMap->mRows.Length()) { 
       bcData = nsnull;
       cellData =
         (BCCellData*)cellMap->mRows[y - fifRowGroupStart].SafeElementAt(x);
       if (cellData) {
         bcData = &cellData->mData;