Bug 165893 - avoid refetching the parser service all the time. r=jst@netscape.com, sr=bzbarsky@mit.edu

This commit is contained in:
bratell%lysator.liu.se 2002-11-19 13:39:20 +00:00
parent 96b32eadc1
commit 60ab58236e
3 changed files with 44 additions and 10 deletions

View File

@ -51,6 +51,7 @@ class nsIDocument;
class nsIDocShell;
class nsIScriptSecurityManager;
class nsIThreadJSContextStack;
class nsIParserService;
class nsContentUtils
@ -204,6 +205,8 @@ public:
// element.
static PRBool InProlog(nsIDOMNode *aNode);
static nsIParserService* GetParserServiceWeakRef();
private:
static nsresult doReparentContentWrapper(nsIContent *aChild,
nsIDocument *aNewDocument,
@ -219,6 +222,9 @@ private:
static nsIScriptSecurityManager *sSecurityManager;
static nsIThreadJSContextStack *sThreadJSContextStack;
static nsIParserService *sParserService;
};

View File

@ -57,13 +57,18 @@
#include "nsIJSContextStack.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsParserCIID.h"
#include "nsIParserService.h"
#include "nsIServiceManager.h"
static const char *kJSStackContractID = "@mozilla.org/js/xpc/ContextStack;1";
static NS_DEFINE_IID(kParserServiceCID, NS_PARSERSERVICE_CID);
nsIDOMScriptObjectFactory *nsContentUtils::sDOMScriptObjectFactory = nsnull;
nsIXPConnect *nsContentUtils::sXPConnect = nsnull;
nsIScriptSecurityManager *nsContentUtils::sSecurityManager = nsnull;
nsIThreadJSContextStack *nsContentUtils::sThreadJSContextStack = nsnull;
nsIParserService *nsContentUtils::sParserService = nsnull;
// static
nsresult
@ -88,6 +93,34 @@ nsContentUtils::Init()
return rv;
}
/**
* Access a cached parser service. Don't addref. We need only one
* reference to it and this class has that one.
*/
/* static */
nsIParserService*
nsContentUtils::GetParserServiceWeakRef()
{
// XXX: This isn't accessed from several threads, is it?
if (sParserService == nsnull) {
// Lock, recheck sCachedParserService and aquire if this should be
// safe for multiple threads.
nsCOMPtr<nsIServiceManager> mgr;
nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr));
if (NS_FAILED(rv))
return nsnull;
// This addrefs the service for us and it will be released in
// |Shutdown|.
mgr->GetService(kParserServiceCID,
NS_GET_IID(nsIParserService),
NS_REINTERPRET_CAST(void**, &sParserService));
}
return sParserService;
}
// static
nsresult
nsContentUtils::GetStaticScriptGlobal(JSContext* aContext, JSObject* aObj,
@ -346,6 +379,7 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sXPConnect);
NS_IF_RELEASE(sSecurityManager);
NS_IF_RELEASE(sThreadJSContextStack);
NS_IF_RELEASE(sParserService);
}
// static

View File

@ -125,7 +125,6 @@
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIParserService.h"
#include "nsParserCIID.h"
#include "nsISelectElement.h"
#include "nsITextAreaElement.h"
@ -169,8 +168,6 @@ const PRBool kBlockByDefault = PR_TRUE;
#endif
static NS_DEFINE_IID(kParserServiceCID, NS_PARSERSERVICE_CID);
//----------------------------------------------------------------------
#ifdef NS_DEBUG
@ -1070,11 +1067,9 @@ NS_CreateHTMLElement(nsIHTMLContent** aResult, nsINodeInfo *aNodeInfo,
{
nsresult rv = NS_OK;
// Cache this service! The XML content sink uses this method!
nsCOMPtr<nsIParserService> parserService =
do_GetService(kParserServiceCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsIParserService* parserService = nsContentUtils::GetParserServiceWeakRef();
if (!parserService)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIAtom> name;
rv = aNodeInfo->GetNameAtom(*getter_AddRefs(name));
@ -2546,8 +2541,7 @@ HTMLContentSink::Init(nsIDocument* aDoc,
mObservers = nsnull;
nsCOMPtr<nsIParserService> service(do_GetService(kParserServiceCID));
nsIParserService* service = nsContentUtils::GetParserServiceWeakRef();
if (!service) {
return NS_ERROR_OUT_OF_MEMORY;
}