зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
988c747a4f
Коммит
836da25092
|
@ -30,6 +30,7 @@
|
|||
class nsIAtom;
|
||||
class nsString;
|
||||
class nsINameSpace;
|
||||
class nsIElementFactory;
|
||||
|
||||
#define kNameSpaceID_Unknown -1
|
||||
#define kNameSpaceID_None 0
|
||||
|
@ -67,17 +68,24 @@ class nsINameSpace;
|
|||
* The "html" and "xml" namespaces come "pre-canned" from the root.
|
||||
*
|
||||
*/
|
||||
class nsINameSpaceManager : public nsISupports {
|
||||
|
||||
class nsINameSpaceManager : public nsISupports
|
||||
{
|
||||
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 RegisterNameSpace(const nsAReadableString& aURI,
|
||||
PRInt32& aNameSpaceID) = 0;
|
||||
|
||||
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsAWritableString& aURI) = 0;
|
||||
NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNameSpaceID) = 0;
|
||||
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID,
|
||||
nsAWritableString& aURI) = 0;
|
||||
NS_IMETHOD GetNameSpaceID(const nsAReadableString& aURI,
|
||||
PRInt32& aNameSpaceID) = 0;
|
||||
|
||||
NS_IMETHOD GetElementFactory(PRInt32 aNameSpaceID,
|
||||
nsIElementFactory **aElementFactory) = 0;
|
||||
};
|
||||
|
||||
extern NS_LAYOUT nsresult
|
||||
|
|
|
@ -22,13 +22,18 @@
|
|||
#include "nscore.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsINameSpace.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIElementFactory.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsString.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 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
|
||||
|
||||
static PRInt32 gNameSpaceTableRefs;
|
||||
static nsHashtable* gURIToIDTable;
|
||||
static nsVoidArray* gURIArray;
|
||||
static PRInt32 gNameSpaceTableRefs;
|
||||
static nsHashtable* gURIToIDTable;
|
||||
static nsVoidArray* gURIArray;
|
||||
static nsISupportsArray* gElementFactoryArray;
|
||||
|
||||
static void AddRefTable()
|
||||
{
|
||||
|
@ -78,9 +84,12 @@ static void AddRefTable()
|
|||
gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink);
|
||||
gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML);
|
||||
gURIToIDTable->Put(&xsltKey, (void*)kNameSpaceID_XSLT);
|
||||
|
||||
NS_NewISupportsArray(&gElementFactoryArray);
|
||||
}
|
||||
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
|
||||
NS_ASSERTION(nsnull != gURIArray, "no URI array");
|
||||
NS_ASSERTION(nsnull != gElementFactoryArray, "no element factory array");
|
||||
}
|
||||
|
||||
static void ReleaseTable()
|
||||
|
@ -95,6 +104,8 @@ static void ReleaseTable()
|
|||
delete gURIArray;
|
||||
gURIToIDTable = nsnull;
|
||||
gURIArray = nsnull;
|
||||
|
||||
NS_IF_RELEASE(gElementFactoryArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,8 +352,10 @@ public:
|
|||
PRInt32& aNameSpaceID);
|
||||
|
||||
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:
|
||||
// These are not supported and are not implemented!
|
||||
NameSpaceManagerImpl(const NameSpaceManagerImpl& aCopy);
|
||||
|
@ -427,6 +440,67 @@ NameSpaceManagerImpl::GetNameSpaceID(const nsAReadableString& aURI, PRInt32& aNa
|
|||
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_NewNameSpaceManager(nsINameSpaceManager** aInstancePtrResult)
|
||||
{
|
||||
|
|
|
@ -193,6 +193,8 @@ nsXMLContentSink::Init(nsIDocument* aDoc,
|
|||
nsIURI* aURL,
|
||||
nsIWebShell* aContainer)
|
||||
{
|
||||
NS_ENSURE_TRUE(gNameSpaceManager, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_PRECONDITION(nsnull != aDoc, "null ptr");
|
||||
NS_PRECONDITION(nsnull != aURL, "null ptr");
|
||||
if ((nsnull == aDoc) || (nsnull == aURL)) {
|
||||
|
@ -691,8 +693,6 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
|
|||
// This is done based off a contractid/namespace scheme.
|
||||
nsCOMPtr<nsIElementFactory> elementFactory;
|
||||
|
||||
// This should *not* be done for every node, only when we find
|
||||
// a new namespace!!! -- jst
|
||||
GetElementFactory(nameSpaceID, getter_AddRefs(elementFactory));
|
||||
if (elementFactory) {
|
||||
// Create the content element using the element factory.
|
||||
|
@ -1542,7 +1542,8 @@ PRInt32
|
|||
nsXMLContentSink::GetNameSpaceId(nsIAtom* aPrefix)
|
||||
{
|
||||
PRInt32 id = (nsnull == aPrefix) ? kNameSpaceID_None : kNameSpaceID_Unknown;
|
||||
if ((nsnull != mNameSpaceStack) && (0 < mNameSpaceStack->Count())) {
|
||||
|
||||
if (mNameSpaceStack && mNameSpaceStack->Count() > 0) {
|
||||
PRInt32 index = mNameSpaceStack->Count() - 1;
|
||||
nsINameSpace* nameSpace = (nsINameSpace*)mNameSpaceStack->ElementAt(index);
|
||||
nameSpace->FindNameSpaceID(aPrefix, id);
|
||||
|
@ -1890,18 +1891,8 @@ XMLElementFactoryImpl::CreateInstanceByTag(nsINodeInfo *aNodeInfo,
|
|||
}
|
||||
|
||||
void
|
||||
nsXMLContentSink::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
||||
nsXMLContentSink::GetElementFactory(PRInt32 aNameSpaceID,
|
||||
nsIElementFactory** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
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);
|
||||
gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult);
|
||||
}
|
||||
|
|
|
@ -4347,14 +4347,6 @@ nsXULDocument::CreateElement(nsINodeInfo *aNodeInfo, nsIContent** aResult)
|
|||
rv = nsXULElement::Create(aNodeInfo, getter_AddRefs(result));
|
||||
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 {
|
||||
PRInt32 namespaceID;
|
||||
aNodeInfo->GetNamespaceID(namespaceID);
|
||||
|
@ -5844,8 +5836,8 @@ nsXULDocument::CreateElement(nsXULPrototypeElement* aPrototype, nsIContent** aRe
|
|||
nsCOMPtr<nsIElementFactory> elementFactory;
|
||||
GetElementFactory(namespaceID,
|
||||
getter_AddRefs(elementFactory));
|
||||
elementFactory->CreateInstanceByTag(aPrototype->mNodeInfo,
|
||||
getter_AddRefs(result));
|
||||
rv = elementFactory->CreateInstanceByTag(aPrototype->mNodeInfo,
|
||||
getter_AddRefs(result));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (! result)
|
||||
|
@ -6582,27 +6574,18 @@ nsXULDocument::RemoveElement(nsIContent* aParent, nsIContent* aChild)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
||||
void
|
||||
nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID,
|
||||
nsIElementFactory** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoString nameSpace;
|
||||
gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace);
|
||||
// Retrieve the appropriate factory.
|
||||
gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult);
|
||||
|
||||
nsCAutoString contractID(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX);
|
||||
contractID.AppendWithConversion(nameSpace);
|
||||
|
||||
// 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);
|
||||
if (!*aResult) {
|
||||
// Nothing found. Use generic XML element.
|
||||
*aResult = gXMLElementFactory;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -1634,21 +1634,12 @@ nsXULContentBuilder::SetContainerAttrs(nsIContent *aElement, const nsTemplateMat
|
|||
void
|
||||
nsXULContentBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoString nameSpace;
|
||||
gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace);
|
||||
gNameSpaceManager->GetElementFactory(aNameSpaceID, aResult);
|
||||
|
||||
nsCAutoString contractID(NS_ELEMENT_FACTORY_CONTRACTID_PREFIX);
|
||||
contractID.AppendWithConversion(nameSpace.get());
|
||||
|
||||
// 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);
|
||||
if (!*aResult) {
|
||||
*aResult = gXMLElementFactory; // Nothing found. Use generic XML element.
|
||||
NS_IF_ADDREF(*aResult);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
#include "nsIBindingManager.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIElementFactory.h"
|
||||
#include "nsINameSpace.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче