From b5b0bf9fbeeddfe063292bc4299ebf752b0a56d9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Jan 2012 18:18:26 -0800 Subject: [PATCH] Bug 671299 (part 1) - Add ns{Void,COM}Array::SizeOfExcludingThis(). r=bz. --HG-- extra : rebase_source : 170c6943e985a8bafc4c441918a0e23fd52e15f2 --- xpcom/glue/nsCOMArray.h | 24 ++++++++++++++++ xpcom/glue/nsVoidArray.cpp | 56 +++++++++++++++++++++++++++++++++++--- xpcom/glue/nsVoidArray.h | 14 ++++++++++ 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/xpcom/glue/nsCOMArray.h b/xpcom/glue/nsCOMArray.h index 35941c3a3097..50300a95b67b 100644 --- a/xpcom/glue/nsCOMArray.h +++ b/xpcom/glue/nsCOMArray.h @@ -121,6 +121,16 @@ public: : true; } + // Measures the size of the array's element storage, and if + // |aSizeOfElement| is non-NULL, measures the size of things pointed to by + // elements. + size_t SizeOfExcludingThis( + nsVoidArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, + nsMallocSizeOfFun aMallocSizeOf, void* aData = NULL) const { + return mArray.SizeOfExcludingThis(aSizeOfElementIncludingThis, + aMallocSizeOf, aData); + } + private: // the actual storage @@ -276,6 +286,20 @@ class nsCOMArray : public nsCOMArray_base return nsCOMArray_base::RemoveObjectsAt(aIndex, aCount); } + // Each element in an nsCOMArray is actually a T*, so this function is + // "IncludingThis" rather than "ExcludingThis" because it needs to measure + // the memory taken by the T itself as well as anything it points to. + typedef size_t (* nsCOMArraySizeOfElementIncludingThisFunc) + (T* aElement, nsMallocSizeOfFun aMallocSizeOf, void *aData); + + size_t SizeOfExcludingThis( + nsCOMArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, + nsMallocSizeOfFun aMallocSizeOf, void *aData = NULL) const { + return nsCOMArray_base::SizeOfExcludingThis( + nsVoidArraySizeOfElementIncludingThisFunc(aSizeOfElementIncludingThis), + aMallocSizeOf, aData); + } + private: // don't implement these! diff --git a/xpcom/glue/nsVoidArray.cpp b/xpcom/glue/nsVoidArray.cpp index f8904edfb286..0ae56d1d2ec5 100644 --- a/xpcom/glue/nsVoidArray.cpp +++ b/xpcom/glue/nsVoidArray.cpp @@ -717,10 +717,22 @@ bool nsVoidArray::EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData) PRInt32 index = -1; bool running = true; - if (mImpl) - { - while (running && (++index < mImpl->mCount)) - { + if (mImpl) { + while (running && (++index < mImpl->mCount)) { + running = (*aFunc)(mImpl->mArray[index], aData); + } + } + return running; +} + +bool nsVoidArray::EnumerateForwards(nsVoidArrayEnumFuncConst aFunc, + void* aData) const +{ + PRInt32 index = -1; + bool running = true; + + if (mImpl) { + while (running && (++index < mImpl->mCount)) { running = (*aFunc)(mImpl->mArray[index], aData); } } @@ -742,6 +754,42 @@ bool nsVoidArray::EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData) return running; } +struct SizeOfElementIncludingThisData +{ + size_t mSize; + nsVoidArraySizeOfElementIncludingThisFunc mSizeOfElementIncludingThis; + nsMallocSizeOfFun mMallocSizeOf; + void *mData; // the arg passed by the user +}; + +static bool +SizeOfElementIncludingThisEnumerator(const void *aElement, void *aData) +{ + SizeOfElementIncludingThisData *d = (SizeOfElementIncludingThisData *)aData; + d->mSize += d->mSizeOfElementIncludingThis(aElement, d->mMallocSizeOf, d->mData); + return true; +} + +size_t +nsVoidArray::SizeOfExcludingThis( + nsVoidArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, + nsMallocSizeOfFun aMallocSizeOf, void* aData) const +{ + size_t n = 0; + // Measure the element storage. + if (mImpl) { + n += aMallocSizeOf(mImpl); + } + // Measure things pointed to by the elements. + if (aSizeOfElementIncludingThis) { + SizeOfElementIncludingThisData data2 = + { 0, aSizeOfElementIncludingThis, aMallocSizeOf, aData }; + EnumerateForwards(SizeOfElementIncludingThisEnumerator, &data2); + n += data2.mSize; + } + return n; +} + //---------------------------------------------------------------- // nsAutoVoidArray diff --git a/xpcom/glue/nsVoidArray.h b/xpcom/glue/nsVoidArray.h index 36cc9ba0f518..9d3415b00843 100644 --- a/xpcom/glue/nsVoidArray.h +++ b/xpcom/glue/nsVoidArray.h @@ -47,6 +47,12 @@ typedef int (* nsVoidArrayComparatorFunc) // Enumerator callback function. Return false to stop typedef bool (* nsVoidArrayEnumFunc)(void* aElement, void *aData); +typedef bool (* nsVoidArrayEnumFuncConst)(const void* aElement, void *aData); + +// SizeOfExcludingThis callback function. +typedef size_t (* nsVoidArraySizeOfElementIncludingThisFunc)(const void* aElement, + nsMallocSizeOfFun aMallocSizeOf, + void *aData); /// A basic zero-based array of void*'s that manages its own memory class NS_COM_GLUE nsVoidArray { @@ -127,8 +133,16 @@ public: void Sort(nsVoidArrayComparatorFunc aFunc, void* aData); bool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData); + bool EnumerateForwards(nsVoidArrayEnumFuncConst aFunc, void* aData) const; bool EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData); + // Measures the size of the array's element storage, and if + // |aSizeOfElementIncludingThis| is non-NULL, measures the size of things + // pointed to by elements. + size_t SizeOfExcludingThis( + nsVoidArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, + nsMallocSizeOfFun aMallocSizeOf, void* aData = NULL) const; + protected: bool GrowArrayBy(PRInt32 aGrowBy);