From 3e283f239c37976092bfa15c858d21e32ca1d971 Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Thu, 30 Sep 2004 05:18:05 +0000 Subject: [PATCH] Improve performance of CSS error reporting. b=261283 r+sr=bzbarsky --- content/html/style/src/nsCSSScanner.cpp | 74 ++++++++++++++++++------- content/html/style/src/nsCSSScanner.h | 8 ++- layout/build/nsLayoutModule.cpp | 2 + layout/style/nsCSSScanner.cpp | 74 ++++++++++++++++++------- layout/style/nsCSSScanner.h | 8 ++- 5 files changed, 122 insertions(+), 44 deletions(-) diff --git a/content/html/style/src/nsCSSScanner.cpp b/content/html/style/src/nsCSSScanner.cpp index 1cf252ccf2ee..972500f12a1e 100644 --- a/content/html/style/src/nsCSSScanner.cpp +++ b/content/html/style/src/nsCSSScanner.cpp @@ -67,6 +67,11 @@ const PRUint8 nsCSSScanner::IS_WHITESPACE = 0x20; static PRBool gLexTableSetup = PR_FALSE; PRUint8 nsCSSScanner::gLexTable[256]; +#ifdef CSS_REPORT_PARSE_ERRORS +static nsIConsoleService *gConsoleService; +static nsIFactory *gScriptErrorFactory; +#endif + /* static */ void nsCSSScanner::BuildLexTable() @@ -168,6 +173,7 @@ nsCSSToken::AppendToString(nsString& aBuffer) MOZ_DECL_CTOR_COUNTER(nsCSSScanner) nsCSSScanner::nsCSSScanner() + : mError(mErrorBuf, NS_ARRAY_LENGTH(mErrorBuf), 0) { MOZ_COUNT_CTOR(nsCSSScanner); if (!gLexTableSetup) { @@ -197,6 +203,36 @@ nsCSSScanner::~nsCSSScanner() } } +/* static */ PRBool nsCSSScanner::InitGlobals() +{ +#ifdef CSS_REPORT_PARSE_ERRORS + if (gConsoleService && gScriptErrorFactory) + return PR_TRUE; + + nsresult rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &gConsoleService); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + + nsCOMPtr compMgr; + rv = NS_GetComponentManager(getter_AddRefs(compMgr)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + rv = compMgr->GetClassObjectByContractID(NS_SCRIPTERROR_CONTRACTID, + NS_GET_IID(nsIFactory), + (void**)&gScriptErrorFactory); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + NS_ASSERTION(gConsoleService && gScriptErrorFactory, + "unexpected null pointer without failure"); +#endif + return PR_TRUE; +} + +/* static */ void nsCSSScanner::ReleaseGlobals() +{ +#ifdef CSS_REPORT_PARSE_ERRORS + NS_IF_RELEASE(gConsoleService); + NS_IF_RELEASE(gScriptErrorFactory); +#endif +} + void nsCSSScanner::Init(nsIUnicharInputStream* aInput, nsIURI* aURI, PRUint32 aLineNumber) { @@ -222,15 +258,14 @@ void nsCSSScanner::Init(nsIUnicharInputStream* aInput, nsIURI* aURI, #define REPORT_UNEXPECTED_EOF(err_) \ AddToError(NS_LITERAL_STRING("Unexpected end of file while searching for ") + err_ + NS_LITERAL_STRING(".")) -void nsCSSScanner::AddToError(const nsAString& aErrorText) +void nsCSSScanner::AddToError(const nsSubstring& aErrorText) { if (mError.IsEmpty()) { mErrorLineNumber = mLineNumber; mErrorColNumber = mColNumber; mError = aErrorText; } else { - // XXX nsAutoString is workaround for string hang bug (bug 74709)! - mError.Append(NS_LITERAL_STRING(" ") + nsAutoString(aErrorText)); + mError.Append(NS_LITERAL_STRING(" ") + aErrorText); } } @@ -250,24 +285,23 @@ void nsCSSScanner::OutputError() #endif // Log it to the JavaScript console - nsCOMPtr consoleService - (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); - nsCOMPtr errorObject - (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); - if (consoleService && errorObject) { - nsresult rv; - PRUnichar *error = ToNewUnicode(mError); - rv = errorObject->Init(error, - NS_ConvertASCIItoUCS2(mFileName.get()).get(), - EmptyString().get(), - mErrorLineNumber, - mErrorColNumber, - 0, - "CSS Parser"); - nsMemory::Free(error); - if (NS_SUCCEEDED(rv)) - consoleService->LogMessage(errorObject); + if (InitGlobals()) { + nsCOMPtr errorObject; + nsresult rv = + gScriptErrorFactory->CreateInstance(nsnull, NS_GET_IID(nsIScriptError), + getter_AddRefs(errorObject)); + if (NS_SUCCEEDED(rv)) { + rv = errorObject->Init(mError.get(), + NS_ConvertASCIItoUCS2(mFileName.get()).get(), + EmptyString().get(), + mErrorLineNumber, + mErrorColNumber, + 0, + "CSS Parser"); + if (NS_SUCCEEDED(rv)) + gConsoleService->LogMessage(errorObject); + } } ClearError(); } diff --git a/content/html/style/src/nsCSSScanner.h b/content/html/style/src/nsCSSScanner.h index 0e3c43959222..8e9998bde58e 100644 --- a/content/html/style/src/nsCSSScanner.h +++ b/content/html/style/src/nsCSSScanner.h @@ -126,8 +126,11 @@ class nsCSSScanner { // when the line number is unknown. void Init(nsIUnicharInputStream* aInput, nsIURI* aURI, PRUint32 aLineNumber); + static PRBool InitGlobals(); + static void ReleaseGlobals(); + #ifdef CSS_REPORT_PARSE_ERRORS - void AddToError(const nsAString& aErrorText); + void AddToError(const nsSubstring& aErrorText); void OutputError(); void ClearError(); #endif @@ -201,7 +204,8 @@ protected: #ifdef CSS_REPORT_PARSE_ERRORS nsXPIDLCString mFileName; PRUint32 mErrorLineNumber, mColNumber, mErrorColNumber; - nsString mError; + nsFixedString mError; + PRUnichar mErrorBuf[200]; #endif static const PRUint8 IS_DIGIT; diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index c55f89a1421f..985687da877f 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -61,6 +61,7 @@ #include "nsIBindingManager.h" #include "nsICSSLoader.h" #include "nsICSSParser.h" +#include "nsCSSScanner.h" #include "nsICSSStyleSheet.h" #include "nsICategoryManager.h" #include "nsIComponentManager.h" @@ -410,6 +411,7 @@ Shutdown() nsImageFrame::ReleaseGlobals(); NS_ShutdownCSSParser(); + nsCSSScanner::ReleaseGlobals(); NS_IF_RELEASE(nsContentDLF::gUAStyleSheet); NS_IF_RELEASE(nsRuleNode::gLangService); diff --git a/layout/style/nsCSSScanner.cpp b/layout/style/nsCSSScanner.cpp index 1cf252ccf2ee..972500f12a1e 100644 --- a/layout/style/nsCSSScanner.cpp +++ b/layout/style/nsCSSScanner.cpp @@ -67,6 +67,11 @@ const PRUint8 nsCSSScanner::IS_WHITESPACE = 0x20; static PRBool gLexTableSetup = PR_FALSE; PRUint8 nsCSSScanner::gLexTable[256]; +#ifdef CSS_REPORT_PARSE_ERRORS +static nsIConsoleService *gConsoleService; +static nsIFactory *gScriptErrorFactory; +#endif + /* static */ void nsCSSScanner::BuildLexTable() @@ -168,6 +173,7 @@ nsCSSToken::AppendToString(nsString& aBuffer) MOZ_DECL_CTOR_COUNTER(nsCSSScanner) nsCSSScanner::nsCSSScanner() + : mError(mErrorBuf, NS_ARRAY_LENGTH(mErrorBuf), 0) { MOZ_COUNT_CTOR(nsCSSScanner); if (!gLexTableSetup) { @@ -197,6 +203,36 @@ nsCSSScanner::~nsCSSScanner() } } +/* static */ PRBool nsCSSScanner::InitGlobals() +{ +#ifdef CSS_REPORT_PARSE_ERRORS + if (gConsoleService && gScriptErrorFactory) + return PR_TRUE; + + nsresult rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &gConsoleService); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + + nsCOMPtr compMgr; + rv = NS_GetComponentManager(getter_AddRefs(compMgr)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + rv = compMgr->GetClassObjectByContractID(NS_SCRIPTERROR_CONTRACTID, + NS_GET_IID(nsIFactory), + (void**)&gScriptErrorFactory); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + NS_ASSERTION(gConsoleService && gScriptErrorFactory, + "unexpected null pointer without failure"); +#endif + return PR_TRUE; +} + +/* static */ void nsCSSScanner::ReleaseGlobals() +{ +#ifdef CSS_REPORT_PARSE_ERRORS + NS_IF_RELEASE(gConsoleService); + NS_IF_RELEASE(gScriptErrorFactory); +#endif +} + void nsCSSScanner::Init(nsIUnicharInputStream* aInput, nsIURI* aURI, PRUint32 aLineNumber) { @@ -222,15 +258,14 @@ void nsCSSScanner::Init(nsIUnicharInputStream* aInput, nsIURI* aURI, #define REPORT_UNEXPECTED_EOF(err_) \ AddToError(NS_LITERAL_STRING("Unexpected end of file while searching for ") + err_ + NS_LITERAL_STRING(".")) -void nsCSSScanner::AddToError(const nsAString& aErrorText) +void nsCSSScanner::AddToError(const nsSubstring& aErrorText) { if (mError.IsEmpty()) { mErrorLineNumber = mLineNumber; mErrorColNumber = mColNumber; mError = aErrorText; } else { - // XXX nsAutoString is workaround for string hang bug (bug 74709)! - mError.Append(NS_LITERAL_STRING(" ") + nsAutoString(aErrorText)); + mError.Append(NS_LITERAL_STRING(" ") + aErrorText); } } @@ -250,24 +285,23 @@ void nsCSSScanner::OutputError() #endif // Log it to the JavaScript console - nsCOMPtr consoleService - (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); - nsCOMPtr errorObject - (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); - if (consoleService && errorObject) { - nsresult rv; - PRUnichar *error = ToNewUnicode(mError); - rv = errorObject->Init(error, - NS_ConvertASCIItoUCS2(mFileName.get()).get(), - EmptyString().get(), - mErrorLineNumber, - mErrorColNumber, - 0, - "CSS Parser"); - nsMemory::Free(error); - if (NS_SUCCEEDED(rv)) - consoleService->LogMessage(errorObject); + if (InitGlobals()) { + nsCOMPtr errorObject; + nsresult rv = + gScriptErrorFactory->CreateInstance(nsnull, NS_GET_IID(nsIScriptError), + getter_AddRefs(errorObject)); + if (NS_SUCCEEDED(rv)) { + rv = errorObject->Init(mError.get(), + NS_ConvertASCIItoUCS2(mFileName.get()).get(), + EmptyString().get(), + mErrorLineNumber, + mErrorColNumber, + 0, + "CSS Parser"); + if (NS_SUCCEEDED(rv)) + gConsoleService->LogMessage(errorObject); + } } ClearError(); } diff --git a/layout/style/nsCSSScanner.h b/layout/style/nsCSSScanner.h index 0e3c43959222..8e9998bde58e 100644 --- a/layout/style/nsCSSScanner.h +++ b/layout/style/nsCSSScanner.h @@ -126,8 +126,11 @@ class nsCSSScanner { // when the line number is unknown. void Init(nsIUnicharInputStream* aInput, nsIURI* aURI, PRUint32 aLineNumber); + static PRBool InitGlobals(); + static void ReleaseGlobals(); + #ifdef CSS_REPORT_PARSE_ERRORS - void AddToError(const nsAString& aErrorText); + void AddToError(const nsSubstring& aErrorText); void OutputError(); void ClearError(); #endif @@ -201,7 +204,8 @@ protected: #ifdef CSS_REPORT_PARSE_ERRORS nsXPIDLCString mFileName; PRUint32 mErrorLineNumber, mColNumber, mErrorColNumber; - nsString mError; + nsFixedString mError; + PRUnichar mErrorBuf[200]; #endif static const PRUint8 IS_DIGIT;