mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-05-13 17:07:01 +00:00
Fixing bug 91241. Don't use the service manager to get the element factory everty time it's needed, cache it per namespace id, we spent about 0.9% of startup getting the element factory service. r=dp@netscape.com, sr=rpotts@netscape.com
This commit is contained in:
parent
c87e337f09
commit
7e2f925135
@ -30,6 +30,7 @@
|
|||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
class nsString;
|
class nsString;
|
||||||
class nsINameSpace;
|
class nsINameSpace;
|
||||||
|
class nsIElementFactory;
|
||||||
|
|
||||||
#define kNameSpaceID_Unknown -1
|
#define kNameSpaceID_Unknown -1
|
||||||
#define kNameSpaceID_None 0
|
#define kNameSpaceID_None 0
|
||||||
@ -67,17 +68,24 @@ class nsINameSpace;
|
|||||||
* The "html" and "xml" namespaces come "pre-canned" from the root.
|
* The "html" and "xml" namespaces come "pre-canned" from the root.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class nsINameSpaceManager : public nsISupports {
|
|
||||||
|
class nsINameSpaceManager : public nsISupports
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
static const nsIID& GetIID() { static nsIID iid = NS_INAMESPACEMANAGER_IID; return iid; }
|
NS_DEFINE_STATIC_IID_ACCESSOR(NS_INAMESPACEMANAGER_IID)
|
||||||
|
|
||||||
NS_IMETHOD CreateRootNameSpace(nsINameSpace*& aRootNameSpace) = 0;
|
NS_IMETHOD CreateRootNameSpace(nsINameSpace*& aRootNameSpace) = 0;
|
||||||
|
|
||||||
NS_IMETHOD RegisterNameSpace(const nsAReadableString& aURI,
|
NS_IMETHOD RegisterNameSpace(const nsAReadableString& aURI,
|
||||||
PRInt32& aNameSpaceID) = 0;
|
PRInt32& aNameSpaceID) = 0;
|
||||||
|
|
||||||
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsAWritableString& aURI) = 0;
|
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID,
|
||||||
NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNameSpaceID) = 0;
|
nsAWritableString& aURI) = 0;
|
||||||
|
NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI,
|
||||||
|
PRInt32& aNameSpaceID) = 0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetElementFactory(PRInt32 aNameSpaceID,
|
||||||
|
nsIElementFactory **aElementFactory) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern NS_LAYOUT nsresult
|
extern NS_LAYOUT nsresult
|
||||||
|
@ -22,13 +22,18 @@
|
|||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsINameSpaceManager.h"
|
#include "nsINameSpaceManager.h"
|
||||||
#include "nsINameSpace.h"
|
#include "nsINameSpace.h"
|
||||||
|
#include "nsISupportsArray.h"
|
||||||
|
#include "nsIElementFactory.h"
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
#include "nsHashtable.h"
|
#include "nsHashtable.h"
|
||||||
#include "nsVoidArray.h"
|
#include "nsVoidArray.h"
|
||||||
#include "nsLayoutAtoms.h"
|
#include "nsLayoutAtoms.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
|
#include "nsContentCID.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern nsresult NS_NewXMLElementFactory(nsIElementFactory** aResult);
|
||||||
|
|
||||||
static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns/";
|
static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns/";
|
||||||
static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace";
|
static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace";
|
||||||
@ -41,9 +46,10 @@ static const char kXSLTNameSpaceURI[] = "http://www.w3.org/1999/XSL/Transform";
|
|||||||
//-----------------------------------------------------------
|
//-----------------------------------------------------------
|
||||||
// Name Space ID table support
|
// Name Space ID table support
|
||||||
|
|
||||||
static PRInt32 gNameSpaceTableRefs;
|
static PRInt32 gNameSpaceTableRefs;
|
||||||
static nsHashtable* gURIToIDTable;
|
static nsHashtable* gURIToIDTable;
|
||||||
static nsVoidArray* gURIArray;
|
static nsVoidArray* gURIArray;
|
||||||
|
static nsISupportsArray* gElementFactoryArray;
|
||||||
|
|
||||||
static void AddRefTable()
|
static void AddRefTable()
|
||||||
{
|
{
|
||||||
@ -78,9 +84,12 @@ static void AddRefTable()
|
|||||||
gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink);
|
gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink);
|
||||||
gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML);
|
gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML);
|
||||||
gURIToIDTable->Put(&xsltKey, (void*)kNameSpaceID_XSLT);
|
gURIToIDTable->Put(&xsltKey, (void*)kNameSpaceID_XSLT);
|
||||||
|
|
||||||
|
NS_NewISupportsArray(&gElementFactoryArray);
|
||||||
}
|
}
|
||||||
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
|
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
|
||||||
NS_ASSERTION(nsnull != gURIArray, "no URI array");
|
NS_ASSERTION(nsnull != gURIArray, "no URI array");
|
||||||
|
NS_ASSERTION(nsnull != gElementFactoryArray, "no element factory array");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReleaseTable()
|
static void ReleaseTable()
|
||||||
@ -95,6 +104,8 @@ static void ReleaseTable()
|
|||||||
delete gURIArray;
|
delete gURIArray;
|
||||||
gURIToIDTable = nsnull;
|
gURIToIDTable = nsnull;
|
||||||
gURIArray = nsnull;
|
gURIArray = nsnull;
|
||||||
|
|
||||||
|
NS_IF_RELEASE(gElementFactoryArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,8 +352,10 @@ public:
|
|||||||
PRInt32& aNameSpaceID);
|
PRInt32& aNameSpaceID);
|
||||||
|
|
||||||
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsAWritableString& aURI);
|
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsAWritableString& aURI);
|
||||||
NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNameSpaceID);
|
NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI,
|
||||||
|
PRInt32& aNameSpaceID);
|
||||||
|
NS_IMETHOD GetElementFactory(PRInt32 aNameSpaceID,
|
||||||
|
nsIElementFactory **aElementFactory);
|
||||||
private:
|
private:
|
||||||
// These are not supported and are not implemented!
|
// These are not supported and are not implemented!
|
||||||
NameSpaceManagerImpl(const NameSpaceManagerImpl& aCopy);
|
NameSpaceManagerImpl(const NameSpaceManagerImpl& aCopy);
|
||||||
@ -427,6 +440,67 @@ NameSpaceManagerImpl::GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNa
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
NameSpaceManagerImpl::GetElementFactory(PRInt32 aNameSpaceID,
|
||||||
|
nsIElementFactory **aElementFactory)
|
||||||
|
{
|
||||||
|
*aElementFactory = nsnull;
|
||||||
|
|
||||||
|
NS_ENSURE_TRUE(gElementFactoryArray, NS_ERROR_NOT_INITIALIZED);
|
||||||
|
NS_ENSURE_TRUE(aNameSpaceID >= 0, NS_ERROR_ILLEGAL_VALUE);
|
||||||
|
|
||||||
|
gElementFactoryArray->QueryElementAt(aNameSpaceID,
|
||||||
|
NS_GET_IID(nsIElementFactory),
|
||||||
|
(void **)aElementFactory);
|
||||||
|
|
||||||
|
if (*aElementFactory) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString uri;
|
||||||
|
|
||||||
|
GetNameSpaceURI(aNameSpaceID, uri);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIElementFactory> ef;
|
||||||
|
|
||||||
|
if (!uri.IsEmpty()) {
|
||||||
|
nsCAutoString contract_id(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX);
|
||||||
|
contract_id.Append(NS_ConvertUCS2toUTF8(uri));
|
||||||
|
|
||||||
|
ef = do_GetService(contract_id.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ef) {
|
||||||
|
nsresult rv = NS_NewXMLElementFactory(getter_AddRefs(ef));
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32 count = 0;
|
||||||
|
gElementFactoryArray->Count(&count);
|
||||||
|
|
||||||
|
if ((PRUint32)aNameSpaceID < count) {
|
||||||
|
gElementFactoryArray->ReplaceElementAt(ef, aNameSpaceID);
|
||||||
|
} else {
|
||||||
|
// This sucks, simply doing an InsertElementAt() should IMNSHO
|
||||||
|
// automatically grow the array and insert null's as needed to
|
||||||
|
// fill up the array!?!!
|
||||||
|
|
||||||
|
for (PRInt32 i = count; i < aNameSpaceID; i++) {
|
||||||
|
gElementFactoryArray->AppendElement(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
gElementFactoryArray->AppendElement(ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
*aElementFactory = ef;
|
||||||
|
NS_ADDREF(*aElementFactory);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_LAYOUT nsresult
|
NS_LAYOUT nsresult
|
||||||
NS_NewNameSpaceManager(nsINameSpaceManager** aInstancePtrResult)
|
NS_NewNameSpaceManager(nsINameSpaceManager** aInstancePtrResult)
|
||||||
{
|
{
|
||||||
|
@ -193,6 +193,8 @@ nsXMLContentSink::Init(nsIDocument* aDoc,
|
|||||||
nsIURI* aURL,
|
nsIURI* aURL,
|
||||||
nsIWebShell* aContainer)
|
nsIWebShell* aContainer)
|
||||||
{
|
{
|
||||||
|
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
NS_PRECONDITION(nsnull != aDoc, "null ptr");
|
NS_PRECONDITION(nsnull != aDoc, "null ptr");
|
||||||
NS_PRECONDITION(nsnull != aURL, "null ptr");
|
NS_PRECONDITION(nsnull != aURL, "null ptr");
|
||||||
if ((nsnull == aDoc) || (nsnull == aURL)) {
|
if ((nsnull == aDoc) || (nsnull == aURL)) {
|
||||||
@ -691,8 +693,6 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
|
|||||||
// This is done based off a contractid/namespace scheme.
|
// This is done based off a contractid/namespace scheme.
|
||||||
nsCOMPtr<nsIElementFactory> elementFactory;
|
nsCOMPtr<nsIElementFactory> elementFactory;
|
||||||
|
|
||||||
// This should *not* be done for every node, only when we find
|
|
||||||
// a new namespace!!! -- jst
|
|
||||||
GetElementFactory(nameSpaceID, getter_AddRefs(elementFactory));
|
GetElementFactory(nameSpaceID, getter_AddRefs(elementFactory));
|
||||||
if (elementFactory) {
|
if (elementFactory) {
|
||||||
// Create the content element using the element factory.
|
// Create the content element using the element factory.
|
||||||
@ -1542,7 +1542,8 @@ PRInt32
|
|||||||
nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix)
|
nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix)
|
||||||
{
|
{
|
||||||
PRInt32 id = (nsnull == aPrefix) ? kNameSpaceID_None : kNameSpaceID_Unknown;
|
PRInt32 id = (nsnull == aPrefix) ? kNameSpaceID_None : kNameSpaceID_Unknown;
|
||||||
if ((nsnull != mNameSpaceStack) && (0 < mNameSpaceStack->Count())) {
|
|
||||||
|
if (mNameSpaceStack && mNameSpaceStack->Count() > 0) {
|
||||||
PRInt32 index = mNameSpaceStack->Count() - 1;
|
PRInt32 index = mNameSpaceStack->Count() - 1;
|
||||||
nsINameSpace* nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(index);
|
nsINameSpace* nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(index);
|
||||||
nameSpace->FindNameSpaceID(aPrefix, id);
|
nameSpace->FindNameSpaceID(aPrefix, id);
|
||||||
@ -1890,18 +1891,8 @@ XMLElementFactoryImpl::CreateInstanceByTag(nsINodeInfo *aNodeInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsXMLContentSink::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
nsXMLContentSink::GetElementFactory(PRInt32 aNameSpaceID,
|
||||||
|
nsIElementFactory** aResult)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult);
|
||||||
nsAutoString nameSpace;
|
|
||||||
gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace);
|
|
||||||
|
|
||||||
nsCAutoString contractID( NS_ELEMENT_FACTORY_CONTRACTID_PREFIX );
|
|
||||||
contractID.AppendWithConversion(nameSpace);
|
|
||||||
|
|
||||||
// Retrieve the appropriate factory.
|
|
||||||
nsCOMPtr<nsIElementFactory> elementFactory(do_GetService(contractID, &rv));
|
|
||||||
|
|
||||||
*aResult = elementFactory;
|
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
}
|
||||||
|
@ -4347,14 +4347,6 @@ nsXULDocument::CreateElement(nsINodeInfo *aNodeInfo, nsIContent** aResult)
|
|||||||
rv = nsXULElement::Create(aNodeInfo, getter_AddRefs(result));
|
rv = nsXULElement::Create(aNodeInfo, getter_AddRefs(result));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
}
|
}
|
||||||
else if (aNodeInfo->NamespaceEquals(kNameSpaceID_HTML)) {
|
|
||||||
rv = gHTMLElementFactory->CreateInstanceByTag(aNodeInfo,
|
|
||||||
getter_AddRefs(result));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
if (! result)
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
PRInt32 namespaceID;
|
PRInt32 namespaceID;
|
||||||
aNodeInfo->GetNamespaceID(namespaceID);
|
aNodeInfo->GetNamespaceID(namespaceID);
|
||||||
@ -5844,8 +5836,8 @@ nsXULDocument::CreateElement(nsXULPrototypeElement* aPrototype, nsIContent** aRe
|
|||||||
nsCOMPtr<nsIElementFactory> elementFactory;
|
nsCOMPtr<nsIElementFactory> elementFactory;
|
||||||
GetElementFactory(namespaceID,
|
GetElementFactory(namespaceID,
|
||||||
getter_AddRefs(elementFactory));
|
getter_AddRefs(elementFactory));
|
||||||
elementFactory->CreateInstanceByTag(aPrototype->mNodeInfo,
|
rv = elementFactory->CreateInstanceByTag(aPrototype->mNodeInfo,
|
||||||
getter_AddRefs(result));
|
getter_AddRefs(result));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
if (! result)
|
if (! result)
|
||||||
@ -6582,27 +6574,18 @@ nsXULDocument::RemoveElement(nsIContent* aParent, nsIContent* aChild)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID,
|
||||||
|
nsIElementFactory** aResult)
|
||||||
void
|
|
||||||
nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
|
||||||
{
|
{
|
||||||
nsresult rv;
|
// Retrieve the appropriate factory.
|
||||||
nsAutoString nameSpace;
|
gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult);
|
||||||
gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace);
|
|
||||||
|
|
||||||
nsCAutoString contractID(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX);
|
if (!*aResult) {
|
||||||
contractID.AppendWithConversion(nameSpace);
|
// Nothing found. Use generic XML element.
|
||||||
|
*aResult = gXMLElementFactory;
|
||||||
// Retrieve the appropriate factory.
|
NS_IF_ADDREF(*aResult);
|
||||||
nsCOMPtr<nsIElementFactory> elementFactory(do_GetService(contractID, &rv));
|
}
|
||||||
|
|
||||||
if (!elementFactory)
|
|
||||||
elementFactory = gXMLElementFactory; // Nothing found. Use generic XML element.
|
|
||||||
|
|
||||||
*aResult = elementFactory;
|
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1634,21 +1634,12 @@ nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement, const nsTemplateMat
|
|||||||
void
|
void
|
||||||
nsXULContentBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
nsXULContentBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult);
|
||||||
nsAutoString nameSpace;
|
|
||||||
gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace);
|
|
||||||
|
|
||||||
nsCAutoString contractID(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX);
|
if (!*aResult) {
|
||||||
contractID.AppendWithConversion(nameSpace.get());
|
*aResult = gXMLElementFactory; // Nothing found. Use generic XML element.
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
// Retrieve the appropriate factory.
|
}
|
||||||
nsCOMPtr<nsIElementFactory> elementFactory(do_GetService(contractID, &rv));
|
|
||||||
|
|
||||||
if (!elementFactory)
|
|
||||||
elementFactory = gXMLElementFactory; // Nothing found. Use generic XML element.
|
|
||||||
|
|
||||||
*aResult = elementFactory;
|
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -59,7 +59,6 @@
|
|||||||
#include "nsIBindingManager.h"
|
#include "nsIBindingManager.h"
|
||||||
#include "nsIDOMNodeList.h"
|
#include "nsIDOMNodeList.h"
|
||||||
#include "nsIHTMLContent.h"
|
#include "nsIHTMLContent.h"
|
||||||
#include "nsIElementFactory.h"
|
|
||||||
#include "nsINameSpace.h"
|
#include "nsINameSpace.h"
|
||||||
#include "nsINameSpaceManager.h"
|
#include "nsINameSpaceManager.h"
|
||||||
#include "nsIRDFCompositeDataSource.h"
|
#include "nsIRDFCompositeDataSource.h"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user