Fix But #250105 - Add Arena for nsLineLayout buffers. r+sr=roc

git-svn-id: svn://10.0.0.236/trunk@159260 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jim_nance%yahoo.com
2004-07-15 17:50:34 +00:00
parent 3e64390f03
commit b0e12359c6
8 changed files with 166 additions and 254 deletions

View File

@@ -3258,23 +3258,25 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
PRInt32 spins = 0;
#endif
PRUint8 lineReflowStatus = LINE_REFLOW_REDO;
while (LINE_REFLOW_REDO == lineReflowStatus) {
// Prevent overflowing limited thread stacks by creating
// nsLineLayout from the heap when the frame tree depth gets
// large.
if (aState.mReflowState.mReflowDepth > 30) {//XXX layout-tune.h?
rv = DoReflowInlineFramesMalloc(aState, aLine, aKeepReflowGoing,
&lineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
}
else {
rv = DoReflowInlineFramesAuto(aState, aLine, aKeepReflowGoing,
&lineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
}
if (NS_FAILED(rv)) {
break;
}
do {
// Once upon a time we allocated the first 30 nsLineLayout objects
// on the stack, and then we switched to the heap. At that time
// these objects were large (1100 bytes on a 32 bit system).
// Then the nsLineLayout object was shrunk to 156 bytes by
// removing some internal buffers. Given that it is so much
// smaller, the complexity of 2 different ways of allocating
// no longer makes sense. Now we always allocate on the stack
nsLineLayout lineLayout(aState.mPresContext,
aState.mReflowState.mSpaceManager,
&aState.mReflowState,
aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH));
lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber);
rv = DoReflowInlineFrames(aState, lineLayout, aLine,
aKeepReflowGoing, &lineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
lineLayout.EndLineReflow();
#ifdef DEBUG
spins++;
if (1000 == spins) {
@@ -3283,51 +3285,9 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
NS_ABORT();
}
#endif
}
return rv;
}
nsresult
nsBlockFrame::DoReflowInlineFramesMalloc(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea)
{
// XXXldb Using the PresShell arena here would be nice.
nsLineLayout* ll = new nsLineLayout(aState.mPresContext,
aState.mReflowState.mSpaceManager,
&aState.mReflowState,
aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH));
if (!ll) {
return NS_ERROR_OUT_OF_MEMORY;
}
ll->Init(&aState, aState.mMinLineHeight, aState.mLineNumber);
nsresult rv = DoReflowInlineFrames(aState, *ll, aLine, aKeepReflowGoing,
aLineReflowStatus, aUpdateMaximumWidth, aDamageDirtyArea);
ll->EndLineReflow();
delete ll;
return rv;
}
} while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO == lineReflowStatus);
nsresult
nsBlockFrame::DoReflowInlineFramesAuto(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea)
{
nsLineLayout lineLayout(aState.mPresContext,
aState.mReflowState.mSpaceManager,
&aState.mReflowState,
aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH));
lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber);
nsresult rv = DoReflowInlineFrames(aState, lineLayout, aLine,
aKeepReflowGoing, aLineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
lineLayout.EndLineReflow();
return rv;
}

View File

@@ -443,20 +443,6 @@ protected:
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea);
nsresult DoReflowInlineFramesAuto(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea);
nsresult DoReflowInlineFramesMalloc(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea);
nsresult ReflowInlineFrame(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,

View File

@@ -39,6 +39,9 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define PL_ARENA_CONST_ALIGN_MASK (sizeof(void*)-1)
#include "plarena.h"
#include "nsCOMPtr.h"
#include "nsLineLayout.h"
#include "nsBlockFrame.h"
@@ -174,7 +177,7 @@ nsLineLayout::nsLineLayout(nsIPresContext* aPresContext,
// spans, we do it on demand so that situations that only use a few
// frames and spans won't waste alot of time in unneeded
// initialization.
mInitialFramesFreed = mInitialSpansFreed = 0;
PL_INIT_ARENA_POOL(&mArena, "nsLineLayout", 1024);
mFrameFreeList = nsnull;
mSpanFreeList = nsnull;
@@ -190,27 +193,35 @@ nsLineLayout::~nsLineLayout()
NS_ASSERTION(nsnull == mRootSpan, "bad line-layout user");
// Free up all of the per-span-data items that were allocated on the heap
PerSpanData* psd = mSpanFreeList;
while (nsnull != psd) {
PerSpanData* nextSpan = psd->mNextFreeSpan;
if ((psd < &mSpanDataBuf[0]) ||
(psd >= &mSpanDataBuf[NS_LINELAYOUT_NUM_SPANS])) {
delete psd;
}
psd = nextSpan;
}
delete mWordFrames; // operator delete for this class just returns
// Free up all of the per-frame-data items that were allocated on the heap
PerFrameData* pfd = mFrameFreeList;
while (nsnull != pfd) {
PerFrameData* nextFrame = pfd->mNext;
if ((pfd < &mFrameDataBuf[0]) ||
(pfd >= &mFrameDataBuf[NS_LINELAYOUT_NUM_FRAMES])) {
delete pfd;
}
pfd = nextFrame;
}
// PL_FreeArenaPool takes our memory and puts in on a global free list so
// that the next time an arena makes an allocation it will not have to go
// all the way down to malloc. This is desirable as this class is created
// and destroyed in a tight loop.
//
// I looked at the code. It is not technically necessary to call
// PL_FinishArenaPool() after PL_FreeArenaPool(), but from an API
// standpoint, I think we are susposed to. It will be very fast anyway,
// since PL_FreeArenaPool() has done all the work.
PL_FreeArenaPool(&mArena);
PL_FinishArenaPool(&mArena);
}
void*
nsLineLayout::ArenaDeque::operator new(size_t aSize, PLArenaPool &aPool)
{
void *mem;
PL_ARENA_ALLOCATE(mem, &aPool, aSize);
return mem;
}
PRBool nsLineLayout::AllocateDeque()
{
mWordFrames = new(mArena) ArenaDeque;
return mWordFrames != nsnull;
}
// Find out if the frame has a non-null prev-in-flow, i.e., whether it
@@ -477,16 +488,12 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult)
{
PerSpanData* psd = mSpanFreeList;
if (nsnull == psd) {
if (mInitialSpansFreed < NS_LINELAYOUT_NUM_SPANS) {
// use one of the ones defined in our struct...
psd = &mSpanDataBuf[mInitialSpansFreed++];
}
else {
psd = new PerSpanData;
if (nsnull == psd) {
return NS_ERROR_OUT_OF_MEMORY;
}
void *mem;
PL_ARENA_ALLOCATE(mem, &mArena, sizeof(PerSpanData));
if (nsnull == mem) {
return NS_ERROR_OUT_OF_MEMORY;
}
psd = NS_REINTERPRET_CAST(PerSpanData*, mem);
}
else {
mSpanFreeList = psd->mNextFreeSpan;
@@ -757,16 +764,12 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult)
{
PerFrameData* pfd = mFrameFreeList;
if (nsnull == pfd) {
if (mInitialFramesFreed < NS_LINELAYOUT_NUM_FRAMES) {
// use one of the ones defined in our struct...
pfd = &mFrameDataBuf[mInitialFramesFreed++];
}
else {
pfd = new PerFrameData;
if (nsnull == pfd) {
return NS_ERROR_OUT_OF_MEMORY;
}
void *mem;
PL_ARENA_ALLOCATE(mem, &mArena, sizeof(PerFrameData));
if (nsnull == mem) {
return NS_ERROR_OUT_OF_MEMORY;
}
pfd = NS_REINTERPRET_CAST(PerFrameData*, mem);
}
else {
mFrameFreeList = pfd->mNext;
@@ -3018,9 +3021,9 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
void
nsLineLayout::ForgetWordFrame(nsIFrame* aFrame)
{
if (0 != mWordFrames.GetSize()) {
NS_ASSERTION((void*)aFrame == mWordFrames.PeekFront(), "forget-word-frame");
mWordFrames.PopFront();
if (mWordFrames && 0 != mWordFrames->GetSize()) {
NS_ASSERTION((void*)aFrame == mWordFrames->PeekFront(), "forget-word-frame");
mWordFrames->PopFront();
}
}

View File

@@ -51,14 +51,12 @@
#include "nsDeque.h"
#include "nsLineBox.h"
#include "nsBlockReflowState.h"
#include "plarena.h"
class nsSpaceManager;
class nsPlaceholderFrame;
struct nsStyleText;
#define NS_LINELAYOUT_NUM_FRAMES 5
#define NS_LINELAYOUT_NUM_SPANS 5
class nsLineLayout {
public:
nsLineLayout(nsIPresContext* aPresContext,
@@ -67,6 +65,14 @@ public:
PRBool aComputeMaxElementWidth);
~nsLineLayout();
class ArenaDeque : public nsDeque
{
public:
ArenaDeque() : nsDeque(nsnull) {}
void *operator new(size_t, PLArenaPool &pool);
void operator delete(void *) {} // Dont do anything. Its Arena memory
};
void Init(nsBlockReflowState* aState, nscoord aMinLineHeight,
PRInt32 aLineNumber) {
mBlockRS = aState;
@@ -201,17 +207,20 @@ public:
}
void RecordWordFrame(nsIFrame* aWordFrame) {
mWordFrames.Push(aWordFrame);
if(mWordFrames || AllocateDeque())
mWordFrames->Push(aWordFrame);
}
PRBool InWord() const {
return 0 != mWordFrames.GetSize();
return mWordFrames && 0 != mWordFrames->GetSize();
}
void ForgetWordFrame(nsIFrame* aFrame);
void ForgetWordFrames() {
mWordFrames.Empty();
if(mWordFrames) {
mWordFrames->Empty();
}
}
nsIFrame* FindNextText(nsIPresContext* aPresContext, nsIFrame* aFrame);
@@ -311,7 +320,8 @@ protected:
nsLineBox* mLineBox;
PRInt32 mTotalPlacedFrames;
nsDeque mWordFrames;
ArenaDeque *mWordFrames;
PRBool AllocateDeque();
nscoord mTopEdge;
nscoord mBottomEdge;
@@ -403,9 +413,7 @@ protected:
return pfd;
}
};
PerFrameData mFrameDataBuf[NS_LINELAYOUT_NUM_FRAMES];
PerFrameData* mFrameFreeList;
PRInt32 mInitialFramesFreed;
struct PerSpanData {
union {
@@ -442,9 +450,7 @@ protected:
mLastFrame = pfd;
}
};
PerSpanData mSpanDataBuf[NS_LINELAYOUT_NUM_SPANS];
PerSpanData* mSpanFreeList;
PRInt32 mInitialSpansFreed;
PerSpanData* mRootSpan;
PerSpanData* mCurrentSpan;
PRInt32 mSpanDepth;
@@ -452,6 +458,7 @@ protected:
PRInt32 mSpansAllocated, mSpansFreed;
PRInt32 mFramesAllocated, mFramesFreed;
#endif
PLArenaPool mArena; // Per span and per frame data
nsresult NewPerFrameData(PerFrameData** aResult);

View File

@@ -3258,23 +3258,25 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
PRInt32 spins = 0;
#endif
PRUint8 lineReflowStatus = LINE_REFLOW_REDO;
while (LINE_REFLOW_REDO == lineReflowStatus) {
// Prevent overflowing limited thread stacks by creating
// nsLineLayout from the heap when the frame tree depth gets
// large.
if (aState.mReflowState.mReflowDepth > 30) {//XXX layout-tune.h?
rv = DoReflowInlineFramesMalloc(aState, aLine, aKeepReflowGoing,
&lineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
}
else {
rv = DoReflowInlineFramesAuto(aState, aLine, aKeepReflowGoing,
&lineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
}
if (NS_FAILED(rv)) {
break;
}
do {
// Once upon a time we allocated the first 30 nsLineLayout objects
// on the stack, and then we switched to the heap. At that time
// these objects were large (1100 bytes on a 32 bit system).
// Then the nsLineLayout object was shrunk to 156 bytes by
// removing some internal buffers. Given that it is so much
// smaller, the complexity of 2 different ways of allocating
// no longer makes sense. Now we always allocate on the stack
nsLineLayout lineLayout(aState.mPresContext,
aState.mReflowState.mSpaceManager,
&aState.mReflowState,
aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH));
lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber);
rv = DoReflowInlineFrames(aState, lineLayout, aLine,
aKeepReflowGoing, &lineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
lineLayout.EndLineReflow();
#ifdef DEBUG
spins++;
if (1000 == spins) {
@@ -3283,51 +3285,9 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
NS_ABORT();
}
#endif
}
return rv;
}
nsresult
nsBlockFrame::DoReflowInlineFramesMalloc(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea)
{
// XXXldb Using the PresShell arena here would be nice.
nsLineLayout* ll = new nsLineLayout(aState.mPresContext,
aState.mReflowState.mSpaceManager,
&aState.mReflowState,
aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH));
if (!ll) {
return NS_ERROR_OUT_OF_MEMORY;
}
ll->Init(&aState, aState.mMinLineHeight, aState.mLineNumber);
nsresult rv = DoReflowInlineFrames(aState, *ll, aLine, aKeepReflowGoing,
aLineReflowStatus, aUpdateMaximumWidth, aDamageDirtyArea);
ll->EndLineReflow();
delete ll;
return rv;
}
} while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO == lineReflowStatus);
nsresult
nsBlockFrame::DoReflowInlineFramesAuto(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea)
{
nsLineLayout lineLayout(aState.mPresContext,
aState.mReflowState.mSpaceManager,
&aState.mReflowState,
aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH));
lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber);
nsresult rv = DoReflowInlineFrames(aState, lineLayout, aLine,
aKeepReflowGoing, aLineReflowStatus,
aUpdateMaximumWidth, aDamageDirtyArea);
lineLayout.EndLineReflow();
return rv;
}

View File

@@ -443,20 +443,6 @@ protected:
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea);
nsresult DoReflowInlineFramesAuto(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea);
nsresult DoReflowInlineFramesMalloc(nsBlockReflowState& aState,
line_iterator aLine,
PRBool* aKeepReflowGoing,
PRUint8* aLineReflowStatus,
PRBool aUpdateMaximumWidth,
PRBool aDamageDirtyArea);
nsresult ReflowInlineFrame(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,

View File

@@ -39,6 +39,9 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define PL_ARENA_CONST_ALIGN_MASK (sizeof(void*)-1)
#include "plarena.h"
#include "nsCOMPtr.h"
#include "nsLineLayout.h"
#include "nsBlockFrame.h"
@@ -174,7 +177,7 @@ nsLineLayout::nsLineLayout(nsIPresContext* aPresContext,
// spans, we do it on demand so that situations that only use a few
// frames and spans won't waste alot of time in unneeded
// initialization.
mInitialFramesFreed = mInitialSpansFreed = 0;
PL_INIT_ARENA_POOL(&mArena, "nsLineLayout", 1024);
mFrameFreeList = nsnull;
mSpanFreeList = nsnull;
@@ -190,27 +193,35 @@ nsLineLayout::~nsLineLayout()
NS_ASSERTION(nsnull == mRootSpan, "bad line-layout user");
// Free up all of the per-span-data items that were allocated on the heap
PerSpanData* psd = mSpanFreeList;
while (nsnull != psd) {
PerSpanData* nextSpan = psd->mNextFreeSpan;
if ((psd < &mSpanDataBuf[0]) ||
(psd >= &mSpanDataBuf[NS_LINELAYOUT_NUM_SPANS])) {
delete psd;
}
psd = nextSpan;
}
delete mWordFrames; // operator delete for this class just returns
// Free up all of the per-frame-data items that were allocated on the heap
PerFrameData* pfd = mFrameFreeList;
while (nsnull != pfd) {
PerFrameData* nextFrame = pfd->mNext;
if ((pfd < &mFrameDataBuf[0]) ||
(pfd >= &mFrameDataBuf[NS_LINELAYOUT_NUM_FRAMES])) {
delete pfd;
}
pfd = nextFrame;
}
// PL_FreeArenaPool takes our memory and puts in on a global free list so
// that the next time an arena makes an allocation it will not have to go
// all the way down to malloc. This is desirable as this class is created
// and destroyed in a tight loop.
//
// I looked at the code. It is not technically necessary to call
// PL_FinishArenaPool() after PL_FreeArenaPool(), but from an API
// standpoint, I think we are susposed to. It will be very fast anyway,
// since PL_FreeArenaPool() has done all the work.
PL_FreeArenaPool(&mArena);
PL_FinishArenaPool(&mArena);
}
void*
nsLineLayout::ArenaDeque::operator new(size_t aSize, PLArenaPool &aPool)
{
void *mem;
PL_ARENA_ALLOCATE(mem, &aPool, aSize);
return mem;
}
PRBool nsLineLayout::AllocateDeque()
{
mWordFrames = new(mArena) ArenaDeque;
return mWordFrames != nsnull;
}
// Find out if the frame has a non-null prev-in-flow, i.e., whether it
@@ -477,16 +488,12 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult)
{
PerSpanData* psd = mSpanFreeList;
if (nsnull == psd) {
if (mInitialSpansFreed < NS_LINELAYOUT_NUM_SPANS) {
// use one of the ones defined in our struct...
psd = &mSpanDataBuf[mInitialSpansFreed++];
}
else {
psd = new PerSpanData;
if (nsnull == psd) {
return NS_ERROR_OUT_OF_MEMORY;
}
void *mem;
PL_ARENA_ALLOCATE(mem, &mArena, sizeof(PerSpanData));
if (nsnull == mem) {
return NS_ERROR_OUT_OF_MEMORY;
}
psd = NS_REINTERPRET_CAST(PerSpanData*, mem);
}
else {
mSpanFreeList = psd->mNextFreeSpan;
@@ -757,16 +764,12 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult)
{
PerFrameData* pfd = mFrameFreeList;
if (nsnull == pfd) {
if (mInitialFramesFreed < NS_LINELAYOUT_NUM_FRAMES) {
// use one of the ones defined in our struct...
pfd = &mFrameDataBuf[mInitialFramesFreed++];
}
else {
pfd = new PerFrameData;
if (nsnull == pfd) {
return NS_ERROR_OUT_OF_MEMORY;
}
void *mem;
PL_ARENA_ALLOCATE(mem, &mArena, sizeof(PerFrameData));
if (nsnull == mem) {
return NS_ERROR_OUT_OF_MEMORY;
}
pfd = NS_REINTERPRET_CAST(PerFrameData*, mem);
}
else {
mFrameFreeList = pfd->mNext;
@@ -3018,9 +3021,9 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
void
nsLineLayout::ForgetWordFrame(nsIFrame* aFrame)
{
if (0 != mWordFrames.GetSize()) {
NS_ASSERTION((void*)aFrame == mWordFrames.PeekFront(), "forget-word-frame");
mWordFrames.PopFront();
if (mWordFrames && 0 != mWordFrames->GetSize()) {
NS_ASSERTION((void*)aFrame == mWordFrames->PeekFront(), "forget-word-frame");
mWordFrames->PopFront();
}
}

View File

@@ -51,14 +51,12 @@
#include "nsDeque.h"
#include "nsLineBox.h"
#include "nsBlockReflowState.h"
#include "plarena.h"
class nsSpaceManager;
class nsPlaceholderFrame;
struct nsStyleText;
#define NS_LINELAYOUT_NUM_FRAMES 5
#define NS_LINELAYOUT_NUM_SPANS 5
class nsLineLayout {
public:
nsLineLayout(nsIPresContext* aPresContext,
@@ -67,6 +65,14 @@ public:
PRBool aComputeMaxElementWidth);
~nsLineLayout();
class ArenaDeque : public nsDeque
{
public:
ArenaDeque() : nsDeque(nsnull) {}
void *operator new(size_t, PLArenaPool &pool);
void operator delete(void *) {} // Dont do anything. Its Arena memory
};
void Init(nsBlockReflowState* aState, nscoord aMinLineHeight,
PRInt32 aLineNumber) {
mBlockRS = aState;
@@ -201,17 +207,20 @@ public:
}
void RecordWordFrame(nsIFrame* aWordFrame) {
mWordFrames.Push(aWordFrame);
if(mWordFrames || AllocateDeque())
mWordFrames->Push(aWordFrame);
}
PRBool InWord() const {
return 0 != mWordFrames.GetSize();
return mWordFrames && 0 != mWordFrames->GetSize();
}
void ForgetWordFrame(nsIFrame* aFrame);
void ForgetWordFrames() {
mWordFrames.Empty();
if(mWordFrames) {
mWordFrames->Empty();
}
}
nsIFrame* FindNextText(nsIPresContext* aPresContext, nsIFrame* aFrame);
@@ -311,7 +320,8 @@ protected:
nsLineBox* mLineBox;
PRInt32 mTotalPlacedFrames;
nsDeque mWordFrames;
ArenaDeque *mWordFrames;
PRBool AllocateDeque();
nscoord mTopEdge;
nscoord mBottomEdge;
@@ -403,9 +413,7 @@ protected:
return pfd;
}
};
PerFrameData mFrameDataBuf[NS_LINELAYOUT_NUM_FRAMES];
PerFrameData* mFrameFreeList;
PRInt32 mInitialFramesFreed;
struct PerSpanData {
union {
@@ -442,9 +450,7 @@ protected:
mLastFrame = pfd;
}
};
PerSpanData mSpanDataBuf[NS_LINELAYOUT_NUM_SPANS];
PerSpanData* mSpanFreeList;
PRInt32 mInitialSpansFreed;
PerSpanData* mRootSpan;
PerSpanData* mCurrentSpan;
PRInt32 mSpanDepth;
@@ -452,6 +458,7 @@ protected:
PRInt32 mSpansAllocated, mSpansFreed;
PRInt32 mFramesAllocated, mFramesFreed;
#endif
PLArenaPool mArena; // Per span and per frame data
nsresult NewPerFrameData(PerFrameData** aResult);