Bug 712835 (part 2 of 3) - Add a memory reporter for the nsAtomTable. r=khuey.

--HG--
extra : rebase_source : 3c934649d072e0d519c905cb8baf49b12bce0312
This commit is contained in:
Nicholas Nethercote 2011-12-22 17:24:43 -08:00
parent e134d1c73e
commit f6824360d3
4 changed files with 75 additions and 12 deletions

View File

@ -171,4 +171,7 @@ ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
endif
LOCAL_INCLUDES += -I$(srcdir)/../build
LOCAL_INCLUDES += \
-I$(srcdir)/../build \
-I$(topsrcdir)/xpcom/ds \
$(NULL)

View File

@ -37,6 +37,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsAtomTable.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
@ -496,6 +497,24 @@ NS_MEMORY_REPORTER_IMPLEMENT(HeapAllocated,
"application because the allocator regularly rounds up request sizes. (The "
"exact amount requested is not recorded.)")
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(AtomTableMallocSizeOf, "atom-table")
static PRInt64 GetAtomTableSize() {
return NS_SizeOfAtomTableIncludingThis(AtomTableMallocSizeOf);
}
// Why is this here? At first glance, you'd think it could be defined and
// registered with nsMemoryReporterManager entirely within nsAtomTable.cpp.
// However, the obvious time to register it is when the table is initialized,
// and that happens before XPCOM components are initialized, which means the
// NS_RegisterMemoryReporter call fails. So instead we do it here.
NS_MEMORY_REPORTER_IMPLEMENT(AtomTable,
"explicit/atom-table",
KIND_HEAP,
UNITS_BYTES,
GetAtomTableSize,
"Memory used by the atoms table.")
/**
** nsMemoryReporterManager implementation
**/
@ -538,6 +557,8 @@ nsMemoryReporterManager::Init()
REGISTER(HeapZone0Used);
#endif
REGISTER(AtomTable);
return NS_OK;
}

View File

@ -369,21 +369,58 @@ AtomImpl::IsStaticAtom()
return IsPermanent();
}
size_t
AtomImpl::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
{
return aMallocSizeOf(this, sizeof(AtomImpl)) +
nsStringBuffer::FromData(mString)->
SizeOfIncludingThisIfUnshared(aMallocSizeOf);
}
//----------------------------------------------------------------------
static size_t
SizeOfAtomTableEntryExcludingThis(PLDHashEntryHdr *aHdr,
nsMallocSizeOfFun aMallocSizeOf,
void *aArg)
{
AtomTableEntry* entry = static_cast<AtomTableEntry*>(aHdr);
return entry->mAtom->SizeOfIncludingThis(aMallocSizeOf);
}
size_t NS_SizeOfAtomTableIncludingThis(nsMallocSizeOfFun aMallocSizeOf) {
if (gAtomTable.ops) {
return PL_DHashTableSizeOfExcludingThis(&gAtomTable,
SizeOfAtomTableEntryExcludingThis,
aMallocSizeOf);
}
return 0;
}
#define ATOM_HASHTABLE_INITIAL_SIZE 4096
static inline bool
EnsureTableExists()
{
if (gAtomTable.ops) {
return true;
}
if (PL_DHashTableInit(&gAtomTable, &AtomTableOps, 0,
sizeof(AtomTableEntry), ATOM_HASHTABLE_INITIAL_SIZE)) {
return true;
}
// Initialization failed.
gAtomTable.ops = nsnull;
return false;
}
static inline AtomTableEntry*
GetAtomHashEntry(const char* aString, PRUint32 aLength)
{
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
if (!gAtomTable.ops &&
!PL_DHashTableInit(&gAtomTable, &AtomTableOps, 0,
sizeof(AtomTableEntry), ATOM_HASHTABLE_INITIAL_SIZE)) {
gAtomTable.ops = nsnull;
if (!EnsureTableExists()) {
return nsnull;
}
AtomTableKey key(aString, aLength);
return static_cast<AtomTableEntry*>
(PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD));
@ -393,13 +430,9 @@ static inline AtomTableEntry*
GetAtomHashEntry(const PRUnichar* aString, PRUint32 aLength)
{
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
if (!gAtomTable.ops &&
!PL_DHashTableInit(&gAtomTable, &AtomTableOps, 0,
sizeof(AtomTableEntry), ATOM_HASHTABLE_INITIAL_SIZE)) {
gAtomTable.ops = nsnull;
if (!EnsureTableExists()) {
return nsnull;
}
AtomTableKey key(aString, aLength);
return static_cast<AtomTableEntry*>
(PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD));

View File

@ -85,6 +85,8 @@ public:
// for |#ifdef NS_BUILD_REFCNT_LOGGING| access to reference count
nsrefcnt GetRefCount() { return mRefCnt; }
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
};
/**
@ -108,14 +110,18 @@ public:
virtual bool IsPermanent();
// SizeOfIncludingThis() isn't needed -- the one inherited from AtomImpl is
// good enough, because PermanentAtomImpl doesn't add any new data members.
void* operator new(size_t size, AtomImpl* aAtom) CPP_THROW_NEW;
void* operator new(size_t size) CPP_THROW_NEW
{
return ::operator new(size);
}
};
void NS_PurgeAtomTable();
size_t NS_SizeOfAtomTableIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
#endif // nsAtomTable_h__