зеркало из https://github.com/mozilla/gecko-dev.git
Bug 803684 - Add a memory reporter for in-memory file data. r=khuey,njn a=blocking-basecamp
This commit is contained in:
Родитель
cdfe32de9a
Коммит
6d135ea5fe
|
@ -21,7 +21,9 @@
|
|||
#include "nsAutoPtr.h"
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
||||
#include "mozilla/dom/indexedDB/FileManager.h"
|
||||
|
@ -360,7 +362,7 @@ public:
|
|||
const nsAString& aName,
|
||||
const nsAString& aContentType)
|
||||
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
|
||||
mDataOwner(new DataOwner(aMemoryBuffer))
|
||||
mDataOwner(new DataOwner(aMemoryBuffer, aLength))
|
||||
{
|
||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||
}
|
||||
|
@ -370,7 +372,7 @@ public:
|
|||
uint64_t aLength,
|
||||
const nsAString& aContentType)
|
||||
: nsDOMFile(aContentType, aLength),
|
||||
mDataOwner(new DataOwner(aMemoryBuffer))
|
||||
mDataOwner(new DataOwner(aMemoryBuffer, aLength))
|
||||
{
|
||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||
}
|
||||
|
@ -391,18 +393,40 @@ protected:
|
|||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType);
|
||||
|
||||
friend class DataOwnerAdapter; // Needs to see DataOwner
|
||||
class DataOwner {
|
||||
// These classes need to see DataOwner.
|
||||
friend class DataOwnerAdapter;
|
||||
friend class nsDOMMemoryFileDataOwnerMemoryReporter;
|
||||
|
||||
class DataOwner : public mozilla::LinkedListElement<DataOwner> {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataOwner)
|
||||
DataOwner(void* aMemoryBuffer)
|
||||
DataOwner(void* aMemoryBuffer, uint64_t aLength)
|
||||
: mData(aMemoryBuffer)
|
||||
, mLength(aLength)
|
||||
{
|
||||
if (!sDataOwners) {
|
||||
sDataOwners = new mozilla::LinkedList<DataOwner>();
|
||||
EnsureMemoryReporterRegistered();
|
||||
}
|
||||
sDataOwners->insertBack(this);
|
||||
}
|
||||
|
||||
~DataOwner() {
|
||||
remove();
|
||||
if (sDataOwners->isEmpty()) {
|
||||
// Free the linked list if it's empty.
|
||||
sDataOwners = nullptr;
|
||||
}
|
||||
|
||||
PR_Free(mData);
|
||||
}
|
||||
|
||||
static void EnsureMemoryReporterRegistered();
|
||||
|
||||
static bool sMemoryReporterRegistered;
|
||||
static mozilla::StaticAutoPtr<mozilla::LinkedList<DataOwner> > sDataOwners;
|
||||
void* mData;
|
||||
uint64_t mLength;
|
||||
};
|
||||
|
||||
// Used when backed by a memory store
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "nsIFileStreams.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsISeekableStream.h"
|
||||
|
@ -29,6 +30,8 @@
|
|||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/SHA1.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
@ -686,6 +689,121 @@ nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
|
|||
return DataOwnerAdapter::Create(mDataOwner, mStart, mLength, aStream);
|
||||
}
|
||||
|
||||
/* static */ StaticAutoPtr<LinkedList<nsDOMMemoryFile::DataOwner> >
|
||||
nsDOMMemoryFile::DataOwner::sDataOwners;
|
||||
|
||||
/* static */ bool
|
||||
nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerSizeOf,
|
||||
"memory-file-data");
|
||||
|
||||
class nsDOMMemoryFileDataOwnerMemoryReporter
|
||||
: public nsIMemoryMultiReporter
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignASCII("dom-memory-file-data-owner");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetExplicitNonHeap(int64_t *aResult)
|
||||
{
|
||||
// All of this reporter's memory is on the heap.
|
||||
*aResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCallback,
|
||||
nsISupports *aClosure)
|
||||
{
|
||||
typedef nsDOMMemoryFile::DataOwner DataOwner;
|
||||
|
||||
if (!DataOwner::sDataOwners) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const size_t LARGE_OBJECT_MIN_SIZE = 8 * 1024;
|
||||
size_t smallObjectsTotal = 0;
|
||||
|
||||
for (DataOwner *owner = DataOwner::sDataOwners->getFirst();
|
||||
owner; owner = owner->getNext()) {
|
||||
|
||||
size_t size = DOMMemoryFileDataOwnerSizeOf(owner->mData);
|
||||
|
||||
if (size < LARGE_OBJECT_MIN_SIZE) {
|
||||
smallObjectsTotal += size;
|
||||
}
|
||||
else {
|
||||
SHA1Sum sha1;
|
||||
sha1.update(owner->mData, owner->mLength);
|
||||
uint8_t digest[SHA1Sum::HashSize]; // SHA1 digests are 20 bytes long.
|
||||
sha1.finish(digest);
|
||||
|
||||
nsAutoCString digestString;
|
||||
for (uint8_t i = 0; i < sizeof(digest); i++) {
|
||||
digestString.AppendPrintf("%02x", digest[i]);
|
||||
}
|
||||
|
||||
nsresult rv = aCallback->Callback(
|
||||
/* process */ NS_LITERAL_CSTRING(""),
|
||||
nsPrintfCString(
|
||||
"explicit/dom/memory-file-data/large/file(length=%d, sha1=%s)",
|
||||
owner->mLength, digestString.get()),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
nsIMemoryReporter::UNITS_BYTES,
|
||||
size,
|
||||
nsPrintfCString(
|
||||
"Memory used to back a memory file of length %d. The file has a "
|
||||
"sha1 of %s.\n\n"
|
||||
"Note that the allocator may round up a memory file's length -- "
|
||||
"that is, an N-byte memory file may take up more than N bytes of "
|
||||
"memory.",
|
||||
owner->mLength, digestString.get()),
|
||||
aClosure);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
if (smallObjectsTotal > 0) {
|
||||
nsresult rv = aCallback->Callback(
|
||||
/* process */ NS_LITERAL_CSTRING(""),
|
||||
NS_LITERAL_CSTRING("explicit/dom/memory-file-data/small"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
nsIMemoryReporter::UNITS_BYTES,
|
||||
smallObjectsTotal,
|
||||
nsPrintfCString(
|
||||
"Memory used to back small memory files (less than %d bytes each).\n\n"
|
||||
"Note that the allocator may round up a memory file's length -- "
|
||||
"that is, an N-byte memory file may take up more than N bytes of "
|
||||
"memory."),
|
||||
aClosure);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter,
|
||||
nsIMemoryMultiReporter);
|
||||
|
||||
/* static */ void
|
||||
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
||||
{
|
||||
if (sMemoryReporterRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsDOMMemoryFileDataOwnerMemoryReporter> reporter = new
|
||||
nsDOMMemoryFileDataOwnerMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(reporter);
|
||||
|
||||
sMemoryReporterRegistered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsDOMFileList implementation
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче