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

@@ -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();
}
}