Bug 504221 part 12. Switch SetInitialChildList to nsFrameList. r=fantasai, r+sr=roc
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 28 Jul 2009 08:53:20 -0400
changeset 30790 ae5133c2c8658c15d0078f2a7fc97275859203c4
parent 30789 5e9842c402e6d57b463cd2f919686f65f8598db1
child 30791 789ad87b744030644188f44ab8524ef782a14ea4
push id8238
push userbzbarsky@mozilla.com
push dateTue, 28 Jul 2009 12:54:45 +0000
treeherdermozilla-central@fa95e1446790 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfantasai, r
bugs504221
milestone1.9.2a1pre
Bug 504221 part 12. Switch SetInitialChildList to nsFrameList. r=fantasai, r+sr=roc
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsGfxButtonControlFrame.cpp
layout/forms/nsListControlFrame.cpp
layout/forms/nsListControlFrame.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsAbsoluteContainingBlock.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsFirstLetterFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsFrameList.h
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsFrameSetFrame.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsHTMLFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsInlineFrame.cpp
layout/generic/nsInlineFrame.h
layout/generic/nsViewportFrame.cpp
layout/generic/nsViewportFrame.h
layout/mathml/nsMathMLContainerFrame.h
layout/mathml/nsMathMLForeignFrameWrapper.h
layout/mathml/nsMathMLTokenFrame.cpp
layout/mathml/nsMathMLTokenFrame.h
layout/mathml/nsMathMLmactionFrame.cpp
layout/mathml/nsMathMLmactionFrame.h
layout/mathml/nsMathMLmfencedFrame.cpp
layout/mathml/nsMathMLmfencedFrame.h
layout/mathml/nsMathMLmtableFrame.cpp
layout/mathml/nsMathMLmtableFrame.h
layout/tables/nsTableColGroupFrame.cpp
layout/tables/nsTableColGroupFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsBoxFrame.h
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsMenuFrame.h
layout/xul/base/src/nsMenuPopupFrame.cpp
layout/xul/base/src/nsMenuPopupFrame.h
layout/xul/base/src/nsPopupSetFrame.cpp
layout/xul/base/src/nsPopupSetFrame.h
layout/xul/base/src/nsSliderFrame.cpp
layout/xul/base/src/nsSliderFrame.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -605,16 +605,24 @@ FindLastBlock(const nsFrameList& aList)
 inline void
 MarkIBSpecialPrevSibling(nsIFrame *aAnonymousFrame,
                          nsIFrame *aSpecialParent)
 {
   aAnonymousFrame->SetProperty(nsGkAtoms::IBSplitSpecialPrevSibling,
                                aSpecialParent, nsnull, nsnull);
 }
 
+inline void
+SetInitialSingleChild(nsIFrame* aParent, nsIFrame* aFrame)
+{
+  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
+  nsFrameList temp(aFrame);
+  aParent->SetInitialChildList(nsnull, temp);
+}
+
 // -----------------------------------------------------------
 
 static PRBool
 IsOutOfFlowList(nsIAtom* aListName)
 {
   return
     aListName == nsGkAtoms::floatList ||
     aListName == nsGkAtoms::absoluteList ||
@@ -1244,18 +1252,21 @@ nsFrameConstructorState::ProcessFrameIns
           break;
         }
         insertionPoint = f;
       }
     }
 
     rv = containingBlock->InsertFrames(aChildListName, insertionPoint,
                                        firstNewFrame);
-  }
-  aFrameItems.Clear();
+    aFrameItems.Clear();
+  }
+
+  NS_POSTCONDITION(aFrameItems.IsEmpty(), "How did that happen?");
+
   // XXXbz And if NS_FAILED(rv), what?  I guess we need to clean up the list
   // and deal with all the placeholders... but what if the placeholders aren't
   // in the document yet?  Could that happen?
   NS_ASSERTION(NS_SUCCEEDED(rv), "Frames getting lost!");
 }
 
 
 nsFrameConstructorSaveState::nsFrameConstructorSaveState()
@@ -1361,20 +1372,21 @@ AdjustFloatParentPtrs(nsIFrame*         
   }
 }
 
 /**
  * Moves frames to a new parent, updating the style context and propagating
  * relevant frame state bits. |aState| may be null, in which case the parent
  * pointers of out-of-flow frames will remain untouched.
  */
-// XXXbz it would be nice if this could take a framelist-like thing,
-// but it would need to take some sort of sublist, not nsFrameList,
-// since the frames get inserted into their new home before we call
-// this method.
+// XXXbz it would be nice if this could take a framelist-like thing, but it
+// would need to take some sort of sublist, not nsFrameList, since the frames
+// get inserted into their new home before we call this method.  This could
+// easily take an nsFrameList::Slice if SetInitialChildList and InsertFrames
+// returned one from their respective underlying framelist ops....
 static void
 MoveChildrenTo(nsFrameManager*          aFrameManager,
                nsIFrame*                aNewParent,
                nsIFrame*                aFrameList,
                nsIFrame*                aFrameListEnd,
                nsFrameConstructorState* aState,
                nsFrameConstructorState* aOuterState)
 {
@@ -2052,17 +2064,17 @@ nsCSSFrameConstructor::ConstructTable(ns
     innerFrame = NS_NewMathMLmtableFrame(mPresShell, styleContext);
   else
 #endif
     innerFrame = NS_NewTableFrame(mPresShell, styleContext);
  
   InitAndRestoreFrame(aState, content, newFrame, nsnull, innerFrame);
 
   // Put the newly created frames into the right child list
-  newFrame->SetInitialChildList(nsnull, innerFrame);
+  SetInitialSingleChild(newFrame, innerFrame);
 
   rv = aState.AddChild(newFrame, aFrameItems, content, styleContext,
                        aParentFrame);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (!mRootElementFrame) {
@@ -2281,17 +2293,17 @@ nsCSSFrameConstructor::ConstructTableCel
     // Clean up
     // XXXbz kids of this stuff need to be cleaned up too!
     cellInnerFrame->Destroy();
     newFrame->Destroy();
     return rv;
   }
 
   cellInnerFrame->SetInitialChildList(nsnull, childItems);
-  newFrame->SetInitialChildList(nsnull, cellInnerFrame);
+  SetInitialSingleChild(newFrame, cellInnerFrame);
   aFrameItems.AddChild(newFrame);
   *aNewFrame = newFrame;
 
   return NS_OK;
 }
 
 static PRBool 
 NeedFrameFor(nsIFrame*   aParentFrame,
@@ -2908,26 +2920,26 @@ nsCSSFrameConstructor::SetUpDocElementCo
   }
   
   if (isPaginated) { // paginated
     // Create the first page
     // Set the initial child lists
     nsIFrame *pageFrame, *canvasFrame;
     ConstructPageFrame(mPresShell, presContext, rootFrame, nsnull,
                        pageFrame, canvasFrame);
-    rootFrame->SetInitialChildList(nsnull, pageFrame);
+    SetInitialSingleChild(rootFrame, pageFrame);
 
     // The eventual parent of the document element frame.
     // XXX should this be set for every new page (in ConstructPageFrame)?
     mDocElementContainingBlock = canvasFrame;
     mHasRootAbsPosContainingBlock = PR_TRUE;
   }
 
   if (viewportFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
-    viewportFrame->SetInitialChildList(nsnull, newFrame);
+    SetInitialSingleChild(viewportFrame, newFrame);
   } else {
     viewportFrame->AppendFrames(nsnull, newFrame);
   }
 
   return NS_OK;
 }
 
 nsresult
@@ -2966,17 +2978,17 @@ nsCSSFrameConstructor::ConstructPageFram
   // Initialize the page content frame and force it to have a view. Also make it the
   // containing block for fixed elements which are repeated on every page.
   nsIFrame* prevPageContentFrame = nsnull;
   if (aPrevPageFrame) {
     prevPageContentFrame = aPrevPageFrame->GetFirstChild(nsnull);
     NS_ASSERTION(prevPageContentFrame, "missing page content frame");
   }
   pageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
-  aPageFrame->SetInitialChildList(nsnull, pageContentFrame);
+  SetInitialSingleChild(aPageFrame, pageContentFrame);
   mFixedContainingBlock = pageContentFrame;
 
   nsRefPtr<nsStyleContext> canvasPseudoStyle;
   canvasPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                       nsCSSAnonBoxes::canvas,
                                                       pageContentPseudoStyle);
 
   aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
@@ -2984,17 +2996,17 @@ nsCSSFrameConstructor::ConstructPageFram
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsIFrame* prevCanvasFrame = nsnull;
   if (prevPageContentFrame) {
     prevCanvasFrame = prevPageContentFrame->GetFirstChild(nsnull);
     NS_ASSERTION(prevCanvasFrame, "missing canvas frame");
   }
   aCanvasFrame->Init(nsnull, pageContentFrame, prevCanvasFrame);
-  pageContentFrame->SetInitialChildList(nsnull, aCanvasFrame);
+  SetInitialSingleChild(pageContentFrame, aCanvasFrame);
 
   return NS_OK;
 }
 
 /* static */
 nsresult
 nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell*    aPresShell, 
                                                  nsIContent*      aContent,
@@ -3121,17 +3133,17 @@ nsCSSFrameConstructor::ConstructButtonFr
     rv = ProcessChildren(aState, content, styleContext, blockFrame, PR_TRUE,
                          childItems, aStyleDisplay->IsBlockInside());
     if (NS_FAILED(rv)) return rv;
   
     // Set the areas frame's initial child lists
     blockFrame->SetInitialChildList(nsnull, childItems);
   }
 
-  buttonFrame->SetInitialChildList(nsnull, blockFrame);
+  SetInitialSingleChild(buttonFrame, blockFrame);
 
   if (isLeaf) {
     nsFrameItems  anonymousChildItems;
     // if there are any anonymous children create frames for them.  Note that
     // we're doing this using a different parent frame from the one we pass to
     // ProcessChildren!
     CreateAnonymousFrames(aState, content, buttonFrame, anonymousChildItems);
     if (anonymousChildItems.NotEmpty()) {
@@ -3424,41 +3436,41 @@ nsCSSFrameConstructor::ConstructFieldSet
     // XXXbz this is probably wrong, and once arbitrary frames can be absolute
     // containing blocks we should fix this..
     aState.PushAbsoluteContainingBlock(blockFrame, absoluteSaveState);
   }
 
   ProcessChildren(aState, content, styleContext, blockFrame, PR_TRUE,
                   childItems, PR_TRUE);
 
-  nsIFrame * child      = childItems.FirstChild();
-  nsIFrame * previous   = nsnull;
-  nsLegendFrame* legendFrame = nsnull;
-  while (nsnull != child) {
-    legendFrame = do_QueryFrame(child);
+  nsFrameItems fieldsetKids;
+  fieldsetKids.AddChild(blockFrame);
+
+  for (nsFrameList::FrameLinkEnumerator link(childItems);
+       !link.AtEnd();
+       link.Next()) {
+    nsLegendFrame* legendFrame = do_QueryFrame(link.NextFrame());
     if (legendFrame) {
       // We want the legend to be the first frame in the fieldset child list.
       // That way the EventStateManager will do the right thing when tabbing
       // from a selection point within the legend (bug 236071), which is
       // used for implementing legend access keys (bug 81481).
       // GetAdjustedParentFrame() below depends on this frame order.
-      childItems.RemoveFrame(child, previous);
-      legendFrame->SetNextSibling(blockFrame);
-      legendFrame->SetParent(newFrame);
+      childItems.RemoveFrame(link.NextFrame(), link.PrevFrame());
+      // Make sure to reparent the legend so it has the fieldset as the parent.
+      fieldsetKids.InsertFrame(newFrame, nsnull, legendFrame);
       break;
     }
-    previous = child;
-    child = child->GetNextSibling();
-  }
-
-  // Set the scrolled frame's initial child lists
+  }
+
+  // Set the inner frame's initial child lists
   blockFrame->SetInitialChildList(nsnull, childItems);
 
-  // Set the scroll frame's initial child list
-  newFrame->SetInitialChildList(nsnull, legendFrame ? legendFrame : blockFrame);
+  // Set the outer frame's initial child list
+  newFrame->SetInitialChildList(nsnull, fieldsetKids);
 
   // our new frame returned is the top frame which is the list frame. 
   *aNewFrame = newFrame; 
 
   return NS_OK;
 }
 
 static nsIFrame*
@@ -4722,17 +4734,18 @@ nsCSSFrameConstructor::FlushAccumulatedB
   if (NS_UNLIKELY(!blockFrame))
     return NS_ERROR_OUT_OF_MEMORY;
 
   InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, blockFrame);
   ReparentFrames(aState.mFrameManager, blockFrame, *aBlockItems);
   // abs-pos and floats are disabled in MathML children so we don't have to
   // worry about messing up those.
   blockFrame->SetInitialChildList(nsnull, *aBlockItems);
-  *aBlockItems = nsFrameItems();
+  NS_ASSERTION(aBlockItems->IsEmpty(), "What happened?");
+  aBlockItems->Clear();
   aNewItems->AddChild(blockFrame);
   return NS_OK;
 }
 
 // Only <math> elements can be floated or positioned.  All other MathML
 // should be in-flow.
 #define SIMPLE_MATHML_CREATE(_tag, _func)                               \
   { &nsGkAtoms::_tag,                                                   \
@@ -8312,17 +8325,17 @@ nsCSSFrameConstructor::CreateContinuingF
                                  &continuingBlockFrame);
       if (NS_FAILED(rv)) {
         newFrame->Destroy();
         *aContinuingFrame = nsnull;
         return rv;
       }
 
       // Set the table cell's initial child list
-      newFrame->SetInitialChildList(nsnull, continuingBlockFrame);
+      SetInitialSingleChild(newFrame, continuingBlockFrame);
     }
   
   } else if (nsGkAtoms::lineFrame == frameType) {
     newFrame = NS_NewFirstLineFrame(shell, styleContext);
 
     if (newFrame) {
       newFrame->Init(content, aParentFrame, aFrame);
       nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
@@ -8380,17 +8393,17 @@ nsCSSFrameConstructor::CreateContinuingF
       rv = CreateContinuingFrame(aPresContext, blockFrame, newFrame,
                                  &continuingBlockFrame);
       if (NS_FAILED(rv)) {
         newFrame->Destroy();
         *aContinuingFrame = nsnull;
         return rv;
       }
       // Set the fieldset's initial child list
-      newFrame->SetInitialChildList(nsnull, continuingBlockFrame);
+      SetInitialSingleChild(newFrame, continuingBlockFrame);
     }
   } else if (nsGkAtoms::legendFrame == frameType) {
     newFrame = NS_NewLegendFrame(shell, styleContext);
 
     if (newFrame) {
       newFrame->Init(content, aParentFrame, aFrame);
       nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
     }
@@ -9602,18 +9615,19 @@ nsCSSFrameConstructor::ProcessChildren(n
     // a real block placed here wouldn't get those set on it.
 
     InitAndRestoreFrame(aState, aContent, aFrame, nsnull,
                         blockFrame, PR_FALSE);
 
     NS_ASSERTION(!blockFrame->HasView(), "need to do view reparenting");
     ReparentFrames(aState.mFrameManager, blockFrame, aFrameItems);
 
-    blockFrame->AppendFrames(nsnull, aFrameItems.FirstChild());
-    aFrameItems = nsFrameItems();
+    blockFrame->SetInitialChildList(nsnull, aFrameItems);
+    NS_ASSERTION(aFrameItems.IsEmpty(), "How did that happen?");
+    aFrameItems.Clear();
     aFrameItems.AddChild(blockFrame);
 
     aFrame->AddStateBits(NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK);
   }
 
   return rv;
 }
 
@@ -9982,17 +9996,17 @@ nsCSSFrameConstructor::CreateFloatingLet
   // letter frame and will have the float property set on it; the text
   // frame shouldn't have that set).
   nsRefPtr<nsStyleContext> textSC;
   textSC = styleSet->ResolveStyleForNonElement(aStyleContext);
   aTextFrame->SetStyleContextWithoutNotification(textSC);
   InitAndRestoreFrame(aState, aTextContent, letterFrame, nsnull, aTextFrame);
 
   // And then give the text frame to the letter frame
-  letterFrame->SetInitialChildList(nsnull, aTextFrame);
+  SetInitialSingleChild(letterFrame, aTextFrame);
 
   // See if we will need to continue the text frame (does it contain
   // more than just the first-letter text or not?) If it does, then we
   // create (in advance) a continuation frame for it.
   nsIFrame* nextTextFrame = nsnull;
   if (NeedFirstLetterContinuation(aTextContent)) {
     // Create continuation
     rv = CreateContinuingFrame(aState.mPresContext, aTextFrame, aParentFrame,
@@ -10092,17 +10106,17 @@ nsCSSFrameConstructor::CreateLetterFrame
         // content for a non-text frame (because we want its primary frame to
         // be a text frame).  So use its parent for the first-letter.
         nsIContent* letterContent = aTextContent->GetParent();
         letterFrame->Init(letterContent, aParentFrame, nsnull);
 
         InitAndRestoreFrame(state, aTextContent, letterFrame, nsnull,
                             textFrame);
 
-        letterFrame->SetInitialChildList(nsnull, textFrame);
+        SetInitialSingleChild(letterFrame, textFrame);
         aResult.Clear();
         aResult.AddChild(letterFrame);
         aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
       }
     }
   }
 
   return NS_OK;
@@ -10553,17 +10567,17 @@ nsCSSFrameConstructor::ConstructBlock(ns
     // See if we need to create a view
     nsHTMLContainerFrame::CreateViewForFrame(columnSetFrame, PR_FALSE);
     blockStyle = mPresShell->StyleSet()->
       ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::columnContent,
                             aStyleContext);
     parent = columnSetFrame;
     *aNewFrame = columnSetFrame;
 
-    columnSetFrame->SetInitialChildList(nsnull, blockFrame);
+    SetInitialSingleChild(columnSetFrame, blockFrame);
   }
 
   blockFrame->SetStyleContextWithoutNotification(blockStyle);
   InitAndRestoreFrame(aState, aContent, parent, nsnull, blockFrame);
 
   nsresult rv = aState.AddChild(*aNewFrame, aFrameItems, aContent,
                                 aStyleContext,
                                 aContentParentFrame ? aContentParentFrame :
@@ -10717,28 +10731,31 @@ nsCSSFrameConstructor::ConstructInline(n
   nsFrameItems blockKids = childItems.ExtractHead(lastBlock);
 
   if (blockFrame->HasView() || newFrame->HasView()) {
     // Move the block's child frames into the new view
     nsHTMLContainerFrame::ReparentFrameViewList(aState.mPresContext, blockKids,
                                                 newFrame, blockFrame);
   }
 
+  // Save the first frame in blockKids for the MoveChildrenTo call, since
+  // SetInitialChildList will empty blockKids.
+  nsIFrame* firstBlock = blockKids.FirstChild();
   blockFrame->SetInitialChildList(nsnull, blockKids);
 
   nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                 GetAbsoluteContainingBlock(blockFrame),
                                 GetFloatContainingBlock(blockFrame));
 
   // If we have an inline between two blocks all inside an inline and the inner
   // inline contains a float, the float will end up in the float list of the
   // parent block of the inline, but its parent pointer will be the anonymous
   // block we create...  AdjustFloatParentPtrs() deals with this by moving the
   // float from the outer state |aState| to the inner |state|.
-  MoveChildrenTo(state.mFrameManager, blockFrame, blockKids.FirstChild(), nsnull,
+  MoveChildrenTo(state.mFrameManager, blockFrame, firstBlock, nsnull,
                  &state, &aState);
 
   // What's left in childItems belongs to our trailing inline frame
   nsIFrame* inlineFrame;
   if (positioned) {
     inlineFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
   }
   else {
@@ -10808,23 +10825,25 @@ nsCSSFrameConstructor::MoveFramesToEndOf
       newFirstChild->GetParent()->HasView()) {
     // Move the frames into the new view
     nsHTMLContainerFrame::ReparentFrameViewList(aState.mPresContext,
                                                 aFramesToMove,
                                                 newFirstChild->GetParent(),
                                                 aExistingEndFrame);
   }
 
-  // Reparent (cheaply) the child frames
+  // Reparent (cheaply) the child frames.  Have to grab the frame pointers
+  // for MoveChildrenTo now, since aFramesToMove will get cleared when we add
+  // the frames to aExistingEndFrame.  We already have newFirstChild.
   nsIFrame* existingFirstChild = aExistingEndFrame->GetFirstChild(nsnull);
   if (!existingFirstChild &&
       (aExistingEndFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     aExistingEndFrame->SetInitialChildList(nsnull, aFramesToMove);
   } else {
-    aExistingEndFrame->InsertFrames(nsnull, nsnull, aFramesToMove);
+    aExistingEndFrame->InsertFrames(nsnull, nsnull, aFramesToMove.FirstChild());
   }
   nsFrameConstructorState* startState = aTargetState ? &aState : nsnull;
   MoveChildrenTo(aState.mFrameManager, aExistingEndFrame, newFirstChild,
                  existingFirstChild, aTargetState, startState);
 }
 
 void
 nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState,
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -152,22 +152,20 @@ struct nsFrameItems : public nsFrameList
   nsFrameItems ExtractTail(FrameLinkEnumerator& aLink) {
     nsIFrame* newLastChild = lastChild;
     lastChild = aLink.PrevFrame();
     return nsFrameItems(nsFrameList::ExtractTail(aLink),
                         newLastChild);
   }
 
   void Clear() {
-    mFirstChild = lastChild = nsnull;
+    nsFrameList::Clear();
+    lastChild = nsnull;
   }
 
-  // For now, until we change some SetInitialChildList signatures
-  operator nsIFrame* ()  { return FirstChild(); }
-
 private:
   // Not implemented; shouldn't be called
   void SetFrames(nsIFrame* aFrameList);
   void AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList);
   Slice AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList);
   void AppendFrame(nsIFrame* aParent, nsIFrame* aFrame);
   PRBool RemoveFirstChild();
   void InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1191,17 +1191,18 @@ nsComboboxControlFrame::CreateFrameFor(n
   if (NS_FAILED(rv)) {
     mDisplayFrame->Destroy();
     mDisplayFrame = nsnull;
     mTextFrame->Destroy();
     mTextFrame = nsnull;
     return nsnull;
   }
 
-  mDisplayFrame->SetInitialChildList(nsnull, mTextFrame);
+  nsFrameList textList(mTextFrame);
+  mDisplayFrame->SetInitialChildList(nsnull, textList);
   return mDisplayFrame;
 }
 
 void
 nsComboboxControlFrame::Destroy()
 {
   // Revoke any pending RedisplayTextEvent
   mRedisplayTextEvent.Revoke();
@@ -1236,33 +1237,32 @@ nsComboboxControlFrame::GetChildList(nsI
   if (nsGkAtoms::selectPopupList == aListName) {
     return mPopupFrames;
   }
   return nsBlockFrame::GetChildList(aListName);
 }
 
 NS_IMETHODIMP
 nsComboboxControlFrame::SetInitialChildList(nsIAtom*        aListName,
-                                            nsIFrame*       aChildList)
+                                            nsFrameList&    aChildList)
 {
   nsresult rv = NS_OK;
   if (nsGkAtoms::selectPopupList == aListName) {
     mPopupFrames.SetFrames(aChildList);
   } else {
-    rv = nsBlockFrame::SetInitialChildList(aListName, aChildList);
-
-    for (nsIFrame * child = aChildList; child;
-         child = child->GetNextSibling()) {
-      nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(child->GetContent());
+    for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
+      nsCOMPtr<nsIFormControl> formControl =
+        do_QueryInterface(e.get()->GetContent());
       if (formControl && formControl->GetType() == NS_FORM_INPUT_BUTTON) {
-        mButtonFrame = child;
+        mButtonFrame = e.get();
         break;
       }
     }
     NS_ASSERTION(mButtonFrame, "missing button frame in initial child list");
+    rv = nsBlockFrame::SetInitialChildList(aListName, aChildList);
   }
   return rv;
 }
 
 #define NS_COMBO_FRAME_POPUP_LIST_INDEX   (NS_BLOCK_LIST_COUNT)
 
 nsIAtom*
 nsComboboxControlFrame::GetAdditionalChildListName(PRInt32 aIndex) const
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -138,17 +138,17 @@ public:
   }
 
 #ifdef NS_DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
   virtual void Destroy();
   virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
   virtual nsIFrame* GetContentInsertionFrame();
 
   // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
   virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; 
   /**
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -65,17 +65,17 @@
 class nsLegendFrame;
 
 class nsFieldSetFrame : public nsHTMLContainerFrame {
 public:
 
   nsFieldSetFrame(nsStyleContext* aContext);
 
   NS_IMETHOD SetInitialChildList(nsIAtom*       aListName,
-                                 nsIFrame*      aChildList);
+                                 nsFrameList&   aChildList);
 
   NS_HIDDEN_(nscoord)
     GetIntrinsicWidth(nsIRenderingContext* aRenderingContext,
                       nsLayoutUtils::IntrinsicWidthType);
   virtual nscoord GetMinWidth(nsIRenderingContext* aRenderingContext);
   virtual nscoord GetPrefWidth(nsIRenderingContext* aRenderingContext);
   virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
@@ -149,24 +149,25 @@ nsFieldSetFrame::GetType() const
 PRBool
 nsFieldSetFrame::IsContainingBlock() const
 {
   return PR_TRUE;
 }
 
 NS_IMETHODIMP
 nsFieldSetFrame::SetInitialChildList(nsIAtom*       aListName,
-                                     nsIFrame*      aChildList)
+                                     nsFrameList&   aChildList)
 {
   // Get the content and legend frames.
-  if (aChildList->GetNextSibling()) {
-    mContentFrame = aChildList->GetNextSibling();
-    mLegendFrame  = aChildList;
+  if (!aChildList.OnlyChild()) {
+    NS_ASSERTION(aChildList.GetLength() == 2, "Unexpected child list");
+    mContentFrame = aChildList.LastChild();
+    mLegendFrame  = aChildList.FirstChild();
   } else {
-    mContentFrame = aChildList;
+    mContentFrame = aChildList.FirstChild();
     mLegendFrame  = nsnull;
   }
 
   // Queue up the frames for the content frame
   return nsHTMLContainerFrame::SetInitialChildList(nsnull, aChildList);
 }
 
 class nsDisplayFieldSetBorderBackground : public nsDisplayItem {
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -144,17 +144,16 @@ nsGfxButtonControlFrame::CreateFrameFor(
     textStyleContext = presContext->StyleSet()->
       ResolveStyleForNonElement(mStyleContext);
 
     if (textStyleContext) {
       newFrame = NS_NewTextFrame(presContext->PresShell(), textStyleContext);
       if (newFrame) {
         // initialize the text frame
         newFrame->Init(mTextContent, parentFrame, nsnull);
-        newFrame->SetInitialChildList(nsnull, nsnull);
       }
     }
   }
 
   return newFrame;
 }
 
 nsresult
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -1089,17 +1089,17 @@ nsListControlFrame::HandleEvent(nsPresCo
 
   return nsHTMLScrollFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
 }
 
 
 //---------------------------------------------------------
 NS_IMETHODIMP
 nsListControlFrame::SetInitialChildList(nsIAtom*       aListName,
-                                        nsIFrame*      aChildList)
+                                        nsFrameList&   aChildList)
 {
   // First check to see if all the content has been added
   mIsAllContentHere = mContent->IsDoneAddingChildren();
   if (!mIsAllContentHere) {
     mIsAllFramesHere    = PR_FALSE;
     mHasBeenInitialized = PR_FALSE;
   }
   nsresult rv = nsHTMLScrollFrame::SetInitialChildList(aListName, aChildList);
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -80,17 +80,17 @@ public:
   NS_DECL_QUERYFRAME
 
     // nsIFrame
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
                          nsGUIEvent* aEvent,
                          nsEventStatus* aEventStatus);
   
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
   virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
 
   NS_IMETHOD Reflow(nsPresContext*          aCX,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -2737,17 +2737,17 @@ nsTextControlFrame::SetValue(const nsASt
     }
   }
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsTextControlFrame::SetInitialChildList(nsIAtom*        aListName,
-                                        nsIFrame*       aChildList)
+                                        nsFrameList&    aChildList)
 {
   nsresult rv = nsBoxFrame::SetInitialChildList(aListName, aChildList);
 
   //look for scroll view below this frame go along first child list
   nsIFrame* first = GetFirstChild(nsnull);
 
   // Mark the scroll frame as being a reflow root. This will allow
   // incremental reflows to be initiated at the scroll frame, rather
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -122,17 +122,17 @@ public:
 
   // Utility methods to set current widget state
 
   // Be careful when using this method.
   // Calling it may cause |this| to be deleted.
   // In that case the method returns an error value.
   nsresult SetValue(const nsAString& aValue);
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
 //==== BEGIN NSIFORMCONTROLFRAME
   virtual void SetFocus(PRBool aOn , PRBool aRepaint); 
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
   virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const; 
 
 
 //==== END NSIFORMCONTROLFRAME
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -50,17 +50,17 @@
 
 #ifdef DEBUG
 #include "nsBlockFrame.h"
 #endif
 
 nsresult
 nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame*       aDelegatingFrame,
                                                nsIAtom*        aListName,
-                                               nsIFrame*       aChildList)
+                                               nsFrameList&    aChildList)
 {
   NS_PRECONDITION(GetChildListName() == aListName, "unexpected child list name");
 #ifdef NS_DEBUG
   nsFrame::VerifyDirtyBitSet(aChildList);
 #endif
   mAbsoluteFrames.SetFrames(aChildList);
   return NS_OK;
 }
--- a/layout/generic/nsAbsoluteContainingBlock.h
+++ b/layout/generic/nsAbsoluteContainingBlock.h
@@ -83,17 +83,17 @@ public:
 #ifdef DEBUG
   nsIAtom* GetChildListName() const { return mChildListName; }
 #endif
 
   const nsFrameList& GetChildList() const { return mAbsoluteFrames; }
 
   nsresult SetInitialChildList(nsIFrame*       aDelegatingFrame,
                                nsIAtom*        aListName,
-                               nsIFrame*       aChildList);
+                               nsFrameList&    aChildList);
   nsresult AppendFrames(nsIFrame*      aDelegatingFrame,
                         nsIAtom*       aListName,
                         nsIFrame*      aFrameList);
   nsresult InsertFrames(nsIFrame*      aDelegatingFrame,
                         nsIAtom*       aListName,
                         nsIFrame*      aPrevFrame,
                         nsIFrame*      aFrameList);
   nsresult RemoveFrame(nsIFrame*      aDelegatingFrame,
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1030,17 +1030,17 @@ nsBlockFrame::Reflow(nsPresContext*     
         nsAutoOOFFrameList oofs(this);
         oofs.mList.AppendFrames(nsnull, floats.FirstChild());
       }
       else {
         mLines.push_back(newLine);
         nsLineList::iterator nextToLastLine = ----end_lines();
         PushLines(state, nextToLastLine);
       }
-      state.mOverflowPlaceholders.SetFrames(nsnull);
+      state.mOverflowPlaceholders.Clear();
     }
     state.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
     if (NS_FRAME_IS_COMPLETE(state.mReflowStatus))
       NS_FRAME_SET_OVERFLOW_INCOMPLETE(state.mReflowStatus);
   }
 
   if (!NS_FRAME_IS_FULLY_COMPLETE(state.mReflowStatus)) {
     if (GetOverflowLines()) {
@@ -4490,33 +4490,33 @@ nsBlockFrame::DrainOverflowLines(nsBlock
 
       // make the overflow out-of-flow frames mine too
       nsAutoOOFFrameList oofs(prevBlock);
       if (oofs.mList.NotEmpty()) {
         for (nsIFrame* f = oofs.mList.FirstChild(); f; f = f->GetNextSibling()) {
           ReparentFrame(f, prevBlock, this);
         }
         mFloats.InsertFrames(nsnull, nsnull, oofs.mList.FirstChild());
-        oofs.mList.SetFrames(nsnull);
+        oofs.mList.Clear();
       }
     }
     
     // The lines on the overflow list have already been marked dirty and their
     // previous margins marked dirty also.
   }
 
   // Don't need to reparent frames in our own overflow lines/oofs, because they're
   // already ours. But we should put overflow floats back in mFloats.
   ourOverflowLines = RemoveOverflowLines();
   if (ourOverflowLines) {
     nsAutoOOFFrameList oofs(this);
     if (oofs.mList.NotEmpty()) {
       // The overflow floats go after our regular floats
       mFloats.AppendFrames(nsnull, oofs.mList.FirstChild());
-      oofs.mList.SetFrames(nsnull);
+      oofs.mList.Clear();
     }
   }
 
   if (!overflowLines && !ourOverflowLines) {
     // nothing to do; always the case for non-constrained-height reflows
     return PR_FALSE;
   }
 
@@ -6414,17 +6414,17 @@ nsBlockFrame::Init(nsIContent*      aCon
       aPrevInFlow->GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
     AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsBlockFrame::SetInitialChildList(nsIAtom*        aListName,
-                                  nsIFrame*       aChildList)
+                                  nsFrameList&    aChildList)
 {
   nsresult rv = NS_OK;
 
   if (nsGkAtoms::absoluteList == aListName) {
     mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
   }
   else if (nsGkAtoms::floatList == aListName) {
     mFloats.SetFrames(aChildList);
@@ -6454,16 +6454,17 @@ nsBlockFrame::SetInitialChildList(nsIAto
                  ((mState & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0),
                  "NS_BLOCK_HAS_FIRST_LETTER_STYLE state out of sync");
 #endif
     
     rv = AddFrames(aChildList, nsnull);
     if (NS_FAILED(rv)) {
       return rv;
     }
+    aChildList.Clear();
 
     // Create list bullet if this is a list-item. Note that this is done
     // here so that RenumberLists will work (it needs the bullets to
     // store the bullet numbers).
     const nsStyleDisplay* styleDisplay = GetStyleDisplay();
     if ((nsnull == GetPrevInFlow()) &&
         (NS_STYLE_DISPLAY_LIST_ITEM == styleDisplay->mDisplay) &&
         (nsnull == mBullet)) {
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -163,17 +163,17 @@ public:
   // nsQueryFrame
   NS_DECL_QUERYFRAME
 
   // nsIFrame
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
   NS_IMETHOD  AppendFrames(nsIAtom*        aListName,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  InsertFrames(nsIAtom*        aListName,
                            nsIFrame*       aPrevFrame,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  RemoveFrame(nsIAtom*        aListName,
                           nsIFrame*       aOldFrame);
   virtual nsFrameList GetChildList(nsIAtom* aListName) const;
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -52,17 +52,17 @@
 #include "nsDisplayList.h"
 #include "nsCSSRendering.h"
 
 class nsColumnSetFrame : public nsHTMLContainerFrame {
 public:
   nsColumnSetFrame(nsStyleContext* aContext);
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   NS_IMETHOD Reflow(nsPresContext* aPresContext,
                     nsHTMLReflowMetrics& aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus& aStatus);
                                
   NS_IMETHOD  AppendFrames(nsIAtom*        aListName,
                            nsIFrame*       aFrameList);
@@ -282,20 +282,20 @@ nsColumnSetFrame::PaintColumnRule(nsIRen
 
     child = nextSibling;
     nextSibling = nextSibling->GetNextSibling();
   }
 }
 
 NS_IMETHODIMP
 nsColumnSetFrame::SetInitialChildList(nsIAtom*        aListName,
-                                      nsIFrame*       aChildList)
+                                      nsFrameList&    aChildList)
 {
   NS_ASSERTION(!aListName, "Only default child list supported");
-  NS_ASSERTION(aChildList && !aChildList->GetNextSibling(),
+  NS_ASSERTION(aChildList.OnlyChild(),
                "initial child list must have exactly one child");
   // Queue up the frames for the content frame
   return nsHTMLContainerFrame::SetInitialChildList(nsnull, aChildList);
 }
 
 static nscoord
 GetAvailableContentWidth(const nsHTMLReflowState& aReflowState)
 {
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -96,18 +96,18 @@ nsContainerFrame::Init(nsIContent* aCont
     // has a child with a view so that we'll properly reposition it.
     if (aPrevInFlow->GetStateBits() & NS_FRAME_HAS_CHILD_WITH_VIEW)
       AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
   }
   return rv;
 }
 
 NS_IMETHODIMP
-nsContainerFrame::SetInitialChildList(nsIAtom*  aListName,
-                                      nsIFrame* aChildList)
+nsContainerFrame::SetInitialChildList(nsIAtom*     aListName,
+                                      nsFrameList& aChildList)
 {
   nsresult  result;
   if (!mFrames.IsEmpty()) {
     // We already have child frames which means we've already been
     // initialized
     NS_NOTREACHED("unexpected second call to SetInitialChildList");
     result = NS_ERROR_UNEXPECTED;
   } else if (aListName) {
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -72,18 +72,18 @@ class nsOverflowContinuationTracker;
  */
 class nsContainerFrame : public nsSplittableFrame
 {
 public:
   // nsIFrame overrides
   NS_IMETHOD Init(nsIContent* aContent,
                   nsIFrame*   aParent,
                   nsIFrame*   aPrevInFlow);
-  NS_IMETHOD SetInitialChildList(nsIAtom*  aListName,
-                                 nsIFrame* aChildList);
+  NS_IMETHOD SetInitialChildList(nsIAtom*     aListName,
+                                 nsFrameList& aChildList);
   NS_IMETHOD AppendFrames(nsIAtom*  aListName,
                           nsIFrame* aFrameList);
   NS_IMETHOD InsertFrames(nsIAtom*  aListName,
                           nsIFrame* aPrevFrame,
                           nsIFrame* aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*  aListName,
                          nsIFrame* aOldFrame);
 
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -92,26 +92,27 @@ nsFirstLetterFrame::Init(nsIContent*    
         SetStyleContextWithoutNotification(newSC);
     }
   }
 
   return nsFirstLetterFrameSuper::Init(aContent, aParent, aPrevInFlow);
 }
 
 NS_IMETHODIMP
-nsFirstLetterFrame::SetInitialChildList(nsIAtom*  aListName,
-                                        nsIFrame* aChildList)
+nsFirstLetterFrame::SetInitialChildList(nsIAtom*     aListName,
+                                        nsFrameList& aChildList)
 {
-  mFrames.SetFrames(aChildList);
   nsFrameManager *frameManager = PresContext()->FrameManager();
 
-  for (nsIFrame* frame = aChildList; frame; frame = frame->GetNextSibling()) {
-    NS_ASSERTION(frame->GetParent() == this, "Unexpected parent");
-    frameManager->ReParentStyleContext(frame);
+  for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
+    NS_ASSERTION(e.get()->GetParent() == this, "Unexpected parent");
+    frameManager->ReParentStyleContext(e.get());
   }
+
+  mFrames.SetFrames(aChildList);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFirstLetterFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
                                                   PRBool inHint,
                                                   PRInt32* outFrameContentOffset,
                                                   nsIFrame **outChildFrame)
--- a/layout/generic/nsFirstLetterFrame.h
+++ b/layout/generic/nsFirstLetterFrame.h
@@ -47,17 +47,17 @@
 class nsFirstLetterFrame : public nsFirstLetterFrameSuper {
 public:
   nsFirstLetterFrame(nsStyleContext* aContext) : nsHTMLContainerFrame(aContext) {}
 
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 #ifdef NS_DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const;
 #endif
   virtual nsIAtom* GetType() const;
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
     if (!GetStyleDisplay()->IsFloating())
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -395,25 +395,25 @@ nsFrame::Init(nsIContent*      aContent,
 
   if (IsBoxWrapped())
     InitBoxMetrics(PR_FALSE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsFrame::SetInitialChildList(nsIAtom*        aListName,
-                                           nsIFrame*       aChildList)
+                                           nsFrameList&    aChildList)
 {
   // XXX This shouldn't be getting called at all, but currently is for backwards
   // compatility reasons...
 #if 0
   NS_ERROR("not a container");
   return NS_ERROR_UNEXPECTED;
 #else
-  NS_ASSERTION(nsnull == aChildList, "not a container");
+  NS_ASSERTION(aChildList.IsEmpty(), "not a container");
   return NS_OK;
 #endif
 }
 
 NS_IMETHODIMP
 nsFrame::AppendFrames(nsIAtom*        aListName,
                       nsIFrame*       aFrameList)
 {
@@ -6867,20 +6867,21 @@ nsFrame::TraceMsg(const char* aFormatStr
 
     char tagbuf[40];
     GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
     PR_LogPrint("%s: %s", tagbuf, argbuf);
   }
 }
 
 void
-nsFrame::VerifyDirtyBitSet(nsIFrame* aFrameList)
-{
-  for (nsIFrame*f = aFrameList; f; f = f->GetNextSibling()) {
-    NS_ASSERTION(f->GetStateBits() & NS_FRAME_IS_DIRTY, "dirty bit not set");
+nsFrame::VerifyDirtyBitSet(const nsFrameList& aFrameList)
+{
+  for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
+    NS_ASSERTION(e.get()->GetStateBits() & NS_FRAME_IS_DIRTY,
+                 "dirty bit not set");
   }
 }
 
 // Start Display Reflow
 #ifdef DEBUG
 
 DR_cookie::DR_cookie(nsPresContext*          aPresContext,
                      nsIFrame*                aFrame, 
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -158,18 +158,18 @@ public:
 
   // nsQueryFrame
   NS_DECL_QUERYFRAME
 
   // nsIFrame
   NS_IMETHOD  Init(nsIContent*      aContent,
                    nsIFrame*        aParent,
                    nsIFrame*        asPrevInFlow);
-  NS_IMETHOD  SetInitialChildList(nsIAtom*        aListName,
-                                  nsIFrame*       aChildList);
+  NS_IMETHOD  SetInitialChildList(nsIAtom*           aListName,
+                                  nsFrameList&       aChildList);
   NS_IMETHOD  AppendFrames(nsIAtom*        aListName,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  InsertFrames(nsIAtom*        aListName,
                            nsIFrame*       aPrevFrame,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  RemoveFrame(nsIAtom*        aListName,
                           nsIFrame*       aOldFrame);
   virtual void Destroy();
@@ -423,17 +423,17 @@ public:
    * level field.
    */
   void Trace(const char* aMethod, PRBool aEnter);
   void Trace(const char* aMethod, PRBool aEnter, nsReflowStatus aStatus);
   void TraceMsg(const char* fmt, ...);
 
   // Helper function that verifies that each frame in the list has the
   // NS_FRAME_IS_DIRTY bit set
-  static void VerifyDirtyBitSet(nsIFrame* aFrameList);
+  static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
 
   // Helper function to return the index in parent of the frame's content
   // object. Returns -1 on error or if the frame doesn't have a content object
   static PRInt32 ContentIndexInContainer(const nsIFrame* aFrame);
 
   static void IndentBy(FILE* out, PRInt32 aIndent) {
     while (--aIndent >= 0) fputs("  ", out);
   }
--- a/layout/generic/nsFrameList.h
+++ b/layout/generic/nsFrameList.h
@@ -86,16 +86,24 @@ public:
 
   void SetFrames(nsIFrame* aFrameList) {
     mFirstChild = aFrameList;
 #ifdef DEBUG
     CheckForLoops();
 #endif
   }
 
+  void Clear() { SetFrames(nsnull); }
+
+  void SetFrames(nsFrameList& aFrameList) {
+    NS_PRECONDITION(!mFirstChild, "Losing frames");
+    mFirstChild = aFrameList.FirstChild();
+    aFrameList.Clear();
+  }
+
   class Slice;
 
   /**
    * Appends frames from aFrameList to this list. If aParent
    * is not null, reparents the newly-added frames.
    */
   void AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList);
 
@@ -103,17 +111,17 @@ public:
    * Appends aFrameList to this list.  If aParent is not null,
    * reparents the newly added frames.  Clears out aFrameList and
    * returns a list slice represening the newly-appended frames.
    */
   Slice AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList) {
     NS_PRECONDITION(!aFrameList.IsEmpty(), "Unexpected empty list");
     nsIFrame* firstNewFrame = aFrameList.FirstChild();
     AppendFrames(aParent, firstNewFrame);
-    aFrameList.mFirstChild = nsnull;
+    aFrameList.Clear();
     return Slice(*this, firstNewFrame, nsnull);
   }
 
   void AppendFrame(nsIFrame* aParent, nsIFrame* aFrame);
 
   /**
    * Take aFrame out of the frame list. This also disconnects aFrame
    * from the sibling list. This will return PR_FALSE if aFrame is
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -472,24 +472,24 @@ nsHTMLFramesetFrame::Init(nsIContent*   
     mChildCount++;
   }
 
   mNonBorderChildCount = mChildCount;
   return rv;
 }
 
 NS_IMETHODIMP
-nsHTMLFramesetFrame::SetInitialChildList(nsIAtom*  aListName,
-                                         nsIFrame* aChildList)
+nsHTMLFramesetFrame::SetInitialChildList(nsIAtom*     aListName,
+                                         nsFrameList& aChildList)
 {
   // We do this weirdness where we create our child frames in Init().  On the
-  // other hand, we're going to get a SetInitialChildList() with a null list
-  // and list name after the frame constructor is done creating us.  So just
-  // ignore that call.
-  if (!aListName && !aChildList) {
+  // other hand, we're going to get a SetInitialChildList() with an empty list
+  // and null list name after the frame constructor is done creating us.  So
+  // just ignore that call.
+  if (!aListName && aChildList.IsEmpty()) {
     return NS_OK;
   }
 
   return nsHTMLContainerFrame::SetInitialChildList(aListName, aChildList);
 }
 
 // XXX should this try to allocate twips based on an even pixel boundary?
 void nsHTMLFramesetFrame::Scale(nscoord  aDesired, 
--- a/layout/generic/nsFrameSetFrame.h
+++ b/layout/generic/nsFrameSetFrame.h
@@ -111,18 +111,18 @@ public:
   virtual ~nsHTMLFramesetFrame();
 
   NS_DECL_QUERYFRAME
 
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
 
-  NS_IMETHOD SetInitialChildList(nsIAtom*  aListName,
-                                 nsIFrame* aChildList);
+  NS_IMETHOD SetInitialChildList(nsIAtom*     aListName,
+                                 nsFrameList& aChildList);
 
   static PRBool  gDragInProgress;
 
   void GetSizeOfChild(nsIFrame* aChild, nsSize& aSize);
 
   void GetSizeOfChildAt(PRInt32  aIndexInParent, 
                         nsSize&  aSize, 
                         nsIntPoint& aCellIndex);
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -153,19 +153,18 @@ nsHTMLScrollFrame::CreateAnonymousConten
 void
 nsHTMLScrollFrame::Destroy()
 {
   mInner.Destroy();
   nsHTMLContainerFrame::Destroy();
 }
 
 NS_IMETHODIMP
-nsHTMLScrollFrame::
-SetInitialChildList(nsIAtom*       aListName,
-                    nsIFrame*      aChildList)
+nsHTMLScrollFrame::SetInitialChildList(nsIAtom*     aListName,
+                                       nsFrameList& aChildList)
 {
   nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aListName, aChildList);
   mInner.CreateScrollableView();
   mInner.ReloadChildFrames();
 
   // listen for scroll events.
   mInner.GetScrollableView()->AddScrollPositionListener(&mInner);
 
@@ -1041,17 +1040,17 @@ void
 nsXULScrollFrame::Destroy()
 {
   mInner.Destroy();
   nsBoxFrame::Destroy();
 }
 
 NS_IMETHODIMP
 nsXULScrollFrame::SetInitialChildList(nsIAtom*        aListName,
-                                      nsIFrame*       aChildList)
+                                      nsFrameList&    aChildList)
 {
   nsresult rv = nsBoxFrame::SetInitialChildList(aListName, aChildList);
 
   mInner.CreateScrollableView();
   mInner.ReloadChildFrames();
 
   // listen for scroll events.
   mInner.GetScrollableView()->AddScrollPositionListener(&mInner);
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -250,17 +250,17 @@ class nsHTMLScrollFrame : public nsHTMLC
 public:
   friend nsIFrame* NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRBool aIsRoot);
 
   NS_DECL_QUERYFRAME
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) {
     return mInner.BuildDisplayList(aBuilder, aDirtyRect, aLists);
   }
 
   PRBool TryLayout(ScrollReflowState* aState,
@@ -437,17 +437,17 @@ class nsXULScrollFrame : public nsBoxFra
 public:
   NS_DECL_QUERYFRAME
 
   friend nsIFrame* NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRBool aIsRoot);
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) {
     return mInner.BuildDisplayList(aBuilder, aDirtyRect, aLists);
   }
 
   // XXXldb Is this actually used?
--- a/layout/generic/nsHTMLFrame.cpp
+++ b/layout/generic/nsHTMLFrame.cpp
@@ -92,17 +92,17 @@ public:
   NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
 
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        aPrevInFlow);
   virtual void Destroy();
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame);
 
@@ -269,22 +269,22 @@ CanvasFrame::SetHasFocus(PRBool aHasFocu
     mDoPaintFocus = aHasFocus;
     mViewManager->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CanvasFrame::SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList)
+                                 nsFrameList&    aChildList)
 {
   if (nsGkAtoms::absoluteList == aListName)
     return mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
 
-  NS_ASSERTION(aListName || !aChildList || !aChildList->GetNextSibling(),
+  NS_ASSERTION(aListName || aChildList.IsEmpty() || aChildList.OnlyChild(),
                "Primary child list can have at most one frame in it");
   return nsHTMLContainerFrame::SetInitialChildList(aListName, aChildList);
 }
 
 NS_IMETHODIMP
 CanvasFrame::AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList)
 {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -538,21 +538,23 @@ public:
    * @param   aListName the name of the child list. A NULL pointer for the atom
    *            name means the unnamed principal child list
    * @param   aChildList list of child frames. Each of the frames has its
    *            NS_FRAME_IS_DIRTY bit set
    * @return  NS_ERROR_INVALID_ARG if there is no child list with the specified
    *            name,
    *          NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
    *            initial list of frames has already been set for that child list,
-   *          NS_OK otherwise
+   *          NS_OK otherwise.  In this case, SetInitialChildList empties out
+   *            aChildList in the process of moving the frames over to its own
+   *            child list.
    * @see     #Init()
    */
   NS_IMETHOD  SetInitialChildList(nsIAtom*        aListName,
-                                  nsIFrame*       aChildList) = 0;
+                                  nsFrameList&    aChildList) = 0;
 
   /**
    * This method is responsible for appending frames to the frame
    * list.  The implementation should append the frames to the specified
    * child list and then generate a reflow command.
    *
    * @param   aListName the name of the child list. A NULL pointer for the atom
    *            name means the unnamed principal child list
@@ -2554,12 +2556,12 @@ nsFrameList::Enumerator::Next() {
 inline nsFrameList::Slice
 nsFrameList::InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
                           nsFrameList& aFrameList) {
   NS_PRECONDITION(!aFrameList.IsEmpty(), "Unexpected empty list");
   nsIFrame* firstNewFrame = aFrameList.FirstChild();
   nsIFrame* nextSibling =
     aPrevSibling ? aPrevSibling->GetNextSibling() : FirstChild();
   InsertFrames(aParent, aPrevSibling, firstNewFrame);
-  aFrameList.mFirstChild = nsnull;
+  aFrameList.Clear();
   return Slice(*this, firstNewFrame, nextSibling);
 }
 #endif /* nsIFrame_h___ */
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -311,17 +311,17 @@ nsInlineFrame::Reflow(nsPresContext*    
       // us children, and there's no next-in-flow, so all our frames
       // will be taken from prevOverflowFrames.
       if ((GetStateBits() & NS_FRAME_FIRST_REFLOW) && mFrames.IsEmpty() &&
           !GetNextInFlow()) {
         // If our child list is empty, just put the new frames into it.
         // Note that we don't set the parent pointer for the new frames. Instead wait
         // to do this until we actually reflow the frame. If the overflow list contains
         // thousands of frames this is a big performance issue (see bug #5588)
-        mFrames.InsertFrames(nsnull, nsnull, *prevOverflowFrames);
+        mFrames.SetFrames(*prevOverflowFrames);
         lazilySetParentPointer = PR_TRUE;
       } else {
         // Assign all floats to our block if necessary
         if (lineContainer && lineContainer->GetPrevContinuation()) {
           ReparentFloatsForInlineChild(lineContainer,
                                        prevOverflowFrames->FirstChild(),
                                        PR_TRUE);
         }
@@ -1078,17 +1078,17 @@ void
 nsPositionedInlineFrame::Destroy()
 {
   mAbsoluteContainer.DestroyFrames(this);
   nsInlineFrame::Destroy();
 }
 
 NS_IMETHODIMP
 nsPositionedInlineFrame::SetInitialChildList(nsIAtom*        aListName,
-                                             nsIFrame*       aChildList)
+                                             nsFrameList&    aChildList)
 {
   nsresult  rv;
 
   if (nsGkAtoms::absoluteList == aListName) {
     rv = mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
   } else {
     rv = nsInlineFrame::SetInitialChildList(aListName, aChildList);
   }
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -252,17 +252,17 @@ public:
     , mAbsoluteContainer(nsGkAtoms::absoluteList)
   {}
 
   virtual ~nsPositionedInlineFrame() { } // useful for debugging
 
   virtual void Destroy();
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame);
 
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -65,17 +65,17 @@ void
 ViewportFrame::Destroy()
 {
   mFixedContainer.DestroyFrames(this);
   nsContainerFrame::Destroy();
 }
 
 NS_IMETHODIMP
 ViewportFrame::SetInitialChildList(nsIAtom*        aListName,
-                                   nsIFrame*       aChildList)
+                                   nsFrameList&    aChildList)
 {
   nsresult rv = NS_OK;
 
   // See which child list to add the frames to
 #ifdef NS_DEBUG
   nsFrame::VerifyDirtyBitSet(aChildList);
 #endif
   if (nsGkAtoms::fixedList == aListName) {
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -67,17 +67,17 @@ public:
 
   virtual void Destroy();
 
   NS_IMETHOD Init(nsIContent*      aContent,
                   nsIFrame*        aParent,
                   nsIFrame*        asPrevInFlow);
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
 
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
 
--- a/layout/mathml/nsMathMLContainerFrame.h
+++ b/layout/mathml/nsMathMLContainerFrame.h
@@ -393,17 +393,17 @@ class nsMathMLmathBlockFrame : public ns
 public:
   friend nsIFrame* NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell,
           nsStyleContext* aContext, PRUint32 aFlags);
 
   // beware, mFrames is not set by nsBlockFrame
   // cannot use mFrames{.FirstChild()|.etc} since the block code doesn't set mFrames
   NS_IMETHOD
   SetInitialChildList(nsIAtom*        aListName,
-                      nsIFrame*       aChildList)
+                      nsFrameList&    aChildList)
   {
     NS_ASSERTION(!aListName, "unexpected frame list");
     nsresult rv = nsBlockFrame::SetInitialChildList(aListName, aChildList);
     // re-resolve our subtree to set any mathml-expected data
     nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this);
     return rv;
   }
 
@@ -461,17 +461,17 @@ protected:
 // --------------
 
 class nsMathMLmathInlineFrame : public nsInlineFrame {
 public:
   friend nsIFrame* NS_NewMathMLmathInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD
   SetInitialChildList(nsIAtom*        aListName,
-                      nsIFrame*       aChildList)
+                      nsFrameList&    aChildList)
   {
     NS_ASSERTION(!aListName, "unexpected frame list");
     nsresult rv = nsInlineFrame::SetInitialChildList(aListName, aChildList);
     // re-resolve our subtree to set any mathml-expected data
     nsMathMLContainerFrame::RebuildAutomaticDataForChildren(this);
     return rv;
   }
 
--- a/layout/mathml/nsMathMLForeignFrameWrapper.h
+++ b/layout/mathml/nsMathMLForeignFrameWrapper.h
@@ -67,24 +67,21 @@ public:
     return NS_OK;
   }
 
   // overloaded nsBlockFrame methods
 
 #ifdef NS_DEBUG
   NS_IMETHOD
   SetInitialChildList(nsIAtom*        aListName,
-                      nsIFrame*       aChildList)
+                      nsFrameList&    aChildList)
   {
-    nsresult rv = nsBlockFrame::SetInitialChildList(aListName, aChildList);
-    // cannot use mFrames{.FirstChild()|.etc} since the block code doesn't set mFrames
-    nsFrameList frameList(aChildList);
-    NS_ASSERTION(frameList.FirstChild() && frameList.GetLength() == 1,
+    NS_ASSERTION(aChildList.NotEmpty() && aChildList.GetLength() == 1,
                  "there must be one and only one child frame");
-    return rv;
+    return nsBlockFrame::SetInitialChildList(aListName, aChildList);
   }
 #endif
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus);
--- a/layout/mathml/nsMathMLTokenFrame.cpp
+++ b/layout/mathml/nsMathMLTokenFrame.cpp
@@ -127,17 +127,17 @@ nsMathMLTokenFrame::Init(nsIContent*    
   CompressWhitespace(aContent);
 
   // let the base class do its Init()
   return nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
 }
 
 NS_IMETHODIMP
 nsMathMLTokenFrame::SetInitialChildList(nsIAtom*        aListName,
-                                        nsIFrame*       aChildList)
+                                        nsFrameList&    aChildList)
 {
   // First, let the base class do its work
   nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListName, aChildList);
   if (NS_FAILED(rv))
     return rv;
 
   SetQuotes();
   ProcessTextData();
--- a/layout/mathml/nsMathMLTokenFrame.h
+++ b/layout/mathml/nsMathMLTokenFrame.h
@@ -54,17 +54,17 @@ public:
 
   NS_IMETHOD
   Init(nsIContent*      aContent,
        nsIFrame*        aParent,
        nsIFrame*        aPrevInFlow);
 
   NS_IMETHOD
   SetInitialChildList(nsIAtom*        aListName,
-                      nsIFrame*       aChildList);
+                      nsFrameList&    aChildList);
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus);
 
   virtual nsresult
--- a/layout/mathml/nsMathMLmactionFrame.cpp
+++ b/layout/mathml/nsMathMLmactionFrame.cpp
@@ -234,17 +234,17 @@ nsMathMLmactionFrame::GetSelectedFrame()
   mPresentationData.baseFrame = mSelectedFrame;
   GetEmbellishDataFrom(mSelectedFrame, mEmbellishData);
 
   return mSelectedFrame;
 }
 
 NS_IMETHODIMP
 nsMathMLmactionFrame::SetInitialChildList(nsIAtom*        aListName,
-                                          nsIFrame*       aChildList)
+                                          nsFrameList&    aChildList)
 {
   nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListName, aChildList);
 
   // This very first call to GetSelectedFrame() will cause us to be marked as an
   // embellished operator if the selected child is an embellished operator
   if (!GetSelectedFrame()) {
     mActionType = NS_MATHML_ACTION_TYPE_NONE;
   }
--- a/layout/mathml/nsMathMLmactionFrame.h
+++ b/layout/mathml/nsMathMLmactionFrame.h
@@ -63,17 +63,17 @@ public:
 
   NS_IMETHOD
   Init(nsIContent*      aContent,
        nsIFrame*        aParent,
        nsIFrame*        aPrevInFlow);
 
   NS_IMETHOD
   SetInitialChildList(nsIAtom*        aListName,
-                      nsIFrame*       aChildList);
+                      nsFrameList&    aChildList);
 
   virtual nsresult
   ChildListChanged(PRInt32 aModType);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
--- a/layout/mathml/nsMathMLmfencedFrame.cpp
+++ b/layout/mathml/nsMathMLmfencedFrame.cpp
@@ -72,17 +72,17 @@ nsMathMLmfencedFrame::InheritAutomaticDa
 
   mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMathMLmfencedFrame::SetInitialChildList(nsIAtom*        aListName,
-                                          nsIFrame*       aChildList)
+                                          nsFrameList&    aChildList)
 {
   // First, let the base class do its work
   nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListName, aChildList);
   if (NS_FAILED(rv)) return rv;
 
   // No need to tract the style contexts given to our MathML chars. 
   // The Style System will use Get/SetAdditionalStyleContext() to keep them
   // up-to-date if dynamic changes arise.
--- a/layout/mathml/nsMathMLmfencedFrame.h
+++ b/layout/mathml/nsMathMLmfencedFrame.h
@@ -57,17 +57,17 @@ public:
   virtual nsStyleContext*
   GetAdditionalStyleContext(PRInt32 aIndex) const;
 
   NS_IMETHOD
   InheritAutomaticData(nsIFrame* aParent);
 
   NS_IMETHOD
   SetInitialChildList(nsIAtom*        aListName,
-                      nsIFrame*       aChildList);
+                      nsFrameList&    aChildList);
 
   NS_IMETHOD
   Reflow(nsPresContext*          aPresContext,
          nsHTMLReflowMetrics&     aDesiredSize,
          const nsHTMLReflowState& aReflowState,
          nsReflowStatus&          aStatus);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -654,17 +654,17 @@ NS_NewMathMLmtableFrame(nsIPresShell* aP
 }
 
 nsMathMLmtableFrame::~nsMathMLmtableFrame()
 {
 }
 
 NS_IMETHODIMP
 nsMathMLmtableFrame::SetInitialChildList(nsIAtom*  aListName,
-                                         nsIFrame* aChildList)
+                                         nsFrameList& aChildList)
 {
   nsresult rv = nsTableFrame::SetInitialChildList(aListName, aChildList);
   if (NS_FAILED(rv)) return rv;
   MapAllAttributesIntoCSS(this);
   return rv;
 }
 
 void
--- a/layout/mathml/nsMathMLmtableFrame.h
+++ b/layout/mathml/nsMathMLmtableFrame.h
@@ -105,17 +105,17 @@ class nsMathMLmtableFrame : public nsTab
 {
 public:
   friend nsIFrame* NS_NewMathMLmtableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   // Overloaded nsTableFrame methods
 
   NS_IMETHOD
   SetInitialChildList(nsIAtom*  aListName,
-                      nsIFrame* aChildList);
+                      nsFrameList& aChildList);
 
   NS_IMETHOD
   AppendFrames(nsIAtom*  aListName,
                nsIFrame* aFrameList)
   {
     nsresult rv = nsTableFrame::AppendFrames(aListName, aFrameList);
     RestyleTable();
     return rv;
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -169,34 +169,34 @@ nsTableColGroupFrame::GetLastRealColGrou
     *aLastColGroup = lastColGroup;
     return PR_TRUE;
   }
 }
 
 // don't set mColCount here, it is done in AddColsToTable
 NS_IMETHODIMP
 nsTableColGroupFrame::SetInitialChildList(nsIAtom*        aListName,
-                                          nsIFrame*       aChildList)
+                                          nsFrameList&    aChildList)
 {
   if (!mFrames.IsEmpty()) {
     // We already have child frames which means we've already been
     // initialized
     NS_NOTREACHED("unexpected second call to SetInitialChildList");
     return NS_ERROR_UNEXPECTED;
   }
   if (aListName) {
     // All we know about is the unnamed principal child list
     NS_NOTREACHED("unknown frame list");
     return NS_ERROR_INVALID_ARG;
   } 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
   if (!tableFrame)
     return NS_ERROR_NULL_POINTER;
 
-  if (!aChildList) {
+  if (aChildList.IsEmpty()) {
     tableFrame->AppendAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup, 
                                          PR_FALSE);
     return NS_OK; 
   }
 
   mFrames.AppendFrames(this, aChildList);
   return NS_OK;
 }
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -68,17 +68,17 @@ public:
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   /** Initialize the colgroup frame with a set of children.
     * @see nsIFrame::SetInitialChildList
     */
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   /**
    * ColGroups never paint anything, nor receive events.
    */
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) { return NS_OK; }
 
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -301,72 +301,58 @@ nsTableFrame::PageBreakAfter(nsIFrame& a
   }
   return PR_FALSE;
 }
 
 // XXX this needs to be cleaned up so that the frame constructor breaks out col group
 // frames into a separate child list, bug 343048.
 NS_IMETHODIMP
 nsTableFrame::SetInitialChildList(nsIAtom*        aListName,
-                                  nsIFrame*       aChildList)
+                                  nsFrameList&    aChildList)
 {
 
   if (!mFrames.IsEmpty() || !mColGroups.IsEmpty()) {
     // We already have child frames which means we've already been
     // initialized
     NS_NOTREACHED("unexpected second call to SetInitialChildList");
     return NS_ERROR_UNEXPECTED;
   }
   if (aListName) {
     // All we know about is the unnamed principal child list
     NS_NOTREACHED("unknown frame list");
     return NS_ERROR_INVALID_ARG;
   } 
-  
-  nsIFrame *childFrame = aChildList;
+
+  // XXXbz the below code is an icky cesspit that's only needed in its current
+  // form for two reasons:
+  // 1) Both rowgroups and column groups come in on the principal child list.
+  // 2) Getting the last frame of a frame list is slow.
+  // Once #2 is fixed, it should be pretty easy to get rid of the
+  // SetNextSibling usage here, at least.
   nsIFrame *prevMainChild = nsnull;
   nsIFrame *prevColGroupChild = nsnull;
-  for ( ; nsnull!=childFrame; )
+  while (aChildList.NotEmpty())
   {
+    nsIFrame* childFrame = aChildList.FirstChild();
+    aChildList.RemoveFrame(childFrame);
     const nsStyleDisplay* childDisplay = childFrame->GetStyleDisplay();
-    // XXX this if should go away
-    if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
-    {
-      if (mFrames.IsEmpty()) 
-        mFrames.SetFrames(childFrame);
-      else
-        prevMainChild->SetNextSibling(childFrame);
-      prevMainChild = childFrame;
-    }
-    else if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+
+    if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
     {
       NS_ASSERTION(nsGkAtoms::tableColGroupFrame == childFrame->GetType(),
                    "This is not a colgroup");
-      if (mColGroups.IsEmpty())
-        mColGroups.SetFrames(childFrame);
-      else
-        prevColGroupChild->SetNextSibling(childFrame);
+      mColGroups.InsertFrame(nsnull, prevColGroupChild, childFrame);
       prevColGroupChild = childFrame;
     }
     else
-    { // unknown frames go on the main list for now
-      if (mFrames.IsEmpty())
-        mFrames.SetFrames(childFrame);
-      else
-        prevMainChild->SetNextSibling(childFrame);
+    { // row groups and unknown frames go on the main list for now
+      mFrames.InsertFrame(nsnull, prevMainChild, childFrame);
       prevMainChild = childFrame;
     }
-    nsIFrame *prevChild = childFrame;
-    childFrame = childFrame->GetNextSibling();
-    prevChild->SetNextSibling(nsnull);
-  }
-  if (nsnull!=prevMainChild)
-    prevMainChild->SetNextSibling(nsnull);
-  if (nsnull!=prevColGroupChild)
-    prevColGroupChild->SetNextSibling(nsnull);
+  }
 
   // If we have a prev-in-flow, then we're a table that has been split and
   // so don't treat this like an append
   if (!GetPrevInFlow()) {
     // process col groups first so that real cols get constructed before
     // anonymous ones due to cells in rows.
     InsertColGroups(0, mColGroups.FirstChild());
     AppendRowGroups(mFrames.FirstChild());
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -253,17 +253,17 @@ public:
     * (header, footer, or body)
     */
   PRBool IsRowGroup(PRInt32 aDisplayType) const;
 
   /** Initialize the table frame with a set of children.
     * @see nsIFrame::SetInitialChildList 
     */
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   /** @see nsIFrame::GetAdditionalChildListName */
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -233,31 +233,31 @@ nsTableOuterFrame::GetAdditionalChildLis
   if (aIndex == NS_TABLE_FRAME_CAPTION_LIST_INDEX) {
     return nsGkAtoms::captionList;
   }
   return nsnull;
 }
 
 NS_IMETHODIMP 
 nsTableOuterFrame::SetInitialChildList(nsIAtom*        aListName,
-                                       nsIFrame*       aChildList)
+                                       nsFrameList&    aChildList)
 {
   if (nsGkAtoms::captionList == aListName) {
     // the frame constructor already checked for table-caption display type
     mCaptionFrames.SetFrames(aChildList);
-    mCaptionFrame  = mCaptionFrames.FirstChild();
+    mCaptionFrame = mCaptionFrames.FirstChild();
   }
   else {
     NS_ASSERTION(!aListName, "wrong childlist");
     NS_ASSERTION(mFrames.IsEmpty(), "Frame leak!");
-    mFrames.SetFrames(aChildList);
     mInnerTableFrame = nsnull;
-    if (aChildList) {
-      if (nsGkAtoms::tableFrame == aChildList->GetType()) {
-        mInnerTableFrame = (nsTableFrame*)aChildList;
+    if (aChildList.NotEmpty()) {
+      if (nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType()) {
+        mInnerTableFrame = (nsTableFrame*)aChildList.FirstChild();
+        mFrames.SetFrames(aChildList);
       }
       else {
         NS_ERROR("expected a table frame");
         return NS_ERROR_INVALID_ARG;
       }
     }
   }
 
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -98,17 +98,17 @@ public:
   
   // nsIFrame overrides - see there for a description
 
   virtual void Destroy();
   
   virtual PRBool IsContainingBlock() const;
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
  
   virtual nsFrameList GetChildList(nsIAtom* aListName) const;
 
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
 
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
 
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -161,17 +161,17 @@ nsBoxFrame::nsBoxFrame(nsIPresShell* aPr
 }
 
 nsBoxFrame::~nsBoxFrame()
 {
 }
 
 NS_IMETHODIMP
 nsBoxFrame::SetInitialChildList(nsIAtom*        aListName,
-                                nsIFrame*       aChildList)
+                                nsFrameList&    aChildList)
 {
   nsresult r = nsContainerFrame::SetInitialChildList(aListName, aChildList);
   if (r == NS_OK) {
     // initialize our list of infos.
     nsBoxLayoutState state(PresContext());
     CheckBoxOrder(state);
     if (mLayoutManager)
       mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild());
--- a/layout/xul/base/src/nsBoxFrame.h
+++ b/layout/xul/base/src/nsBoxFrame.h
@@ -136,17 +136,17 @@ public:
                            nsIFrame*       aFrameList);
 
   NS_IMETHOD  RemoveFrame(nsIAtom*        aListName,
                           nsIFrame*       aOldFrame);
 
   virtual nsIFrame* GetContentInsertionFrame();
 
   NS_IMETHOD  SetInitialChildList(nsIAtom*        aListName,
-                                  nsIFrame*       aChildList);
+                                  nsFrameList&    aChildList);
 
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
 
   virtual nsIAtom* GetType() const;
 
   virtual PRBool IsFrameOfType(PRUint32 aFlags) const
   {
     // record that children that are ignorable whitespace should be excluded 
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -334,38 +334,40 @@ nsMenuFrame::GetChildList(nsIAtom* aList
   return nsBoxFrame::GetChildList(aListName);
 }
 
 nsIFrame*
 nsMenuFrame::SetPopupFrame(nsIFrame* aChildList)
 {
   // Check for a menupopup and move it to mPopupFrame
   nsFrameList frames(aChildList);
-  nsIFrame* frame = frames.FirstChild();
-  while (frame) {
-    if (frame->GetType() == nsGkAtoms::menuPopupFrame) {
+  SetPopupFrame(frames);
+  return frames.FirstChild();
+}
+
+void
+nsMenuFrame::SetPopupFrame(nsFrameList& aFrameList)
+{
+  for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
+    if (e.get()->GetType() == nsGkAtoms::menuPopupFrame) {
       // Remove this frame from the list and set it as mPopupFrame
-      frames.RemoveFrame(frame);
-      mPopupFrame = (nsMenuPopupFrame *)frame;
-      aChildList = frames.FirstChild();
+      mPopupFrame = (nsMenuPopupFrame *)e.get();
+      aFrameList.RemoveFrame(e.get());
       break;
     }
-    frame = frame->GetNextSibling();
   }
-
-  return aChildList;
 }
 
 NS_IMETHODIMP
 nsMenuFrame::SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList)
+                                 nsFrameList&    aChildList)
 {
   NS_ASSERTION(!mPopupFrame, "already have a popup frame set");
   if (!aListName || aListName == nsGkAtoms::popupList)
-    aChildList = SetPopupFrame(aChildList);
+    SetPopupFrame(aChildList);
   return nsBoxFrame::SetInitialChildList(aListName, aChildList);
 }
 
 nsIAtom*
 nsMenuFrame::GetAdditionalChildListName(PRInt32 aIndex) const
 {
   if (NS_MENU_POPUP_LIST_INDEX == aIndex) {
     return nsGkAtoms::popupList;
--- a/layout/xul/base/src/nsMenuFrame.h
+++ b/layout/xul/base/src/nsMenuFrame.h
@@ -127,17 +127,17 @@ public:
 
   NS_IMETHOD IsActive(PRBool& aResult) { aResult = PR_TRUE; return NS_OK; }
 
   // The following methods are all overridden so that the menupopup
   // can be stored in a separate list, so that it doesn't impact reflow of the
   // actual menu item at all.
   virtual nsFrameList GetChildList(nsIAtom* aListName) const;
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
   virtual void Destroy();
 
   // Overridden to prevent events from going to children of the menu.
   NS_IMETHOD BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                          const nsRect&           aDirtyRect,
                                          const nsDisplayListSet& aLists);
                                          
@@ -228,16 +228,19 @@ public:
 protected:
   friend class nsMenuTimerMediator;
   friend class nsASyncMenuInitialization;
 
   // initialize mPopupFrame to the first popup frame within aChildList. Returns
   // aChildList with the popup frame removed.
   nsIFrame* SetPopupFrame(nsIFrame* aChildList);
 
+  // As above, but using an nsFrameList; modifies the passed-in list.
+  void SetPopupFrame(nsFrameList& aChildList);
+
   // set mMenuParent to the nearest enclosing menu bar or menupopup frame of
   // aParent (or aParent itself). This is called when initializing the frame,
   // so aParent should be the expected parent of this frame.
   void InitMenuParent(nsIFrame* aParent);
 
   // Update the menu's type (normal, checkbox, radio).
   // This method can destroy the frame.
   void UpdateMenuType(nsPresContext* aPresContext);
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -312,20 +312,20 @@ public:
 
 private:
   nsCOMPtr<nsIContent> mPopup;
   nsRefPtr<nsPresContext> mPresContext;
 };
 
 NS_IMETHODIMP
 nsMenuPopupFrame::SetInitialChildList(nsIAtom* aListName,
-                                      nsIFrame* aChildList)
+                                      nsFrameList& aChildList)
 {
   // unless the list is empty, indicate that children have been generated.
-  if (aChildList)
+  if (aChildList.NotEmpty())
     mGeneratedChildren = PR_TRUE;
   return nsBoxFrame::SetInitialChildList(aListName, aChildList);
 }
 
 PRBool
 nsMenuPopupFrame::IsLeaf() const
 {
   if (mGeneratedChildren)
--- a/layout/xul/base/src/nsMenuPopupFrame.h
+++ b/layout/xul/base/src/nsMenuPopupFrame.h
@@ -184,17 +184,17 @@ public:
   // panel appears in front of the parent window.
   PRBool IsTopMost();
 
   void EnsureWidget();
 
   virtual nsresult CreateWidgetForView(nsIView* aView);
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   virtual PRBool IsLeaf() const;
 
   // AdjustView should be called by the parent frame after the popup has been
   // laid out, so that the view can be shown.
   void AdjustView();
 
   nsIView* GetRootViewForPopup(nsIFrame* aStartFrame);
--- a/layout/xul/base/src/nsPopupSetFrame.cpp
+++ b/layout/xul/base/src/nsPopupSetFrame.cpp
@@ -90,17 +90,18 @@ nsPopupSetFrame::GetType() const
   return nsGkAtoms::popupSetFrame;
 }
 
 NS_IMETHODIMP
 nsPopupSetFrame::AppendFrames(nsIAtom*        aListName,
                               nsIFrame*       aFrameList)
 {
   if (aListName == nsGkAtoms::popupList) {
-    return AddPopupFrameList(aFrameList);
+    nsFrameList temp(aFrameList);
+    return AddPopupFrameList(temp);
   }
   return nsBoxFrame::AppendFrames(aListName, aFrameList);
 }
 
 NS_IMETHODIMP
 nsPopupSetFrame::RemoveFrame(nsIAtom*        aListName,
                              nsIFrame*       aOldFrame)
 {
@@ -111,24 +112,25 @@ nsPopupSetFrame::RemoveFrame(nsIAtom*   
 }
 
 NS_IMETHODIMP
 nsPopupSetFrame::InsertFrames(nsIAtom*        aListName,
                               nsIFrame*       aPrevFrame,
                               nsIFrame*       aFrameList)
 {
   if (aListName == nsGkAtoms::popupList) {
-    return AddPopupFrameList(aFrameList);
+    nsFrameList temp(aFrameList);
+    return AddPopupFrameList(temp);
   }
   return nsBoxFrame::InsertFrames(aListName, aPrevFrame, aFrameList);
 }
 
 NS_IMETHODIMP
 nsPopupSetFrame::SetInitialChildList(nsIAtom*        aListName,
-                                     nsIFrame*       aChildList)
+                                     nsFrameList&    aChildList)
 {
   if (aListName == nsGkAtoms::popupList) {
     return AddPopupFrameList(aChildList);
   }
   return nsBoxFrame::SetInitialChildList(aListName, aChildList);
 }
 
 void
@@ -258,22 +260,23 @@ nsPopupSetFrame::RemovePopupFrame(nsIFra
     currEntry = currEntry->mNextPopup;
   }
 
   NS_ASSERTION(found, "frame to remove is not in our ::popupList");
   return NS_OK;
 }
 
 nsresult
-nsPopupSetFrame::AddPopupFrameList(nsIFrame* aPopupFrameList)
+nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
 {
-  for (nsIFrame* kid = aPopupFrameList; kid; kid = kid->GetNextSibling()) {
-    nsresult rv = AddPopupFrame(kid);
+  for (nsFrameList::Enumerator e(aPopupFrameList); !e.AtEnd(); e.Next()) {
+    nsresult rv = AddPopupFrame(e.get());
     NS_ENSURE_SUCCESS(rv, rv);
   }
+  aPopupFrameList.Clear();
   return NS_OK;
 }
 
 nsresult
 nsPopupSetFrame::AddPopupFrame(nsIFrame* aPopup)
 {
   NS_ASSERTION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
                aPopup->GetType() == nsGkAtoms::menuPopupFrame,
--- a/layout/xul/base/src/nsPopupSetFrame.h
+++ b/layout/xul/base/src/nsPopupSetFrame.h
@@ -75,17 +75,17 @@ public:
   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
                           nsIFrame*       aFrameList);
   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
                          nsIFrame*       aOldFrame);
   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
                           nsIFrame*       aPrevFrame,
                           nsIFrame*       aFrameList);
   NS_IMETHOD  SetInitialChildList(nsIAtom*        aListName,
-                                  nsIFrame*       aChildList);
+                                  nsFrameList&    aChildList);
 
     // nsIBox
   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
 
   // Used to destroy our popup frames.
   virtual void Destroy();
 
   virtual nsIAtom* GetType() const;
@@ -95,17 +95,17 @@ public:
   NS_IMETHOD GetFrameName(nsAString& aResult) const
   {
       return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult);
   }
 #endif
 
 protected:
 
-  nsresult AddPopupFrameList(nsIFrame* aPopupFrameList);
+  nsresult AddPopupFrameList(nsFrameList& aPopupFrameList);
   nsresult AddPopupFrame(nsIFrame* aPopup);
   nsresult RemovePopupFrame(nsIFrame* aPopup);
   
   nsPopupFrameList* mPopupList;
 
 }; // class nsPopupSetFrame
 
 #endif
--- a/layout/xul/base/src/nsSliderFrame.cpp
+++ b/layout/xul/base/src/nsSliderFrame.cpp
@@ -882,17 +882,17 @@ nsSliderFrame::SetCurrentPositionInterna
 nsIAtom*
 nsSliderFrame::GetType() const
 {
   return nsGkAtoms::sliderFrame;
 }
 
 NS_IMETHODIMP
 nsSliderFrame::SetInitialChildList(nsIAtom*        aListName,
-                                   nsIFrame*       aChildList)
+                                   nsFrameList&    aChildList)
 {
   nsresult r = nsBoxFrame::SetInitialChildList(aListName, aChildList);
 
   AddListener();
 
   return r;
 }
 
--- a/layout/xul/base/src/nsSliderFrame.h
+++ b/layout/xul/base/src/nsSliderFrame.h
@@ -162,17 +162,17 @@ public:
                    nsIFrame*        asPrevInFlow);
 
 
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
                          nsGUIEvent* aEvent,
                          nsEventStatus* aEventStatus);
 
   NS_IMETHOD SetInitialChildList(nsIAtom*        aListName,
-                                 nsIFrame*       aChildList);
+                                 nsFrameList&    aChildList);
 
   virtual nsIAtom* GetType() const;
 
   NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
   NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
 
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }