mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Back out most of patch for bug 154910 to fix crash, since nsLineLayout need not do all its allocation without other things lower on the stack. b=162516
This commit is contained in:
parent
22351decd5
commit
815f207e63
@ -179,16 +179,18 @@ nsLineLayout::nsLineLayout(nsIPresContext* aPresContext,
|
||||
mTotalPlacedFrames = 0;
|
||||
mTopEdge = mBottomEdge = 0;
|
||||
|
||||
// Instead of always pre-initializing the free-lists for frames and
|
||||
// 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;
|
||||
mFrameFreeList = nsnull;
|
||||
mSpanFreeList = nsnull;
|
||||
|
||||
mCurrentSpan = mRootSpan = nsnull;
|
||||
mSpanDepth = 0;
|
||||
|
||||
mPresContext->GetCompatibilityMode(&mCompatMode);
|
||||
|
||||
// Mark the dynamic stack on which we will allocate |PerSpanData| and
|
||||
// |PerFrameData| objects.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
shell->PushStackMemory();
|
||||
}
|
||||
|
||||
nsLineLayout::~nsLineLayout()
|
||||
@ -197,11 +199,27 @@ nsLineLayout::~nsLineLayout()
|
||||
|
||||
NS_ASSERTION(nsnull == mRootSpan, "bad line-layout user");
|
||||
|
||||
// Free up the space in which we allocated |PerSpanData| and
|
||||
// |PerFrameData| objects.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
shell->PopStackMemory();
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Find out if the frame has a non-null prev-in-flow, i.e., whether it
|
||||
@ -242,6 +260,9 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
|
||||
aImpactedByFloaters?"true":"false",
|
||||
aIsTopOfPage ? "top-of-page" : "");
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
mSpansAllocated = mSpansFreed = mFramesAllocated = mFramesFreed = 0;
|
||||
#endif
|
||||
|
||||
mColumn = 0;
|
||||
|
||||
@ -332,7 +353,24 @@ nsLineLayout::EndLineReflow()
|
||||
printf(": EndLineReflow: width=%d\n", mRootSpan->mX - mRootSpan->mLeftEdge);
|
||||
#endif
|
||||
|
||||
FreeSpan(mRootSpan);
|
||||
mCurrentSpan = mRootSpan = nsnull;
|
||||
|
||||
NS_ASSERTION(mSpansAllocated == mSpansFreed, "leak");
|
||||
NS_ASSERTION(mFramesAllocated == mFramesFreed, "leak");
|
||||
|
||||
#if 0
|
||||
static PRInt32 maxSpansAllocated = NS_LINELAYOUT_NUM_SPANS;
|
||||
static PRInt32 maxFramesAllocated = NS_LINELAYOUT_NUM_FRAMES;
|
||||
if (mSpansAllocated > maxSpansAllocated) {
|
||||
printf("XXX: saw a line with %d spans\n", mSpansAllocated);
|
||||
maxSpansAllocated = mSpansAllocated;
|
||||
}
|
||||
if (mFramesAllocated > maxFramesAllocated) {
|
||||
printf("XXX: saw a line with %d frames\n", mFramesAllocated);
|
||||
maxFramesAllocated = mFramesAllocated;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// XXX swtich to a single mAvailLineWidth that we adjust as each frame
|
||||
@ -455,12 +493,22 @@ nsLineLayout::UpdateFrames()
|
||||
nsresult
|
||||
nsLineLayout::NewPerSpanData(PerSpanData** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
PerSpanData* psd = new (shell) PerSpanData;
|
||||
if (!psd)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mSpanFreeList = psd->mNextFreeSpan;
|
||||
}
|
||||
psd->mParent = nsnull;
|
||||
psd->mFrame = nsnull;
|
||||
psd->mFirstFrame = nsnull;
|
||||
@ -468,6 +516,9 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult)
|
||||
psd->mContainsFloater = PR_FALSE;
|
||||
psd->mZeroEffectiveSpanBox = PR_FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
mSpansAllocated++;
|
||||
#endif
|
||||
*aResult = psd;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -618,10 +669,25 @@ nsLineLayout::SplitLineTo(PRInt32 aNewCount)
|
||||
PerFrameData* pfd = psd->mFirstFrame;
|
||||
while (nsnull != pfd) {
|
||||
if (--aNewCount == 0) {
|
||||
// Truncate list at pfd (we keep pfd; leak the rest in dynamic stack)
|
||||
// Truncate list at pfd (we keep pfd, but anything following is freed)
|
||||
PerFrameData* next = pfd->mNext;
|
||||
pfd->mNext = nsnull;
|
||||
psd->mLastFrame = pfd;
|
||||
|
||||
// Now release all of the frames following pfd
|
||||
pfd = next;
|
||||
while (nsnull != pfd) {
|
||||
next = pfd->mNext;
|
||||
pfd->mNext = mFrameFreeList;
|
||||
mFrameFreeList = pfd;
|
||||
#ifdef DEBUG
|
||||
mFramesFreed++;
|
||||
#endif
|
||||
if (nsnull != pfd->mSpan) {
|
||||
FreeSpan(pfd->mSpan);
|
||||
}
|
||||
pfd = next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pfd = pfd->mNext;
|
||||
@ -658,6 +724,15 @@ nsLineLayout::PushFrame(nsIFrame* aFrame)
|
||||
psd->mLastFrame = prevFrame;
|
||||
}
|
||||
|
||||
// Now free it, and if it has a span, free that too
|
||||
pfd->mNext = mFrameFreeList;
|
||||
mFrameFreeList = pfd;
|
||||
#ifdef DEBUG
|
||||
mFramesFreed++;
|
||||
#endif
|
||||
if (nsnull != pfd->mSpan) {
|
||||
FreeSpan(pfd->mSpan);
|
||||
}
|
||||
#ifdef NOISY_PUSHING
|
||||
nsFrame::IndentBy(stdout, mSpanDepth);
|
||||
printf("PushFrame: %p after:\n", psd);
|
||||
@ -665,6 +740,32 @@ nsLineLayout::PushFrame(nsIFrame* aFrame)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsLineLayout::FreeSpan(PerSpanData* psd)
|
||||
{
|
||||
// Free its frames
|
||||
PerFrameData* pfd = psd->mFirstFrame;
|
||||
while (nsnull != pfd) {
|
||||
if (nsnull != pfd->mSpan) {
|
||||
FreeSpan(pfd->mSpan);
|
||||
}
|
||||
PerFrameData* next = pfd->mNext;
|
||||
pfd->mNext = mFrameFreeList;
|
||||
mFrameFreeList = pfd;
|
||||
#ifdef DEBUG
|
||||
mFramesFreed++;
|
||||
#endif
|
||||
pfd = next;
|
||||
}
|
||||
|
||||
// Now put the span on the free list since its free too
|
||||
psd->mNextFreeSpan = mSpanFreeList;
|
||||
mSpanFreeList = psd;
|
||||
#ifdef DEBUG
|
||||
mSpansFreed++;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsLineLayout::IsZeroHeight()
|
||||
{
|
||||
@ -682,12 +783,22 @@ nsLineLayout::IsZeroHeight()
|
||||
nsresult
|
||||
nsLineLayout::NewPerFrameData(PerFrameData** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
PerFrameData* pfd = new (shell) PerFrameData;
|
||||
if (!pfd)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mFrameFreeList = pfd->mNext;
|
||||
}
|
||||
pfd->mSpan = nsnull;
|
||||
pfd->mNext = nsnull;
|
||||
pfd->mPrev = nsnull;
|
||||
@ -696,6 +807,7 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult)
|
||||
|
||||
#ifdef DEBUG
|
||||
pfd->mVerticalAlign = 0xFF;
|
||||
mFramesAllocated++;
|
||||
#endif
|
||||
*aResult = pfd;
|
||||
return NS_OK;
|
||||
|
@ -40,6 +40,9 @@ class nsSpaceManager;
|
||||
class nsPlaceholderFrame;
|
||||
struct nsStyleText;
|
||||
|
||||
#define NS_LINELAYOUT_NUM_FRAMES 5
|
||||
#define NS_LINELAYOUT_NUM_SPANS 5
|
||||
|
||||
class nsLineLayout {
|
||||
public:
|
||||
nsLineLayout(nsIPresContext* aPresContext,
|
||||
@ -382,30 +385,19 @@ protected:
|
||||
}
|
||||
return pfd;
|
||||
}
|
||||
|
||||
// PerFrameData objects are allocated in the pres shell's dynamic
|
||||
// stack arena.
|
||||
void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW {
|
||||
void *ptr;
|
||||
aPresShell->AllocateStackMemory(sz, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void* aPtr, size_t sz) {
|
||||
NS_NOTREACHED("PerFrameData destructors are not called");
|
||||
}
|
||||
|
||||
private:
|
||||
// The normal operator new is disallowed.
|
||||
void* operator new(size_t sz) CPP_THROW_NEW { return nsnull; };
|
||||
|
||||
};
|
||||
PerFrameData mFrameDataBuf[NS_LINELAYOUT_NUM_FRAMES];
|
||||
PerFrameData* mFrameFreeList;
|
||||
PRInt32 mInitialFramesFreed;
|
||||
|
||||
#if defined(AIX_XLC_364) || defined(XP_OS2_VACPP)
|
||||
public:
|
||||
#endif
|
||||
struct PerSpanData {
|
||||
PerSpanData* mParent;
|
||||
union {
|
||||
PerSpanData* mParent;
|
||||
PerSpanData* mNextFreeSpan;
|
||||
};
|
||||
PerFrameData* mFrame;
|
||||
PerFrameData* mFirstFrame;
|
||||
PerFrameData* mLastFrame;
|
||||
@ -435,35 +427,27 @@ public:
|
||||
}
|
||||
mLastFrame = pfd;
|
||||
}
|
||||
|
||||
// PerSpanData objects are allocated in the pres shell's dynamic
|
||||
// stack arena.
|
||||
void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW {
|
||||
void *ptr;
|
||||
aPresShell->AllocateStackMemory(sz, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void* aPtr, size_t sz) {
|
||||
NS_NOTREACHED("PerSpanData destructors are not called");
|
||||
}
|
||||
|
||||
private:
|
||||
// The normal operator new is disallowed.
|
||||
void* operator new(size_t sz) CPP_THROW_NEW { return nsnull; };
|
||||
|
||||
};
|
||||
#if defined(AIX_XLC_364) || defined(XP_OS2_VACPP)
|
||||
protected:
|
||||
#endif
|
||||
PerSpanData mSpanDataBuf[NS_LINELAYOUT_NUM_SPANS];
|
||||
PerSpanData* mSpanFreeList;
|
||||
PRInt32 mInitialSpansFreed;
|
||||
PerSpanData* mRootSpan;
|
||||
PerSpanData* mCurrentSpan;
|
||||
PRInt32 mSpanDepth;
|
||||
#ifdef DEBUG
|
||||
PRInt32 mSpansAllocated, mSpansFreed;
|
||||
PRInt32 mFramesAllocated, mFramesFreed;
|
||||
#endif
|
||||
|
||||
nsresult NewPerFrameData(PerFrameData** aResult);
|
||||
|
||||
nsresult NewPerSpanData(PerSpanData** aResult);
|
||||
|
||||
void FreeSpan(PerSpanData* psd);
|
||||
|
||||
PRBool InBlockContext() const {
|
||||
return mSpanDepth == 0;
|
||||
}
|
||||
|
@ -179,16 +179,18 @@ nsLineLayout::nsLineLayout(nsIPresContext* aPresContext,
|
||||
mTotalPlacedFrames = 0;
|
||||
mTopEdge = mBottomEdge = 0;
|
||||
|
||||
// Instead of always pre-initializing the free-lists for frames and
|
||||
// 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;
|
||||
mFrameFreeList = nsnull;
|
||||
mSpanFreeList = nsnull;
|
||||
|
||||
mCurrentSpan = mRootSpan = nsnull;
|
||||
mSpanDepth = 0;
|
||||
|
||||
mPresContext->GetCompatibilityMode(&mCompatMode);
|
||||
|
||||
// Mark the dynamic stack on which we will allocate |PerSpanData| and
|
||||
// |PerFrameData| objects.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
shell->PushStackMemory();
|
||||
}
|
||||
|
||||
nsLineLayout::~nsLineLayout()
|
||||
@ -197,11 +199,27 @@ nsLineLayout::~nsLineLayout()
|
||||
|
||||
NS_ASSERTION(nsnull == mRootSpan, "bad line-layout user");
|
||||
|
||||
// Free up the space in which we allocated |PerSpanData| and
|
||||
// |PerFrameData| objects.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
shell->PopStackMemory();
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Find out if the frame has a non-null prev-in-flow, i.e., whether it
|
||||
@ -242,6 +260,9 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
|
||||
aImpactedByFloaters?"true":"false",
|
||||
aIsTopOfPage ? "top-of-page" : "");
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
mSpansAllocated = mSpansFreed = mFramesAllocated = mFramesFreed = 0;
|
||||
#endif
|
||||
|
||||
mColumn = 0;
|
||||
|
||||
@ -332,7 +353,24 @@ nsLineLayout::EndLineReflow()
|
||||
printf(": EndLineReflow: width=%d\n", mRootSpan->mX - mRootSpan->mLeftEdge);
|
||||
#endif
|
||||
|
||||
FreeSpan(mRootSpan);
|
||||
mCurrentSpan = mRootSpan = nsnull;
|
||||
|
||||
NS_ASSERTION(mSpansAllocated == mSpansFreed, "leak");
|
||||
NS_ASSERTION(mFramesAllocated == mFramesFreed, "leak");
|
||||
|
||||
#if 0
|
||||
static PRInt32 maxSpansAllocated = NS_LINELAYOUT_NUM_SPANS;
|
||||
static PRInt32 maxFramesAllocated = NS_LINELAYOUT_NUM_FRAMES;
|
||||
if (mSpansAllocated > maxSpansAllocated) {
|
||||
printf("XXX: saw a line with %d spans\n", mSpansAllocated);
|
||||
maxSpansAllocated = mSpansAllocated;
|
||||
}
|
||||
if (mFramesAllocated > maxFramesAllocated) {
|
||||
printf("XXX: saw a line with %d frames\n", mFramesAllocated);
|
||||
maxFramesAllocated = mFramesAllocated;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// XXX swtich to a single mAvailLineWidth that we adjust as each frame
|
||||
@ -455,12 +493,22 @@ nsLineLayout::UpdateFrames()
|
||||
nsresult
|
||||
nsLineLayout::NewPerSpanData(PerSpanData** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
PerSpanData* psd = new (shell) PerSpanData;
|
||||
if (!psd)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mSpanFreeList = psd->mNextFreeSpan;
|
||||
}
|
||||
psd->mParent = nsnull;
|
||||
psd->mFrame = nsnull;
|
||||
psd->mFirstFrame = nsnull;
|
||||
@ -468,6 +516,9 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult)
|
||||
psd->mContainsFloater = PR_FALSE;
|
||||
psd->mZeroEffectiveSpanBox = PR_FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
mSpansAllocated++;
|
||||
#endif
|
||||
*aResult = psd;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -618,10 +669,25 @@ nsLineLayout::SplitLineTo(PRInt32 aNewCount)
|
||||
PerFrameData* pfd = psd->mFirstFrame;
|
||||
while (nsnull != pfd) {
|
||||
if (--aNewCount == 0) {
|
||||
// Truncate list at pfd (we keep pfd; leak the rest in dynamic stack)
|
||||
// Truncate list at pfd (we keep pfd, but anything following is freed)
|
||||
PerFrameData* next = pfd->mNext;
|
||||
pfd->mNext = nsnull;
|
||||
psd->mLastFrame = pfd;
|
||||
|
||||
// Now release all of the frames following pfd
|
||||
pfd = next;
|
||||
while (nsnull != pfd) {
|
||||
next = pfd->mNext;
|
||||
pfd->mNext = mFrameFreeList;
|
||||
mFrameFreeList = pfd;
|
||||
#ifdef DEBUG
|
||||
mFramesFreed++;
|
||||
#endif
|
||||
if (nsnull != pfd->mSpan) {
|
||||
FreeSpan(pfd->mSpan);
|
||||
}
|
||||
pfd = next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pfd = pfd->mNext;
|
||||
@ -658,6 +724,15 @@ nsLineLayout::PushFrame(nsIFrame* aFrame)
|
||||
psd->mLastFrame = prevFrame;
|
||||
}
|
||||
|
||||
// Now free it, and if it has a span, free that too
|
||||
pfd->mNext = mFrameFreeList;
|
||||
mFrameFreeList = pfd;
|
||||
#ifdef DEBUG
|
||||
mFramesFreed++;
|
||||
#endif
|
||||
if (nsnull != pfd->mSpan) {
|
||||
FreeSpan(pfd->mSpan);
|
||||
}
|
||||
#ifdef NOISY_PUSHING
|
||||
nsFrame::IndentBy(stdout, mSpanDepth);
|
||||
printf("PushFrame: %p after:\n", psd);
|
||||
@ -665,6 +740,32 @@ nsLineLayout::PushFrame(nsIFrame* aFrame)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsLineLayout::FreeSpan(PerSpanData* psd)
|
||||
{
|
||||
// Free its frames
|
||||
PerFrameData* pfd = psd->mFirstFrame;
|
||||
while (nsnull != pfd) {
|
||||
if (nsnull != pfd->mSpan) {
|
||||
FreeSpan(pfd->mSpan);
|
||||
}
|
||||
PerFrameData* next = pfd->mNext;
|
||||
pfd->mNext = mFrameFreeList;
|
||||
mFrameFreeList = pfd;
|
||||
#ifdef DEBUG
|
||||
mFramesFreed++;
|
||||
#endif
|
||||
pfd = next;
|
||||
}
|
||||
|
||||
// Now put the span on the free list since its free too
|
||||
psd->mNextFreeSpan = mSpanFreeList;
|
||||
mSpanFreeList = psd;
|
||||
#ifdef DEBUG
|
||||
mSpansFreed++;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsLineLayout::IsZeroHeight()
|
||||
{
|
||||
@ -682,12 +783,22 @@ nsLineLayout::IsZeroHeight()
|
||||
nsresult
|
||||
nsLineLayout::NewPerFrameData(PerFrameData** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
PerFrameData* pfd = new (shell) PerFrameData;
|
||||
if (!pfd)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mFrameFreeList = pfd->mNext;
|
||||
}
|
||||
pfd->mSpan = nsnull;
|
||||
pfd->mNext = nsnull;
|
||||
pfd->mPrev = nsnull;
|
||||
@ -696,6 +807,7 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult)
|
||||
|
||||
#ifdef DEBUG
|
||||
pfd->mVerticalAlign = 0xFF;
|
||||
mFramesAllocated++;
|
||||
#endif
|
||||
*aResult = pfd;
|
||||
return NS_OK;
|
||||
|
@ -40,6 +40,9 @@ class nsSpaceManager;
|
||||
class nsPlaceholderFrame;
|
||||
struct nsStyleText;
|
||||
|
||||
#define NS_LINELAYOUT_NUM_FRAMES 5
|
||||
#define NS_LINELAYOUT_NUM_SPANS 5
|
||||
|
||||
class nsLineLayout {
|
||||
public:
|
||||
nsLineLayout(nsIPresContext* aPresContext,
|
||||
@ -382,30 +385,19 @@ protected:
|
||||
}
|
||||
return pfd;
|
||||
}
|
||||
|
||||
// PerFrameData objects are allocated in the pres shell's dynamic
|
||||
// stack arena.
|
||||
void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW {
|
||||
void *ptr;
|
||||
aPresShell->AllocateStackMemory(sz, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void* aPtr, size_t sz) {
|
||||
NS_NOTREACHED("PerFrameData destructors are not called");
|
||||
}
|
||||
|
||||
private:
|
||||
// The normal operator new is disallowed.
|
||||
void* operator new(size_t sz) CPP_THROW_NEW { return nsnull; };
|
||||
|
||||
};
|
||||
PerFrameData mFrameDataBuf[NS_LINELAYOUT_NUM_FRAMES];
|
||||
PerFrameData* mFrameFreeList;
|
||||
PRInt32 mInitialFramesFreed;
|
||||
|
||||
#if defined(AIX_XLC_364) || defined(XP_OS2_VACPP)
|
||||
public:
|
||||
#endif
|
||||
struct PerSpanData {
|
||||
PerSpanData* mParent;
|
||||
union {
|
||||
PerSpanData* mParent;
|
||||
PerSpanData* mNextFreeSpan;
|
||||
};
|
||||
PerFrameData* mFrame;
|
||||
PerFrameData* mFirstFrame;
|
||||
PerFrameData* mLastFrame;
|
||||
@ -435,35 +427,27 @@ public:
|
||||
}
|
||||
mLastFrame = pfd;
|
||||
}
|
||||
|
||||
// PerSpanData objects are allocated in the pres shell's dynamic
|
||||
// stack arena.
|
||||
void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW {
|
||||
void *ptr;
|
||||
aPresShell->AllocateStackMemory(sz, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void* aPtr, size_t sz) {
|
||||
NS_NOTREACHED("PerSpanData destructors are not called");
|
||||
}
|
||||
|
||||
private:
|
||||
// The normal operator new is disallowed.
|
||||
void* operator new(size_t sz) CPP_THROW_NEW { return nsnull; };
|
||||
|
||||
};
|
||||
#if defined(AIX_XLC_364) || defined(XP_OS2_VACPP)
|
||||
protected:
|
||||
#endif
|
||||
PerSpanData mSpanDataBuf[NS_LINELAYOUT_NUM_SPANS];
|
||||
PerSpanData* mSpanFreeList;
|
||||
PRInt32 mInitialSpansFreed;
|
||||
PerSpanData* mRootSpan;
|
||||
PerSpanData* mCurrentSpan;
|
||||
PRInt32 mSpanDepth;
|
||||
#ifdef DEBUG
|
||||
PRInt32 mSpansAllocated, mSpansFreed;
|
||||
PRInt32 mFramesAllocated, mFramesFreed;
|
||||
#endif
|
||||
|
||||
nsresult NewPerFrameData(PerFrameData** aResult);
|
||||
|
||||
nsresult NewPerSpanData(PerSpanData** aResult);
|
||||
|
||||
void FreeSpan(PerSpanData* psd);
|
||||
|
||||
PRBool InBlockContext() const {
|
||||
return mSpanDepth == 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user