Bug 729519 - Allocate heap nsFrameLists from the shell arena. r=bzbarsky

"new nsFrameList()" becomes "new (shell) nsFrameList()".
"delete list" becomes "if (list) list->Delete(shell)" - note also that
an additional assertion was added that list is empty when deleted.

"nsAutoPtr<nsFrameList> list(StealSomeFrames())" becomes
"AutoFrameListPtr list(aPresContext, StealSomeFrames())"
This commit is contained in:
Mats Palmgren 2013-04-01 17:26:02 +02:00
parent 46cbb9a249
commit 7fa166a5f5
12 changed files with 133 additions and 95 deletions

View File

@ -45,6 +45,7 @@ public:
nsLineBox_id = nsQueryFrame::NON_FRAME_MARKER,
nsRuleNode_id,
nsStyleContext_id,
nsFrameList_id,
// The PresArena implementation uses this bit to distinguish objects
// allocated by size from objects allocated by type ID (that is, frames

View File

@ -75,6 +75,7 @@ static const PRUnichar kSquareCharacter = 0x25aa;
using namespace mozilla;
using namespace mozilla::css;
using namespace mozilla::layout;
#ifdef DEBUG
#include "nsBlockDebugFlags.h"
@ -276,13 +277,14 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
DestroyAbsoluteFrames(aDestructRoot);
mFloats.DestroyFramesFrom(aDestructRoot);
nsPresContext* presContext = PresContext();
nsIPresShell* shell = presContext->PresShell();
nsLineBox::DeleteLineList(presContext, mLines, aDestructRoot,
&mFrames);
FramePropertyTable* props = presContext->PropertyTable();
if (HasPushedFloats()) {
SafelyDestroyFrameListProp(aDestructRoot, props,
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
PushedFloatProperty());
RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
}
@ -296,13 +298,13 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
}
if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) {
SafelyDestroyFrameListProp(aDestructRoot, props,
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
OverflowOutOfFlowsProperty());
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
}
if (HasOutsideBullet()) {
SafelyDestroyFrameListProp(aDestructRoot, props,
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
OutsideBulletProperty());
RemoveStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
}
@ -4479,7 +4481,8 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
// rather than this block? Might we need to pull it back so we don't
// report ourselves complete?
// FIXME: Maybe we should just pull all of them back?
nsFrameList *ourPushedFloats = GetPushedFloats();
nsPresContext* presContext = PresContext();
nsFrameList* ourPushedFloats = GetPushedFloats();
if (ourPushedFloats) {
// When we pull back floats, we want to put them with the pushed
// floats, which must live at the start of our float list, but we
@ -4492,7 +4495,6 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
insertionPrevSibling = f;
}
nsPresContext *presContext = PresContext();
for (nsIFrame *f = ourPushedFloats->LastChild(), *next; f; f = next) {
next = f->GetPrevSibling();
@ -4515,7 +4517,7 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
}
if (ourPushedFloats->IsEmpty()) {
delete RemovePushedFloats();
RemovePushedFloats()->Delete(presContext->PresShell());
}
}
@ -4523,12 +4525,9 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
// floats list, containing floats that we need to own. Take these.
nsBlockFrame* prevBlock = static_cast<nsBlockFrame*>(GetPrevInFlow());
if (prevBlock) {
nsFrameList *list = prevBlock->RemovePushedFloats();
if (list) {
if (list->NotEmpty()) {
mFloats.InsertFrames(this, nullptr, *list);
}
delete list;
AutoFrameListPtr list(presContext, prevBlock->RemovePushedFloats());
if (list && list->NotEmpty()) {
mFloats.InsertFrames(this, nullptr, *list);
}
}
}
@ -4620,11 +4619,11 @@ nsBlockFrame::SetOverflowOutOfFlows(const nsFrameList& aList,
if (!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS)) {
return;
}
nsFrameList* list =
RemovePropTableFrames(PresContext(),
OverflowOutOfFlowsProperty());
nsPresContext* pc = PresContext();
nsFrameList* list = RemovePropTableFrames(pc, OverflowOutOfFlowsProperty());
NS_ASSERTION(aPropValue == list, "prop value mismatch");
delete list;
list->Clear();
list->Delete(pc->PresShell());
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
}
else if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) {
@ -4634,7 +4633,8 @@ nsBlockFrame::SetOverflowOutOfFlows(const nsFrameList& aList,
*aPropValue = aList;
}
else {
SetPropTableFrames(PresContext(), new nsFrameList(aList),
nsPresContext* pc = PresContext();
SetPropTableFrames(pc, new (pc->PresShell()) nsFrameList(aList),
OverflowOutOfFlowsProperty());
AddStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
}
@ -4696,7 +4696,7 @@ nsBlockFrame::EnsurePushedFloats()
if (result)
return result;
result = new nsFrameList;
result = new (PresContext()->PresShell()) nsFrameList;
Properties().Set(PushedFloatProperty(), result);
AddStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
@ -6592,7 +6592,7 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID,
Properties().Set(InsideBulletProperty(), bullet);
AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
} else {
nsFrameList* bulletList = new nsFrameList(bullet, bullet);
nsFrameList* bulletList = new (shell) nsFrameList(bullet, bullet);
Properties().Set(OutsideBulletProperty(), bulletList);
AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
}

View File

@ -27,10 +27,9 @@
#include "nsIScrollableFrame.h"
#include "nsIDocShell.h"
#ifdef DEBUG_rods
//#define DEBUG_CANVAS_FOCUS
#endif
using namespace mozilla::layout;
nsIFrame*
NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@ -430,7 +429,8 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
nsCanvasFrame* prevCanvasFrame = static_cast<nsCanvasFrame*>
(GetPrevInFlow());
if (prevCanvasFrame) {
nsAutoPtr<nsFrameList> overflow(prevCanvasFrame->StealOverflowFrames());
AutoFrameListPtr overflow(aPresContext,
prevCanvasFrame->StealOverflowFrames());
if (overflow) {
NS_ASSERTION(overflow->OnlyChild(),
"must have doc root as canvas frame's only child");

View File

@ -21,6 +21,7 @@
#include <algorithm>
using namespace mozilla;
using namespace mozilla::layout;
class nsColumnSetFrame : public nsContainerFrame {
public:
@ -865,11 +866,12 @@ nsColumnSetFrame::DrainOverflowColumns()
{
// First grab the prev-in-flows overflows and reparent them to this
// frame.
nsPresContext* presContext = PresContext();
nsColumnSetFrame* prev = static_cast<nsColumnSetFrame*>(GetPrevInFlow());
if (prev) {
nsAutoPtr<nsFrameList> overflows(prev->StealOverflowFrames());
AutoFrameListPtr overflows(presContext, prev->StealOverflowFrames());
if (overflows) {
nsContainerFrame::ReparentFrameViewList(PresContext(), *overflows,
nsContainerFrame::ReparentFrameViewList(presContext, *overflows,
prev, this);
mFrames.InsertFrames(this, nullptr, *overflows);
@ -878,7 +880,7 @@ nsColumnSetFrame::DrainOverflowColumns()
// Now pull back our own overflows and append them to our children.
// We don't need to reparent them since we're already their parent.
nsAutoPtr<nsFrameList> overflows(StealOverflowFrames());
AutoFrameListPtr overflows(presContext, StealOverflowFrames());
if (overflows) {
// We're already the parent for these frames, so no need to set
// their parent again.

View File

@ -48,6 +48,7 @@
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::layout;
NS_IMPL_FRAMEARENA_HELPERS(nsContainerFrame)
@ -217,6 +218,7 @@ nsContainerFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)
void
nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
FramePropertyTable* aPropTable,
const FramePropertyDescriptor* aProp)
{
@ -230,7 +232,7 @@ nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
frame->DestroyFrom(aDestructRoot);
} else {
aPropTable->Remove(this, aProp);
delete frameList;
frameList->Delete(aPresShell);
return;
}
}
@ -251,17 +253,18 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
// Destroy frames on the auxiliary frame lists and delete the lists.
nsPresContext* pc = PresContext();
nsIPresShell* shell = pc->PresShell();
FramePropertyTable* props = pc->PropertyTable();
SafelyDestroyFrameListProp(aDestructRoot, props, OverflowProperty());
SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowProperty());
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) ||
!(props->Get(this, nsContainerFrame::OverflowContainersProperty()) ||
props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())),
"this type of frame should't have overflow containers");
SafelyDestroyFrameListProp(aDestructRoot, props,
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
OverflowContainersProperty());
SafelyDestroyFrameListProp(aDestructRoot, props,
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
ExcessOverflowContainersProperty());
nsSplittableFrame::DestroyFrom(aDestructRoot);
@ -1113,7 +1116,7 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
if (selfExcessOCFrames) {
if (overflowContainers) {
overflowContainers->AppendFrames(nullptr, *selfExcessOCFrames);
delete selfExcessOCFrames;
selfExcessOCFrames->Delete(aPresContext->PresShell());
} else {
overflowContainers = selfExcessOCFrames;
SetPropTableFrames(aPresContext, overflowContainers,
@ -1231,7 +1234,7 @@ TryRemoveFrame(nsIFrame* aFrame, FramePropertyTable* aPropTable,
// aChildToRemove *may* have been removed from this list.
if (list->IsEmpty()) {
aPropTable->Remove(aFrame, aProp);
delete list;
list->Delete(aFrame->PresContext()->PresShell());
}
return true;
}
@ -1421,7 +1424,7 @@ nsContainerFrame::SetOverflowFrames(nsPresContext* aPresContext,
const nsFrameList& aOverflowFrames)
{
NS_PRECONDITION(aOverflowFrames.NotEmpty(), "Shouldn't be called");
nsFrameList* newList = new nsFrameList(aOverflowFrames);
nsFrameList* newList = new (aPresContext->PresShell()) nsFrameList(aOverflowFrames);
aPresContext->PropertyTable()->Set(this, OverflowProperty(), newList);
}
@ -1518,7 +1521,8 @@ nsContainerFrame::MoveOverflowToChildList(nsPresContext* aPresContext)
// Check for an overflow list with our prev-in-flow
nsContainerFrame* prevInFlow = (nsContainerFrame*)GetPrevInFlow();
if (nullptr != prevInFlow) {
nsAutoPtr<nsFrameList> prevOverflowFrames(prevInFlow->StealOverflowFrames());
AutoFrameListPtr prevOverflowFrames(aPresContext,
prevInFlow->StealOverflowFrames());
if (prevOverflowFrames) {
// Tables are special; they can have repeated header/footer
// frames on mFrames at this point.
@ -1541,7 +1545,7 @@ nsContainerFrame::MoveOverflowToChildList(nsPresContext* aPresContext)
bool
nsContainerFrame::DrainSelfOverflowList()
{
nsAutoPtr<nsFrameList> overflowFrames(StealOverflowFrames());
AutoFrameListPtr overflowFrames(PresContext(), StealOverflowFrames());
if (overflowFrames) {
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
mFrames.AppendFrames(nullptr, *overflowFrames);
@ -1684,7 +1688,7 @@ nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
aOverflowCont->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
if (!mOverflowContList) {
mOverflowContList = new nsFrameList();
mOverflowContList = new (presContext->PresShell()) nsFrameList();
mParent->SetPropTableFrames(presContext, mOverflowContList,
nsContainerFrame::ExcessOverflowContainersProperty());
SetUpListWalker();

View File

@ -12,7 +12,6 @@
#include "nsSplittableFrame.h"
#include "nsFrameList.h"
#include "nsLayoutUtils.h"
#include "nsAutoPtr.h"
// Option flags for ReflowChild() and FinishReflowChild()
// member functions
@ -431,10 +430,10 @@ protected:
/**
* As GetOverflowFrames, but removes the overflow frames property. The
* caller is responsible for deleting nsFrameList and either passing
* ownership of the frames to someone else or destroying the frames. A
* non-null return value indicates that the list is nonempty. The
* ownership of the frames to someone else or destroying the frames.
* A non-null return value indicates that the list is nonempty. The
* recommended way to use this function it to assign its return value
* into an nsAutoPtr.
* into an AutoFrameListPtr.
*/
inline nsFrameList* StealOverflowFrames();
@ -512,6 +511,7 @@ protected:
* Nothing happens if the property doesn't exist.
*/
void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
mozilla::FramePropertyTable* aPropTable,
const FramePropertyDescriptor* aProp);
@ -684,7 +684,7 @@ nsContainerFrame::DestroyOverflowList(nsPresContext* aPresContext)
{
nsFrameList* list = RemovePropTableFrames(aPresContext, OverflowProperty());
MOZ_ASSERT(list && list->IsEmpty());
delete list;
list->Delete(aPresContext->PresShell());
}
#endif /* nsContainerFrame_h___ */

View File

@ -18,7 +18,8 @@
#include "nsPlaceholderFrame.h"
#include "nsCSSFrameConstructor.h"
using namespace::mozilla;
using namespace mozilla;
using namespace mozilla::layout;
nsIFrame*
NS_NewFirstLetterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@ -345,12 +346,11 @@ nsFirstLetterFrame::CreateContinuationForFloatingParent(nsPresContext* aPresCont
void
nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
{
nsAutoPtr<nsFrameList> overflowFrames;
// Check for an overflow list with our prev-in-flow
nsFirstLetterFrame* prevInFlow = (nsFirstLetterFrame*)GetPrevInFlow();
if (nullptr != prevInFlow) {
overflowFrames = prevInFlow->StealOverflowFrames();
if (prevInFlow) {
AutoFrameListPtr overflowFrames(aPresContext,
prevInFlow->StealOverflowFrames());
if (overflowFrames) {
NS_ASSERTION(mFrames.IsEmpty(), "bad overflow list");
@ -363,7 +363,7 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
}
// It's also possible that we have an overflow list for ourselves
overflowFrames = StealOverflowFrames();
AutoFrameListPtr overflowFrames(aPresContext, StealOverflowFrames());
if (overflowFrames) {
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
mFrames.AppendFrames(nullptr, *overflowFrames);

View File

@ -6,6 +6,8 @@
#include "nsFrameList.h"
#include "nsIFrame.h"
#include "nsLayoutUtils.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#ifdef IBMBIDI
#include "nsCOMPtr.h"
@ -22,22 +24,19 @@ const AlignedFrameListBytes gEmptyFrameListBytes = { 0 };
}
}
void
nsFrameList::Destroy()
void*
nsFrameList::operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW
{
NS_PRECONDITION(this != &EmptyList(), "Shouldn't Destroy() sEmptyList");
DestroyFrames();
delete this;
return aPresShell->AllocateByObjectID(nsPresArena::nsFrameList_id, sz);
}
void
nsFrameList::DestroyFrom(nsIFrame* aDestructRoot)
nsFrameList::Delete(nsIPresShell* aPresShell)
{
NS_PRECONDITION(this != &EmptyList(), "Shouldn't Destroy() this list");
NS_PRECONDITION(this != &EmptyList(), "Shouldn't Delete() this list");
NS_ASSERTION(IsEmpty(), "Shouldn't Delete() a non-empty list");
DestroyFramesFrom(aDestructRoot);
delete this;
aPresShell->FreeByObjectID(nsPresArena::nsFrameList_id, this);
}
void
@ -541,3 +540,16 @@ nsFrameList::VerifyList() const
// prevents that, e.g. table captions.
}
#endif
namespace mozilla {
namespace layout {
AutoFrameListPtr::~AutoFrameListPtr()
{
if (mFrameList) {
mFrameList->Delete(mPresContext->PresShell());
}
}
}
}

View File

@ -13,6 +13,9 @@
#include "nsTArray.h"
class nsIFrame;
class nsIPresShell;
class nsPresContext;
namespace mozilla {
namespace layout {
class FrameChildList;
@ -50,26 +53,29 @@ public:
nsFrameList() :
mFirstChild(nullptr), mLastChild(nullptr)
{
MOZ_COUNT_CTOR(nsFrameList);
}
nsFrameList(nsIFrame* aFirstFrame, nsIFrame* aLastFrame) :
mFirstChild(aFirstFrame), mLastChild(aLastFrame)
{
MOZ_COUNT_CTOR(nsFrameList);
VerifyList();
}
nsFrameList(const nsFrameList& aOther) :
mFirstChild(aOther.mFirstChild), mLastChild(aOther.mLastChild)
{
MOZ_COUNT_CTOR(nsFrameList);
}
~nsFrameList() {
MOZ_COUNT_DTOR(nsFrameList);
// Don't destroy our frames here, so that we can have temporary nsFrameLists
}
/**
* Allocate a nsFrameList from the shell arena.
*/
void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW;
/**
* Deallocate this list that was allocated from the shell arena.
* The list is required to be empty.
*/
void Delete(nsIPresShell* aPresShell);
/**
* For each frame in this list: remove it from the list then call
@ -79,24 +85,10 @@ public:
/**
* For each frame in this list: remove it from the list then call
* DestroyFrom() on it.
* DestroyFrom(aDestructRoot) on it.
*/
void DestroyFramesFrom(nsIFrame* aDestructRoot);
/**
* For each frame in this list: remove it from the list then call
* Destroy() on it. Finally <code>delete this</code>.
*
*/
void Destroy();
/**
* For each frame in this list: remove it from the list then call
* DestroyFrom() on it. Finally <code>delete this</code>.
*
*/
void DestroyFrom(nsIFrame* aDestructRoot);
void Clear() { mFirstChild = mLastChild = nullptr; }
void SetFrames(nsIFrame* aFrameList);
@ -456,6 +448,8 @@ public:
};
private:
void operator delete(void*) MOZ_DELETE;
#ifdef DEBUG_FRAME_LIST
void VerifyList() const;
#else
@ -477,6 +471,24 @@ protected:
namespace mozilla {
namespace layout {
/**
* Simple "auto_ptr" for nsFrameLists allocated from the shell arena.
* The frame list given to the constructor will be deallocated (if non-null)
* in the destructor. The frame list must then be empty.
*/
class AutoFrameListPtr {
public:
AutoFrameListPtr(nsPresContext* aPresContext, nsFrameList* aFrameList)
: mPresContext(aPresContext), mFrameList(aFrameList) {}
~AutoFrameListPtr();
operator nsFrameList*() const { return mFrameList; }
nsFrameList* operator->() const { return mFrameList; }
private:
nsPresContext* mPresContext;
nsFrameList* mFrameList;
};
namespace detail {
union AlignedFrameListBytes {
void* ptr;

View File

@ -27,6 +27,7 @@
#endif
using namespace mozilla;
using namespace mozilla::layout;
//////////////////////////////////////////////////////////////////////
@ -312,9 +313,9 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
// Check for an overflow list with our prev-in-flow
nsInlineFrame* prevInFlow = (nsInlineFrame*)GetPrevInFlow();
if (nullptr != prevInFlow) {
nsAutoPtr<nsFrameList> prevOverflowFrames(prevInFlow->StealOverflowFrames());
if (prevInFlow) {
AutoFrameListPtr prevOverflowFrames(aPresContext,
prevInFlow->StealOverflowFrames());
if (prevOverflowFrames) {
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
@ -370,7 +371,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
}
#endif
if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
nsAutoPtr<nsFrameList> overflowFrames(StealOverflowFrames());
AutoFrameListPtr overflowFrames(aPresContext, StealOverflowFrames());
if (overflowFrames) {
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
if (!lazilySetParentPointer) {
@ -435,10 +436,12 @@ nsInlineFrame::PullOverflowsFromPrevInFlow()
{
nsInlineFrame* prevInFlow = static_cast<nsInlineFrame*>(GetPrevInFlow());
if (prevInFlow) {
nsAutoPtr<nsFrameList> prevOverflowFrames(prevInFlow->StealOverflowFrames());
nsPresContext* presContext = PresContext();
AutoFrameListPtr prevOverflowFrames(presContext,
prevInFlow->StealOverflowFrames());
if (prevOverflowFrames) {
// Assume that our prev-in-flow has the same line container that we do.
nsContainerFrame::ReparentFrameViewList(PresContext(),
nsContainerFrame::ReparentFrameViewList(presContext,
*prevOverflowFrames,
prevInFlow, this);
mFrames.InsertFrames(this, nullptr, *prevOverflowFrames);
@ -977,8 +980,9 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
// Check for an overflow list with our prev-in-flow
nsFirstLineFrame* prevInFlow = (nsFirstLineFrame*)GetPrevInFlow();
if (nullptr != prevInFlow) {
nsAutoPtr<nsFrameList> prevOverflowFrames(prevInFlow->StealOverflowFrames());
if (prevInFlow) {
AutoFrameListPtr prevOverflowFrames(aPresContext,
prevInFlow->StealOverflowFrames());
if (prevOverflowFrames) {
// Assign all floats to our block if necessary
if (lineContainer && lineContainer->GetPrevContinuation()) {
@ -993,7 +997,7 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
}
// It's also possible that we have an overflow list for ourselves
nsAutoPtr<nsFrameList> overflowFrames(StealOverflowFrames());
AutoFrameListPtr overflowFrames(aPresContext, StealOverflowFrames());
if (overflowFrames) {
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
@ -1083,12 +1087,14 @@ nsFirstLineFrame::PullOverflowsFromPrevInFlow()
{
nsFirstLineFrame* prevInFlow = static_cast<nsFirstLineFrame*>(GetPrevInFlow());
if (prevInFlow) {
nsAutoPtr<nsFrameList> prevOverflowFrames(prevInFlow->StealOverflowFrames());
nsPresContext* presContext = PresContext();
AutoFrameListPtr prevOverflowFrames(presContext,
prevInFlow->StealOverflowFrames());
if (prevOverflowFrames) {
// Assume that our prev-in-flow has the same line container that we do.
const nsFrameList::Slice& newFrames =
mFrames.InsertFrames(this, nullptr, *prevOverflowFrames);
ReparentChildListStyle(PresContext(), newFrames, this);
ReparentChildListStyle(presContext, newFrames, this);
}
}
}

View File

@ -22,6 +22,7 @@
#include <algorithm>
using namespace mozilla;
using namespace mozilla::layout;
nsTableRowGroupFrame::nsTableRowGroupFrame(nsStyleContext* aContext):
nsContainerFrame(aContext)
@ -971,7 +972,7 @@ nsTableRowGroupFrame::UndoContinuedRow(nsPresContext* aPresContext,
NS_PRECONDITION(mFrames.ContainsFrame(rowBefore),
"rowBefore not in our frame list?");
nsAutoPtr<nsFrameList> overflows(StealOverflowFrames());
AutoFrameListPtr overflows(aPresContext, StealOverflowFrames());
if (!rowBefore || !overflows || overflows->IsEmpty() ||
overflows->FirstChild() != aRow) {
NS_ERROR("invalid continued row");
@ -982,10 +983,10 @@ nsTableRowGroupFrame::UndoContinuedRow(nsPresContext* aPresContext,
// will not have reflowed yet to pick up content from any overflow lines.
overflows->DestroyFrame(aRow);
if (overflows->IsEmpty())
return;
// Put the overflow rows into our child list
mFrames.InsertFrames(nullptr, rowBefore, *overflows);
if (!overflows->IsEmpty()) {
mFrames.InsertFrames(nullptr, rowBefore, *overflows);
}
}
static nsTableRowFrame*

View File

@ -306,7 +306,7 @@ nsMenuFrame::DestroyPopupList()
NS_ASSERTION(prop && prop->IsEmpty(),
"popup list must exist and be empty when destroying");
RemoveStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
delete prop;
prop->Delete(PresContext()->PresShell());
}
void
@ -317,7 +317,7 @@ nsMenuFrame::SetPopupFrame(nsFrameList& aFrameList)
if (popupFrame) {
// Remove the frame from the list and store it in a nsFrameList* property.
aFrameList.RemoveFrame(popupFrame);
nsFrameList* popupList = new nsFrameList(popupFrame, popupFrame);
nsFrameList* popupList = new (PresContext()->PresShell()) nsFrameList(popupFrame, popupFrame);
Properties().Set(PopupListProperty(), popupList);
AddStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
break;