Don't create new nsCSSScanners all the time. Just make nsCSSScanner a

non-pointer member of nsCSSParser so when we recycle parsers scanners get
recycled automatically.  Bug 263959, r+sr=dbaron
This commit is contained in:
bzbarsky%mit.edu 2004-10-14 03:30:55 +00:00
parent f9dc6bdf0e
commit e9d20500ed
6 changed files with 122 additions and 80 deletions

View File

@ -316,8 +316,8 @@ protected:
// Current token. The value is valid after calling GetToken
nsCSSToken mToken;
// Our scanner. We own this and are responsible for deallocating it.
nsCSSScanner* mScanner;
// Our scanner.
nsCSSScanner mScanner;
// The URI to be used as a base for relative URIs.
nsCOMPtr<nsIURI> mBaseURL;
@ -372,6 +372,10 @@ protected:
// All data from successfully parsed properties are placed into |mData|.
nsCSSExpandedDataBlock mData;
#ifdef DEBUG
PRPackedBool mScannerInited;
#endif
};
PR_STATIC_CALLBACK(void) AppendRuleToArray(nsICSSRule* aRule, void* aArray)
@ -401,27 +405,27 @@ NS_NewCSSParser(nsICSSParser** aInstancePtrResult)
#ifdef CSS_REPORT_PARSE_ERRORS
#define REPORT_UNEXPECTED(msg_) \
mScanner->ReportUnexpected(#msg_)
mScanner.ReportUnexpected(#msg_)
#define REPORT_UNEXPECTED_P(msg_, params_) \
mScanner->ReportUnexpectedParams(#msg_, params_, NS_ARRAY_LENGTH(params_))
mScanner.ReportUnexpectedParams(#msg_, params_, NS_ARRAY_LENGTH(params_))
#define REPORT_UNEXPECTED_EOF(lf_) \
mScanner->ReportUnexpectedEOF(#lf_)
mScanner.ReportUnexpectedEOF(#lf_)
#define REPORT_UNEXPECTED_TOKEN(msg_) \
mScanner->ReportUnexpectedToken(mToken, #msg_)
mScanner.ReportUnexpectedToken(mToken, #msg_)
#define REPORT_UNEXPECTED_TOKEN_P(msg_, params_) \
mScanner->ReportUnexpectedTokenParams(mToken, #msg_, \
params_, NS_ARRAY_LENGTH(params_))
mScanner.ReportUnexpectedTokenParams(mToken, #msg_, \
params_, NS_ARRAY_LENGTH(params_))
#define OUTPUT_ERROR() \
mScanner->OutputError()
mScanner.OutputError()
#define CLEAR_ERROR() \
mScanner->ClearError()
mScanner.ClearError()
#else
@ -437,7 +441,7 @@ NS_NewCSSParser(nsICSSParser** aInstancePtrResult)
CSSParserImpl::CSSParserImpl()
: mToken(),
mScanner(nsnull),
mScanner(),
mChildLoader(nsnull),
mSection(eCSSSection_Charset),
mHavePushBack(PR_FALSE),
@ -447,6 +451,9 @@ CSSParserImpl::CSSParserImpl()
#endif
mCaseSensitive(PR_FALSE),
mParsingCompoundProperty(PR_FALSE)
#ifdef DEBUG
, mScannerInited(PR_FALSE)
#endif
{
}
@ -510,13 +517,9 @@ nsresult
CSSParserImpl::InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
PRUint32 aLineNumber, nsIURI* aBaseURI)
{
NS_ASSERTION(! mScanner, "already have scanner");
NS_ASSERTION(! mScannerInited, "already have scanner");
mScanner = new nsCSSScanner();
if (! mScanner) {
return NS_ERROR_OUT_OF_MEMORY;
}
mScanner->Init(aInput, aSheetURI, aLineNumber);
mScanner.Init(aInput, aSheetURI, aLineNumber);
mBaseURL = aBaseURI;
mHavePushBack = PR_FALSE;
@ -527,10 +530,10 @@ CSSParserImpl::InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
nsresult
CSSParserImpl::ReleaseScanner(void)
{
if (mScanner) {
delete mScanner;
mScanner = nsnull;
}
mScanner.Close();
#ifdef DEBUG
mScannerInited = PR_FALSE;
#endif
mBaseURL = nsnull;
return NS_OK;
}
@ -881,7 +884,7 @@ PRBool CSSParserImpl::GetToken(nsresult& aErrorCode, PRBool aSkipWS)
{
for (;;) {
if (!mHavePushBack) {
if (!mScanner->Next(aErrorCode, mToken)) {
if (!mScanner.Next(aErrorCode, mToken)) {
break;
}
}
@ -898,7 +901,7 @@ PRBool CSSParserImpl::GetURLToken(nsresult& aErrorCode, PRBool aSkipWS)
{
for (;;) {
if (! mHavePushBack) {
if (! mScanner->NextURL(aErrorCode, mToken)) {
if (! mScanner.NextURL(aErrorCode, mToken)) {
break;
}
}
@ -1536,7 +1539,7 @@ PRBool CSSParserImpl::ParseRuleSet(nsresult& aErrorCode, RuleAppendFunc aAppendF
{
// First get the list of selectors for the rule
nsCSSSelectorList* slist = nsnull;
PRUint32 linenum = mScanner->GetLineNumber();
PRUint32 linenum = mScanner.GetLineNumber();
if (! ParseSelectorList(aErrorCode, slist)) {
REPORT_UNEXPECTED(PEBadSelectorRSIgnored);
OUTPUT_ERROR();

View File

@ -182,14 +182,12 @@ nsCSSScanner::nsCSSScanner()
// XXX need a monitor
BuildLexTable();
}
mInput = nsnull;
mBuffer = new PRUnichar[BUFFER_SIZE];
mOffset = 0;
mCount = 0;
mPushback = mLocalPushback;
mPushbackCount = 0;
mPushbackSize = 4;
mLastRead = 0;
// No need to init the other members, since they represent state
// which can get cleared. We'll init them every time Init() is
// called.
}
nsCSSScanner::~nsCSSScanner()
@ -234,20 +232,38 @@ nsCSSScanner::~nsCSSScanner()
void nsCSSScanner::Init(nsIUnicharInputStream* aInput, nsIURI* aURI,
PRUint32 aLineNumber)
{
NS_PRECONDITION(nsnull != aInput, "Null input stream pointer");
Close();
NS_PRECONDITION(aInput, "Null input stream pointer");
NS_PRECONDITION(!mInput, "Should not have an existing input stream!");
mInput = aInput;
NS_IF_ADDREF(aInput);
#ifdef CSS_REPORT_PARSE_ERRORS
if (aURI) {
aURI->GetSpec(mFileName);
} else {
mFileName.Adopt(nsCRT::strdup("from DOM"));
// If aURI is the same as mURI, no need to reget mFileName -- it
// shouldn't have changed.
if (aURI != mURI) {
mURI = aURI;
if (aURI) {
aURI->GetSpec(mFileName);
} else {
mFileName.Adopt(nsCRT::strdup("from DOM"));
}
}
mColNumber = 0;
#endif // CSS_REPORT_PARSE_ERRORS
mLineNumber = aLineNumber;
// Reset variables that we use to keep track of our progress through mInput
mOffset = 0;
mCount = 0;
mPushbackCount = 0;
mLastRead = 0;
#ifdef CSS_REPORT_PARSE_ERRORS
mColNumber = 0;
#endif
// Note that we do NOT want to change mBuffer, mPushback, or
// mPushbackCount here. We can keep using the existing values even
// if the input stream we're using has changed.
}
#ifdef CSS_REPORT_PARSE_ERRORS
@ -413,7 +429,7 @@ void nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok,
void nsCSSScanner::Close()
{
NS_IF_RELEASE(mInput);
mInput = nsnull;
}
#ifdef CSS_REPORT_PARSE_ERRORS

View File

@ -40,6 +40,7 @@
#define nsCSSScanner_h___
#include "nsString.h"
#include "nsCOMPtr.h"
class nsIUnicharInputStream;
// XXX turn this off for minimo builds
@ -125,6 +126,7 @@ class nsCSSScanner {
// |aLineNumber == 1| is the beginning of a file, use |aLineNumber == 0|
// when the line number is unknown.
void Init(nsIUnicharInputStream* aInput, nsIURI* aURI, PRUint32 aLineNumber);
void Close();
static PRBool InitGlobals();
static void ReleaseGlobals();
@ -181,7 +183,6 @@ class nsCSSScanner {
}
protected:
void Close();
PRInt32 Read(nsresult& aErrorCode);
PRInt32 Peek(nsresult& aErrorCode);
void Unread();
@ -207,7 +208,7 @@ protected:
nsString& aString);
PRBool GatherIdent(nsresult& aErrorCode, PRInt32 aChar, nsString& aIdent);
nsIUnicharInputStream* mInput;
nsCOMPtr<nsIUnicharInputStream> mInput;
PRUnichar* mBuffer;
PRInt32 mOffset;
PRInt32 mCount;
@ -220,6 +221,7 @@ protected:
PRUint32 mLineNumber;
#ifdef CSS_REPORT_PARSE_ERRORS
nsXPIDLCString mFileName;
nsCOMPtr<nsIURI> mURI; // Cached so we know to not refetch mFileName
PRUint32 mErrorLineNumber, mColNumber, mErrorColNumber;
nsFixedString mError;
PRUnichar mErrorBuf[200];

View File

@ -316,8 +316,8 @@ protected:
// Current token. The value is valid after calling GetToken
nsCSSToken mToken;
// Our scanner. We own this and are responsible for deallocating it.
nsCSSScanner* mScanner;
// Our scanner.
nsCSSScanner mScanner;
// The URI to be used as a base for relative URIs.
nsCOMPtr<nsIURI> mBaseURL;
@ -372,6 +372,10 @@ protected:
// All data from successfully parsed properties are placed into |mData|.
nsCSSExpandedDataBlock mData;
#ifdef DEBUG
PRPackedBool mScannerInited;
#endif
};
PR_STATIC_CALLBACK(void) AppendRuleToArray(nsICSSRule* aRule, void* aArray)
@ -401,27 +405,27 @@ NS_NewCSSParser(nsICSSParser** aInstancePtrResult)
#ifdef CSS_REPORT_PARSE_ERRORS
#define REPORT_UNEXPECTED(msg_) \
mScanner->ReportUnexpected(#msg_)
mScanner.ReportUnexpected(#msg_)
#define REPORT_UNEXPECTED_P(msg_, params_) \
mScanner->ReportUnexpectedParams(#msg_, params_, NS_ARRAY_LENGTH(params_))
mScanner.ReportUnexpectedParams(#msg_, params_, NS_ARRAY_LENGTH(params_))
#define REPORT_UNEXPECTED_EOF(lf_) \
mScanner->ReportUnexpectedEOF(#lf_)
mScanner.ReportUnexpectedEOF(#lf_)
#define REPORT_UNEXPECTED_TOKEN(msg_) \
mScanner->ReportUnexpectedToken(mToken, #msg_)
mScanner.ReportUnexpectedToken(mToken, #msg_)
#define REPORT_UNEXPECTED_TOKEN_P(msg_, params_) \
mScanner->ReportUnexpectedTokenParams(mToken, #msg_, \
params_, NS_ARRAY_LENGTH(params_))
mScanner.ReportUnexpectedTokenParams(mToken, #msg_, \
params_, NS_ARRAY_LENGTH(params_))
#define OUTPUT_ERROR() \
mScanner->OutputError()
mScanner.OutputError()
#define CLEAR_ERROR() \
mScanner->ClearError()
mScanner.ClearError()
#else
@ -437,7 +441,7 @@ NS_NewCSSParser(nsICSSParser** aInstancePtrResult)
CSSParserImpl::CSSParserImpl()
: mToken(),
mScanner(nsnull),
mScanner(),
mChildLoader(nsnull),
mSection(eCSSSection_Charset),
mHavePushBack(PR_FALSE),
@ -447,6 +451,9 @@ CSSParserImpl::CSSParserImpl()
#endif
mCaseSensitive(PR_FALSE),
mParsingCompoundProperty(PR_FALSE)
#ifdef DEBUG
, mScannerInited(PR_FALSE)
#endif
{
}
@ -510,13 +517,9 @@ nsresult
CSSParserImpl::InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
PRUint32 aLineNumber, nsIURI* aBaseURI)
{
NS_ASSERTION(! mScanner, "already have scanner");
NS_ASSERTION(! mScannerInited, "already have scanner");
mScanner = new nsCSSScanner();
if (! mScanner) {
return NS_ERROR_OUT_OF_MEMORY;
}
mScanner->Init(aInput, aSheetURI, aLineNumber);
mScanner.Init(aInput, aSheetURI, aLineNumber);
mBaseURL = aBaseURI;
mHavePushBack = PR_FALSE;
@ -527,10 +530,10 @@ CSSParserImpl::InitScanner(nsIUnicharInputStream* aInput, nsIURI* aSheetURI,
nsresult
CSSParserImpl::ReleaseScanner(void)
{
if (mScanner) {
delete mScanner;
mScanner = nsnull;
}
mScanner.Close();
#ifdef DEBUG
mScannerInited = PR_FALSE;
#endif
mBaseURL = nsnull;
return NS_OK;
}
@ -881,7 +884,7 @@ PRBool CSSParserImpl::GetToken(nsresult& aErrorCode, PRBool aSkipWS)
{
for (;;) {
if (!mHavePushBack) {
if (!mScanner->Next(aErrorCode, mToken)) {
if (!mScanner.Next(aErrorCode, mToken)) {
break;
}
}
@ -898,7 +901,7 @@ PRBool CSSParserImpl::GetURLToken(nsresult& aErrorCode, PRBool aSkipWS)
{
for (;;) {
if (! mHavePushBack) {
if (! mScanner->NextURL(aErrorCode, mToken)) {
if (! mScanner.NextURL(aErrorCode, mToken)) {
break;
}
}
@ -1536,7 +1539,7 @@ PRBool CSSParserImpl::ParseRuleSet(nsresult& aErrorCode, RuleAppendFunc aAppendF
{
// First get the list of selectors for the rule
nsCSSSelectorList* slist = nsnull;
PRUint32 linenum = mScanner->GetLineNumber();
PRUint32 linenum = mScanner.GetLineNumber();
if (! ParseSelectorList(aErrorCode, slist)) {
REPORT_UNEXPECTED(PEBadSelectorRSIgnored);
OUTPUT_ERROR();

View File

@ -182,14 +182,12 @@ nsCSSScanner::nsCSSScanner()
// XXX need a monitor
BuildLexTable();
}
mInput = nsnull;
mBuffer = new PRUnichar[BUFFER_SIZE];
mOffset = 0;
mCount = 0;
mPushback = mLocalPushback;
mPushbackCount = 0;
mPushbackSize = 4;
mLastRead = 0;
// No need to init the other members, since they represent state
// which can get cleared. We'll init them every time Init() is
// called.
}
nsCSSScanner::~nsCSSScanner()
@ -234,20 +232,38 @@ nsCSSScanner::~nsCSSScanner()
void nsCSSScanner::Init(nsIUnicharInputStream* aInput, nsIURI* aURI,
PRUint32 aLineNumber)
{
NS_PRECONDITION(nsnull != aInput, "Null input stream pointer");
Close();
NS_PRECONDITION(aInput, "Null input stream pointer");
NS_PRECONDITION(!mInput, "Should not have an existing input stream!");
mInput = aInput;
NS_IF_ADDREF(aInput);
#ifdef CSS_REPORT_PARSE_ERRORS
if (aURI) {
aURI->GetSpec(mFileName);
} else {
mFileName.Adopt(nsCRT::strdup("from DOM"));
// If aURI is the same as mURI, no need to reget mFileName -- it
// shouldn't have changed.
if (aURI != mURI) {
mURI = aURI;
if (aURI) {
aURI->GetSpec(mFileName);
} else {
mFileName.Adopt(nsCRT::strdup("from DOM"));
}
}
mColNumber = 0;
#endif // CSS_REPORT_PARSE_ERRORS
mLineNumber = aLineNumber;
// Reset variables that we use to keep track of our progress through mInput
mOffset = 0;
mCount = 0;
mPushbackCount = 0;
mLastRead = 0;
#ifdef CSS_REPORT_PARSE_ERRORS
mColNumber = 0;
#endif
// Note that we do NOT want to change mBuffer, mPushback, or
// mPushbackCount here. We can keep using the existing values even
// if the input stream we're using has changed.
}
#ifdef CSS_REPORT_PARSE_ERRORS
@ -413,7 +429,7 @@ void nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok,
void nsCSSScanner::Close()
{
NS_IF_RELEASE(mInput);
mInput = nsnull;
}
#ifdef CSS_REPORT_PARSE_ERRORS

View File

@ -40,6 +40,7 @@
#define nsCSSScanner_h___
#include "nsString.h"
#include "nsCOMPtr.h"
class nsIUnicharInputStream;
// XXX turn this off for minimo builds
@ -125,6 +126,7 @@ class nsCSSScanner {
// |aLineNumber == 1| is the beginning of a file, use |aLineNumber == 0|
// when the line number is unknown.
void Init(nsIUnicharInputStream* aInput, nsIURI* aURI, PRUint32 aLineNumber);
void Close();
static PRBool InitGlobals();
static void ReleaseGlobals();
@ -181,7 +183,6 @@ class nsCSSScanner {
}
protected:
void Close();
PRInt32 Read(nsresult& aErrorCode);
PRInt32 Peek(nsresult& aErrorCode);
void Unread();
@ -207,7 +208,7 @@ protected:
nsString& aString);
PRBool GatherIdent(nsresult& aErrorCode, PRInt32 aChar, nsString& aIdent);
nsIUnicharInputStream* mInput;
nsCOMPtr<nsIUnicharInputStream> mInput;
PRUnichar* mBuffer;
PRInt32 mOffset;
PRInt32 mCount;
@ -220,6 +221,7 @@ protected:
PRUint32 mLineNumber;
#ifdef CSS_REPORT_PARSE_ERRORS
nsXPIDLCString mFileName;
nsCOMPtr<nsIURI> mURI; // Cached so we know to not refetch mFileName
PRUint32 mErrorLineNumber, mColNumber, mErrorColNumber;
nsFixedString mError;
PRUnichar mErrorBuf[200];