Log parser token refcounting, and fix a number of token leaks in view-source that were also leaking strings. Bug 402633, r+sr=mrbkap

This commit is contained in:
bzbarsky@mit.edu 2007-11-07 09:28:22 -08:00
parent 187831740f
commit a9c3d9bdfb
6 changed files with 34 additions and 22 deletions

View File

@ -130,13 +130,14 @@ class CToken {
*/
static void operator delete (void*,size_t) {}
public:
protected:
/**
* destructor
* @update gess5/11/98
*/
virtual ~CToken();
private:
/**
* Destroy a token.
*/
@ -147,18 +148,24 @@ class CToken {
aArenaPool.Free(aToken, sz);
}
public:
/**
* Make a note on number of times you have been referenced
* @update harishd 08/02/00
*/
void AddRef() { ++mUseCount; }
void AddRef() {
++mUseCount;
NS_LOG_ADDREF(this, mUseCount, "CToken", sizeof(*this));
}
/**
* Free yourself if no one is holding you.
* @update harishd 08/02/00
*/
void Release(nsFixedSizeAllocator& aArenaPool) {
if(--mUseCount==0)
--mUseCount;
NS_LOG_RELEASE(this, mUseCount, "CToken");
if (mUseCount==0)
Destroy(this, aArenaPool);
}

View File

@ -364,7 +364,7 @@ public:
virtual void* operator()(void* anObject) {
CToken* aToken = (CToken*)anObject;
CToken::Destroy(aToken, mArenaPool);
aToken->Release(mArenaPool);
return 0;
}
};

View File

@ -74,7 +74,9 @@ nsCParserNode::nsCParserNode(CToken* aToken,
static int theNodeCount = 0;
++theNodeCount;
IF_HOLD(mToken);
if (mTokenAllocator) {
IF_HOLD(mToken);
} // Else a stack-based token
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator = aNodeAllocator;
@ -117,7 +119,9 @@ nsCParserNode::Init(CToken* aToken,
{
mTokenAllocator = aTokenAllocator;
mToken = aToken;
IF_HOLD(mToken);
if (mTokenAllocator) {
IF_HOLD(mToken);
} // Else a stack-based token
mGenericState = PR_FALSE;
mUseCount=0;
#ifdef HEAP_ALLOCATED_NODES

View File

@ -56,11 +56,6 @@ int CToken::GetTokenCount() {
* @update gess 7/21/98
*/
CToken::CToken(PRInt32 aTag) {
// Tokens are allocated through the arena ( not heap allocated..yay ).
// We, therefore, don't need this macro anymore..
#ifdef MATCH_CTOR_DTOR
MOZ_COUNT_CTOR(CToken);
#endif
mAttrCount=0;
mNewlineCount=0;
mLineNumber = 0;
@ -72,6 +67,7 @@ CToken::CToken(PRInt32 aTag) {
// rather IF_HOLD. This, also, will make sure that tokens created
// on the stack do not accidently hit the arena recycler.
mUseCount=1;
NS_LOG_ADDREF(this, 1, "CToken", sizeof(*this));
#ifdef NS_DEBUG
++TokenCount;
@ -84,12 +80,13 @@ CToken::CToken(PRInt32 aTag) {
* @update gess 3/25/98
*/
CToken::~CToken() {
// Tokens are allocated through the arena ( not heap allocated..yay ).
// We, therefore, don't need this macro anymore..
#ifdef MATCH_CTOR_DTOR
MOZ_COUNT_DTOR(CToken);
#endif
++DelTokenCount;
#ifdef NS_BUILD_REFCNT_LOGGING
if (mUseCount == 1) {
// Stack token
NS_LOG_RELEASE(this, 0, "CToken");
}
#endif
mUseCount=0;
}

View File

@ -399,6 +399,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
mSink->AddLeaf(theNode);
}
IF_FREE(theToken, theAllocator);
}
result = mSink->CloseContainer(eHTMLTag_head);
@ -428,6 +429,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
result = mSink->OpenContainer(bodyNode);
if(NS_SUCCEEDED(result)) mHasOpenBody=PR_TRUE;
}
IF_FREE(bodyToken, theAllocator);
if (NS_SUCCEEDED(result)) {
CStartToken* preToken =
@ -444,6 +446,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
} else {
result = NS_ERROR_OUT_OF_MEMORY;
}
IF_FREE(preToken, theAllocator);
}
}
}
@ -502,6 +505,7 @@ void CViewSourceHTML::StartNewPreBlock(void){
NS_LITERAL_STRING("id"),
NS_ConvertASCIItoUTF16(nsPrintfCString("line%d", mLineNumber)));
mSink->OpenContainer(startNode);
IF_FREE(theToken, theAllocator);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
@ -531,6 +535,10 @@ void CViewSourceHTML::AddAttrToNode(nsCParserStartNode& aNode,
theAttr->SetKey(aAttrName);
aNode.AddAttribute(theAttr);
// Parser nodes assume that they are being handed a ref when AddAttribute is
// called, unlike Init() and construction, when they actually addref the
// incoming token. Do NOT release here unless this setup changes.
}
/**
@ -747,6 +755,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
NS_LITERAL_STRING("class"),
NS_LITERAL_STRING("error"));
mSink->OpenContainer(mErrorNode);
IF_FREE(theTagToken, theAllocator);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
fprintf(gDumpFile, "<span class=\"error\">");
@ -777,6 +786,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
NS_LITERAL_STRING("class"),
NS_ConvertASCIItoUTF16(kElementClasses[aTagType]));
mSink->OpenContainer(mStartNode); //emit <starttag>...
IF_FREE(theTagToken, theAllocator);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
fprintf(gDumpFile, "<span class=\"");
@ -800,8 +810,6 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
if (mSyntaxHighlight && aTagType != kText) {
mStartNode.ReleaseAll();
CEndToken theEndToken(eHTMLTag_span);
mEndNode.Init(&theEndToken, 0/*stack token*/);
mSink->CloseContainer(eHTMLTag_span); //emit </endtag>...
#ifdef DUMP_TO_FILE
if (gDumpFile)
@ -828,8 +836,6 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
if (mSyntaxHighlight && aTagInError) {
mErrorNode.ReleaseAll();
CEndToken theEndToken(eHTMLTag_span);
mEndErrorNode.Init(&theEndToken, 0/*stack token*/);
mSink->CloseContainer(eHTMLTag_span); //emit </endtag>...
#ifdef DUMP_TO_FILE
if (gDumpFile)

View File

@ -129,12 +129,10 @@ protected:
PRUint32 mTokenCount;
nsCParserNode mEndNode;
nsCParserStartNode mStartNode;
nsCParserStartNode mTokenNode;
CIndirectTextToken mITextToken;
nsCParserStartNode mErrorNode;
nsCParserNode mEndErrorNode;
};
#endif