Skip to content

Commit

Permalink
Bug 729519 - Allocate heap nsFrameLists from the shell arena. r=bzbarsky
Browse files Browse the repository at this point in the history
"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())"
  • Loading branch information
MatsPalmgren committed Apr 1, 2013
1 parent 4e51efe commit 53d1b2f
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 93 deletions.
1 change: 1 addition & 0 deletions layout/base/nsPresArena.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class nsPresArena {
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
Expand Down
38 changes: 19 additions & 19 deletions layout/generic/nsBlockFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand All @@ -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();

Expand All @@ -4515,20 +4517,17 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
}

if (ourPushedFloats->IsEmpty()) {
delete RemovePushedFloats();
RemovePushedFloats()->Delete(presContext->PresShell());
}
}

// After our prev-in-flow has completed reflow, it may have a pushed
// 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);
}
}
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}
Expand Down
6 changes: 3 additions & 3 deletions layout/generic/nsCanvasFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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");
Expand Down
8 changes: 5 additions & 3 deletions layout/generic/nsColumnSetFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <algorithm>

using namespace mozilla;
using namespace mozilla::layout;

class nsColumnSetFrame : public nsContainerFrame {
public:
Expand Down Expand Up @@ -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);
Expand All @@ -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.
Expand Down
24 changes: 14 additions & 10 deletions layout/generic/nsContainerFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::layout;

NS_IMPL_FRAMEARENA_HELPERS(nsContainerFrame)

Expand Down Expand Up @@ -217,6 +218,7 @@ nsContainerFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)

void
nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
FramePropertyTable* aPropTable,
const FramePropertyDescriptor* aProp)
{
Expand All @@ -230,7 +232,7 @@ nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
frame->DestroyFrom(aDestructRoot);
} else {
aPropTable->Remove(this, aProp);
delete frameList;
frameList->Delete(aPresShell);
return;
}
}
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
10 changes: 5 additions & 5 deletions layout/generic/nsContainerFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "nsSplittableFrame.h"
#include "nsFrameList.h"
#include "nsLayoutUtils.h"
#include "nsAutoPtr.h"

// Option flags for ReflowChild() and FinishReflowChild()
// member functions
Expand Down Expand Up @@ -431,10 +430,10 @@ class nsContainerFrame : public nsSplittableFrame
/**
* 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();

Expand Down Expand Up @@ -512,6 +511,7 @@ class nsContainerFrame : public nsSplittableFrame
* Nothing happens if the property doesn't exist.
*/
void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
mozilla::FramePropertyTable* aPropTable,
const FramePropertyDescriptor* aProp);

Expand Down Expand Up @@ -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___ */
12 changes: 6 additions & 6 deletions layout/generic/nsFirstLetterFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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");

Expand All @@ -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);
Expand Down
Loading

0 comments on commit 53d1b2f

Please sign in to comment.