Fixing bug 98828. Cache a few nsSpaceManager objects to avoid spending 43%cvs ci -m ! of the time spent in PresShell::ProcessReflowCommand() in new and delete. r=dbaron@fas.harvard.edu, sr=waterson@netscape.com

This commit is contained in:
jst%netscape.com 2001-09-11 00:55:05 +00:00
parent 02ea02d8ee
commit 31c9d83acb
13 changed files with 200 additions and 20 deletions

View File

@ -35,6 +35,10 @@
/////////////////////////////////////////////////////////////////////////////
// BandList
PRInt32 nsSpaceManager::sCachedSpaceManagerCount = 0;
nsSpaceManager *
nsSpaceManager::sCachedSpaceManagers[NS_SPACE_MANAGER_CACHE_SIZE];
#define NSCOORD_MIN (-2147483647 - 1) /* minimum signed value */
nsSpaceManager::BandList::BandList()
@ -88,7 +92,86 @@ nsSpaceManager::~nsSpaceManager()
ClearFrameInfo();
}
NS_IMPL_ISUPPORTS1(nsSpaceManager, nsISpaceManager)
NS_INTERFACE_MAP_BEGIN(nsSpaceManager)
NS_INTERFACE_MAP_ENTRY(nsISpaceManager)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsSpaceManager)
NS_IMPL_RELEASE_WITH_DESTROY(nsSpaceManager, LastRelease())
// static
nsSpaceManager *nsSpaceManager::Create(nsIFrame* aFrame)
{
if (sCachedSpaceManagerCount > 0) {
// We have cached unused instances of this class, return a cached
// instance in stead of always creating a new one.
nsSpaceManager *spaceManager =
sCachedSpaceManagers[--sCachedSpaceManagerCount];
// Re-initialize the cached space manager by calling its
// constructor (using placement new), the destructor was called
// when the space manager was put in the cache.
return new (spaceManager) nsSpaceManager(aFrame);
}
// The cache is empty, this means we haveto create a new instance.
return new nsSpaceManager(aFrame);
}
// static
void nsSpaceManager::Shutdown()
{
// The layout module is being shut down, clean up the cache and
// disable further caching.
PRInt32 i;
for (i = 0; i < sCachedSpaceManagerCount; i++) {
// The destructor for the cached space managers has already been
// called (when the space manager was put in the cache) so we cast
// spaceManager to char * when calling delete to prevent the
// destructor from being called again.
nsSpaceManager *spaceManager = sCachedSpaceManagers[i];
delete (char *)spaceManager;
}
// Disable futher caching.
sCachedSpaceManagerCount = -1;
}
void
nsSpaceManager::LastRelease()
{
// This space manager is no longer used, if there's still room in
// the cache we'll cache this space manager, unless the layout
// module was already shut down.
if (sCachedSpaceManagerCount < NS_SPACE_MANAGER_CACHE_SIZE &&
sCachedSpaceManagerCount >= 0) {
// There's still space in the cache for more instances, put this
// instance in the cache in stead of deleting it.
sCachedSpaceManagers[sCachedSpaceManagerCount++] = this;
// Call the destructor so that the proper cleanup happens
this->~nsSpaceManager();
return;
}
// The cache is full, or the layout module has been shut down,
// delete this space manager.
delete this;
}
NS_IMETHODIMP
nsSpaceManager::GetFrame(nsIFrame*& aFrame) const

View File

@ -25,13 +25,16 @@
#include "nsISpaceManager.h"
#include "prclist.h"
#define NS_SPACE_MANAGER_CACHE_SIZE 4
/**
* Implementation of nsISpaceManager that maintains a region data structure of
* unavailable space
*/
class nsSpaceManager : public nsISpaceManager {
public:
nsSpaceManager(nsIFrame* aFrame);
static nsSpaceManager *Create(nsIFrame* aFrame);
static void Shutdown();
// nsISupports
NS_DECL_ISUPPORTS
@ -64,6 +67,8 @@ public:
#endif
protected:
nsSpaceManager(nsIFrame* aFrame);
// Structure that maintains information about the region associated
// with a particular frame
struct FrameInfo {
@ -169,8 +174,13 @@ protected:
nsBandData& aAvailableSpace) const;
private:
nsSpaceManager(const nsSpaceManager&); // no implementation
void operator=(const nsSpaceManager&); // no implementation
static PRInt32 sCachedSpaceManagerCount;
static nsSpaceManager *sCachedSpaceManagers[NS_SPACE_MANAGER_CACHE_SIZE];
void LastRelease();
nsSpaceManager(const nsSpaceManager&); // no implementation
void operator=(const nsSpaceManager&); // no implementation
};
#endif /* nsSpaceManager_h___ */

View File

@ -44,6 +44,7 @@
#include "nsCSSAtoms.h" // to addref/release table
#include "nsColorNames.h" // to addref/release table
#include "nsCSSFrameConstructor.h"
#include "nsSpaceManager.h"
#ifdef INCLUDE_XUL
#include "nsXULAtoms.h"
@ -146,6 +147,8 @@ Shutdown(nsIModule* self)
nsCSSFrameConstructor::ReleaseGlobals();
nsTextTransformer::Shutdown();
nsSpaceManager::Shutdown();
}
#ifdef NS_DEBUG

View File

@ -26,7 +26,6 @@
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIViewManager.h"
#include "nsSpaceManager.h"
#include "nsHTMLAtoms.h"
#include "nsIView.h"
#include "nsHTMLIIDs.h"
@ -36,7 +35,6 @@
#include "nsISizeOfHandler.h"
#undef NOISY_MAX_ELEMENT_SIZE
#undef NOISY_SPACEMANAGER
#undef NOISY_FINAL_SIZE
nsresult

View File

@ -26,8 +26,6 @@
#include "nsVoidArray.h"
#include "nsAbsoluteContainingBlock.h"
class nsSpaceManager;
struct nsStyleDisplay;
struct nsStylePosition;

View File

@ -674,7 +674,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// only when there are actually floats to manage. Otherwise things
// like tables will gain significant bloat.
if (NS_BLOCK_SPACE_MGR & mState) {
nsSpaceManager* rawPtr = new nsSpaceManager(this);
nsSpaceManager* rawPtr = nsSpaceManager::Create(this);
if (!rawPtr) {
return NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -35,6 +35,10 @@
/////////////////////////////////////////////////////////////////////////////
// BandList
PRInt32 nsSpaceManager::sCachedSpaceManagerCount = 0;
nsSpaceManager *
nsSpaceManager::sCachedSpaceManagers[NS_SPACE_MANAGER_CACHE_SIZE];
#define NSCOORD_MIN (-2147483647 - 1) /* minimum signed value */
nsSpaceManager::BandList::BandList()
@ -88,7 +92,86 @@ nsSpaceManager::~nsSpaceManager()
ClearFrameInfo();
}
NS_IMPL_ISUPPORTS1(nsSpaceManager, nsISpaceManager)
NS_INTERFACE_MAP_BEGIN(nsSpaceManager)
NS_INTERFACE_MAP_ENTRY(nsISpaceManager)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsSpaceManager)
NS_IMPL_RELEASE_WITH_DESTROY(nsSpaceManager, LastRelease())
// static
nsSpaceManager *nsSpaceManager::Create(nsIFrame* aFrame)
{
if (sCachedSpaceManagerCount > 0) {
// We have cached unused instances of this class, return a cached
// instance in stead of always creating a new one.
nsSpaceManager *spaceManager =
sCachedSpaceManagers[--sCachedSpaceManagerCount];
// Re-initialize the cached space manager by calling its
// constructor (using placement new), the destructor was called
// when the space manager was put in the cache.
return new (spaceManager) nsSpaceManager(aFrame);
}
// The cache is empty, this means we haveto create a new instance.
return new nsSpaceManager(aFrame);
}
// static
void nsSpaceManager::Shutdown()
{
// The layout module is being shut down, clean up the cache and
// disable further caching.
PRInt32 i;
for (i = 0; i < sCachedSpaceManagerCount; i++) {
// The destructor for the cached space managers has already been
// called (when the space manager was put in the cache) so we cast
// spaceManager to char * when calling delete to prevent the
// destructor from being called again.
nsSpaceManager *spaceManager = sCachedSpaceManagers[i];
delete (char *)spaceManager;
}
// Disable futher caching.
sCachedSpaceManagerCount = -1;
}
void
nsSpaceManager::LastRelease()
{
// This space manager is no longer used, if there's still room in
// the cache we'll cache this space manager, unless the layout
// module was already shut down.
if (sCachedSpaceManagerCount < NS_SPACE_MANAGER_CACHE_SIZE &&
sCachedSpaceManagerCount >= 0) {
// There's still space in the cache for more instances, put this
// instance in the cache in stead of deleting it.
sCachedSpaceManagers[sCachedSpaceManagerCount++] = this;
// Call the destructor so that the proper cleanup happens
this->~nsSpaceManager();
return;
}
// The cache is full, or the layout module has been shut down,
// delete this space manager.
delete this;
}
NS_IMETHODIMP
nsSpaceManager::GetFrame(nsIFrame*& aFrame) const

View File

@ -25,13 +25,16 @@
#include "nsISpaceManager.h"
#include "prclist.h"
#define NS_SPACE_MANAGER_CACHE_SIZE 4
/**
* Implementation of nsISpaceManager that maintains a region data structure of
* unavailable space
*/
class nsSpaceManager : public nsISpaceManager {
public:
nsSpaceManager(nsIFrame* aFrame);
static nsSpaceManager *Create(nsIFrame* aFrame);
static void Shutdown();
// nsISupports
NS_DECL_ISUPPORTS
@ -64,6 +67,8 @@ public:
#endif
protected:
nsSpaceManager(nsIFrame* aFrame);
// Structure that maintains information about the region associated
// with a particular frame
struct FrameInfo {
@ -169,8 +174,13 @@ protected:
nsBandData& aAvailableSpace) const;
private:
nsSpaceManager(const nsSpaceManager&); // no implementation
void operator=(const nsSpaceManager&); // no implementation
static PRInt32 sCachedSpaceManagerCount;
static nsSpaceManager *sCachedSpaceManagers[NS_SPACE_MANAGER_CACHE_SIZE];
void LastRelease();
nsSpaceManager(const nsSpaceManager&); // no implementation
void operator=(const nsSpaceManager&); // no implementation
};
#endif /* nsSpaceManager_h___ */

View File

@ -26,7 +26,6 @@
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIViewManager.h"
#include "nsSpaceManager.h"
#include "nsHTMLAtoms.h"
#include "nsIView.h"
#include "nsHTMLIIDs.h"
@ -36,7 +35,6 @@
#include "nsISizeOfHandler.h"
#undef NOISY_MAX_ELEMENT_SIZE
#undef NOISY_SPACEMANAGER
#undef NOISY_FINAL_SIZE
nsresult

View File

@ -26,8 +26,6 @@
#include "nsVoidArray.h"
#include "nsAbsoluteContainingBlock.h"
class nsSpaceManager;
struct nsStyleDisplay;
struct nsStylePosition;

View File

@ -674,7 +674,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// only when there are actually floats to manage. Otherwise things
// like tables will gain significant bloat.
if (NS_BLOCK_SPACE_MGR & mState) {
nsSpaceManager* rawPtr = new nsSpaceManager(this);
nsSpaceManager* rawPtr = nsSpaceManager::Create(this);
if (!rawPtr) {
return NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -609,7 +609,7 @@ nsBoxToBlockAdaptor::Reflow(nsBoxLayoutState& aState,
// printf("In debug\n");
if (mSpaceManager == nsnull) {
mSpaceManager = new nsSpaceManager(mFrame);
mSpaceManager = nsSpaceManager::Create(mFrame);
NS_ADDREF(mSpaceManager);
}

View File

@ -53,7 +53,6 @@
#include "nsXULAtoms.h"
#include "nsIReflowCommand.h"
#include "nsIContent.h"
#include "nsSpaceManager.h"
#include "nsHTMLParts.h"
#include "nsIViewManager.h"
#include "nsIView.h"