add CurrentItemInPlaceUTF8 to reduce startup alloc by 2.3M(!), r=brendan

This commit is contained in:
shaver%mozilla.org 2000-04-25 01:11:08 +00:00
parent a12d17bca9
commit 1e9b5eec44
5 changed files with 105 additions and 62 deletions

View File

@ -82,6 +82,13 @@ interface nsIRegistry : nsISupports
void pack();
};
[scriptable, uuid(8cecf236-1dd2-11b2-893c-f9848956eaec)]
interface nsIRegistryEnumerator : nsIEnumerator
{
void currentItemInPlaceUTF8(out nsRegistryKey key,
[shared, retval] out string item);
};
[scriptable, uuid(D1B54831-AC07-11d2-805E-00600811A9C3)]
interface nsIRegistryNode : nsISupports
{

View File

@ -103,13 +103,16 @@ struct nsRegistryFactory : public nsIFactory {
| This class implements the nsIEnumerator interface and is used to implement |
| the nsRegistry EnumerateSubtrees and EnumerateAllSubtrees functions. |
------------------------------------------------------------------------------*/
struct nsRegSubtreeEnumerator : public nsIEnumerator {
struct nsRegSubtreeEnumerator : public nsIRegistryEnumerator {
// This class implements the nsISupports interface functions.
NS_DECL_ISUPPORTS
// This class implements the nsIEnumerator interface functions.
NS_DECL_NSIENUMERATOR
// And our magic behind-the-back fast-path thing.
NS_DECL_NSIREGISTRYENUMERATOR
// ctor/dtor
nsRegSubtreeEnumerator( HREG hReg, RKEY rKey, PRBool all );
virtual ~nsRegSubtreeEnumerator();
@ -322,7 +325,8 @@ static void reginfo2Length( const REGINFO &in, PRUint32 &out ) {
| for each class implemented in this file. |
------------------------------------------------------------------------------*/
NS_IMPL_ISUPPORTS1( nsRegistry, nsIRegistry )
NS_IMPL_ISUPPORTS1( nsRegSubtreeEnumerator, nsIEnumerator )
NS_IMPL_ISUPPORTS2( nsRegSubtreeEnumerator, nsIEnumerator,
nsIRegistryEnumerator)
NS_IMPL_ISUPPORTS1( nsRegistryNode, nsIRegistryNode )
NS_IMPL_ISUPPORTS1( nsRegistryValue, nsIRegistryValue )
@ -1303,6 +1307,20 @@ nsRegSubtreeEnumerator::CurrentItem( nsISupports **result) {
return rv;
}
/*--------------nsRegSubtreeEnumerator::CurrentItemInPlaceUTF8-----------------
| An ugly name for an ugly function. Hands back a shared pointer to the |
| name (encoded as UTF-8), and the subkey identifier. |
-----------------------------------------------------------------------------*/
NS_IMETHODIMP
nsRegSubtreeEnumerator::CurrentItemInPlaceUTF8( nsRegistryKey *childKey ,
const char **name )
{
*childKey = mNext;
/* [shared] */
*name = mName;
return NS_OK;
}
/*---------------------- nsRegSubtreeEnumerator::IsDone ------------------------
| Simply return mDone. |
------------------------------------------------------------------------------*/

View File

@ -771,32 +771,30 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
rv = mRegistry->EnumerateSubtrees( mCLSIDKey, getter_AddRefs(cidEnum));
if (NS_FAILED(rv)) return rv;
rv = cidEnum->First();
for (; NS_SUCCEEDED(rv) && (cidEnum->IsDone() != NS_OK); (rv = cidEnum->Next()))
nsCOMPtr<nsIRegistryEnumerator> regEnum = do_QueryInterface(cidEnum, &rv);
if (NS_FAILED(rv)) return rv;
rv = regEnum->First();
for (rv = regEnum->First();
NS_SUCCEEDED(rv) && (regEnum->IsDone() != NS_OK);
rv = regEnum->Next())
{
nsCOMPtr<nsISupports> base;
rv = cidEnum->CurrentItem(getter_AddRefs(base));
if (NS_FAILED(rv)) continue;
// Get specific interface.
nsCOMPtr<nsIRegistryNode> node;
node = do_QueryInterface(base);
if (!node) continue;
// Get library name
nsXPIDLCString cidString;
rv = node->GetNameUTF8(getter_Copies(cidString));
if (NS_FAILED(rv)) continue;
// Get key associated with library
const char *cidString;
nsRegistryKey cidKey;
rv = node->GetKey(&cidKey);
if (NS_FAILED(rv)) continue;
/*
* CurrentItemInPlaceUTF8 will give us back a _shared_ pointer in
* cidString. This is bad XPCOM practice. It is evil, and requires
* great care with the relative lifetimes of cidString and regEnum.
*
* It is also faster, and less painful in the allocation department.
*/
rv = regEnum->CurrentItemInPlaceUTF8(&cidKey, &cidString);
if (NS_FAILED(rv)) continue;
// Create the CID entry
nsXPIDLCString library;
rv = mRegistry->GetStringUTF8(cidKey, inprocServerValueName,
getter_Copies(library));
getter_Copies(library));
if (NS_FAILED(rv)) continue;
nsCID aClass;
@ -824,32 +822,29 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
rv = mRegistry->EnumerateSubtrees( mClassesKey, getter_AddRefs(progidEnum));
if (NS_FAILED(rv)) return rv;
rv = progidEnum->First();
for (; NS_SUCCEEDED(rv) && (progidEnum->IsDone() != NS_OK); (rv = progidEnum->Next()))
regEnum = do_QueryInterface(progidEnum, &rv);
if (NS_FAILED(rv)) return rv;
rv = regEnum->First();
for (rv = regEnum->First();
NS_SUCCEEDED(rv) && (regEnum->IsDone() != NS_OK);
rv = regEnum->Next())
{
nsCOMPtr<nsISupports> base;
rv = progidEnum->CurrentItem(getter_AddRefs(base));
if (NS_FAILED(rv)) continue;
// Get specific interface.
nsIID nodeIID = NS_IREGISTRYNODE_IID;
nsCOMPtr<nsIRegistryNode> node;
rv = base->QueryInterface(nodeIID, getter_AddRefs(node));
if (NS_FAILED(rv)) continue;
// Get the progid string
nsXPIDLCString progidString;
rv = node->GetNameUTF8(getter_Copies(progidString));
if (NS_FAILED(rv)) continue;
// Get cid string
const char *progidString;
nsRegistryKey progidKey;
rv = node->GetKey(&progidKey);
/*
* CurrentItemInPlaceUTF8 will give us back a _shared_ pointer in
* progidString. This is bad XPCOM practice. It is evil, and requires
* great care with the relative lifetimes of progidString and regEnum.
*
* It is also faster, and less painful in the allocation department.
*/
rv = regEnum->CurrentItemInPlaceUTF8(&progidKey, &progidString);
if (NS_FAILED(rv)) continue;
nsXPIDLCString cidString;
rv = mRegistry->GetStringUTF8(progidKey, classIDValueName,
getter_Copies(cidString));
getter_Copies(cidString));
if (NS_FAILED(rv)) continue;
nsCID *aClass = new nsCID();
@ -1953,29 +1948,27 @@ nsComponentManagerImpl::AutoRegister(PRInt32 when, nsIFile *inDirSpec)
if (NS_FAILED(rv))
return rv;
rv = loaderEnum->First();
nsCOMPtr<nsIRegistryEnumerator> regEnum =
do_QueryInterface(loaderEnum, &rv);
if (NS_FAILED(rv))
return rv;
for (; NS_SUCCEEDED(rv) && (loaderEnum->IsDone() != NS_OK);
(rv = loaderEnum->Next())) {
nsCOMPtr<nsISupports> base;
rv = loaderEnum->CurrentItem(getter_AddRefs(base));
if (NS_FAILED(rv))
return rv;
// Narrow
nsCOMPtr<nsIRegistryNode> node;
node = do_QueryInterface(base, &rv);
if (NS_FAILED(rv))
continue;
nsXPIDLCString type;
rv = node->GetNameUTF8(getter_Copies(type));
for (rv = regEnum->First();
NS_SUCCEEDED(rv) && (regEnum->IsDone() != NS_OK);
rv = regEnum->Next()) {
const char * type;
nsRegistryKey throwAway;
/*
* CurrentItemInPlaceUTF8 will give us back a _shared_ pointer in
* type. This is bad XPCOM practice. It is evil, and requires
* great care with the relative lifetimes of type and regEnum.
*
* It is also faster, and less painful in the allocation department.
*/
rv = regEnum->CurrentItemInPlaceUTF8(&throwAway, &type);
if (NS_FAILED(rv))
continue;
nsStringKey typeKey(type);
nsCOMPtr<nsIComponentLoader> loader;
/* this will create it if we haven't already */
GetLoaderForType(type, getter_AddRefs(loader));

View File

@ -82,6 +82,13 @@ interface nsIRegistry : nsISupports
void pack();
};
[scriptable, uuid(8cecf236-1dd2-11b2-893c-f9848956eaec)]
interface nsIRegistryEnumerator : nsIEnumerator
{
void currentItemInPlaceUTF8(out nsRegistryKey key,
[shared, retval] out string item);
};
[scriptable, uuid(D1B54831-AC07-11d2-805E-00600811A9C3)]
interface nsIRegistryNode : nsISupports
{

View File

@ -103,13 +103,16 @@ struct nsRegistryFactory : public nsIFactory {
| This class implements the nsIEnumerator interface and is used to implement |
| the nsRegistry EnumerateSubtrees and EnumerateAllSubtrees functions. |
------------------------------------------------------------------------------*/
struct nsRegSubtreeEnumerator : public nsIEnumerator {
struct nsRegSubtreeEnumerator : public nsIRegistryEnumerator {
// This class implements the nsISupports interface functions.
NS_DECL_ISUPPORTS
// This class implements the nsIEnumerator interface functions.
NS_DECL_NSIENUMERATOR
// And our magic behind-the-back fast-path thing.
NS_DECL_NSIREGISTRYENUMERATOR
// ctor/dtor
nsRegSubtreeEnumerator( HREG hReg, RKEY rKey, PRBool all );
virtual ~nsRegSubtreeEnumerator();
@ -322,7 +325,8 @@ static void reginfo2Length( const REGINFO &in, PRUint32 &out ) {
| for each class implemented in this file. |
------------------------------------------------------------------------------*/
NS_IMPL_ISUPPORTS1( nsRegistry, nsIRegistry )
NS_IMPL_ISUPPORTS1( nsRegSubtreeEnumerator, nsIEnumerator )
NS_IMPL_ISUPPORTS2( nsRegSubtreeEnumerator, nsIEnumerator,
nsIRegistryEnumerator)
NS_IMPL_ISUPPORTS1( nsRegistryNode, nsIRegistryNode )
NS_IMPL_ISUPPORTS1( nsRegistryValue, nsIRegistryValue )
@ -1303,6 +1307,20 @@ nsRegSubtreeEnumerator::CurrentItem( nsISupports **result) {
return rv;
}
/*--------------nsRegSubtreeEnumerator::CurrentItemInPlaceUTF8-----------------
| An ugly name for an ugly function. Hands back a shared pointer to the |
| name (encoded as UTF-8), and the subkey identifier. |
-----------------------------------------------------------------------------*/
NS_IMETHODIMP
nsRegSubtreeEnumerator::CurrentItemInPlaceUTF8( nsRegistryKey *childKey ,
const char **name )
{
*childKey = mNext;
/* [shared] */
*name = mName;
return NS_OK;
}
/*---------------------- nsRegSubtreeEnumerator::IsDone ------------------------
| Simply return mDone. |
------------------------------------------------------------------------------*/