NS_DECL_THREADSAFE_ISUPPORTS NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback, nsISupports *aClosure) { typedef nsDOMMemoryFile::DataOwner DataOwner; StaticMutexAutoLock lock(DataOwner::sDataOwnerMutex); 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 = DOMMemoryFileDataOwnerMallocSizeOf(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 (size_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=%llu, sha1=%s)", owner->mLength, digestString.get()), KIND_HEAP, UNITS_BYTES, size, nsPrintfCString( "Memory used to back a memory file of length %llu bytes. 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"), KIND_HEAP, 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_DECL_THREADSAFE_ISUPPORTS NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) override { typedef BlobImplMemory::DataOwner DataOwner; StaticMutexAutoLock lock(DataOwner::sDataOwnerMutex); 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 = MemoryFileDataOwnerMallocSizeOf(owner->mData); if (size < LARGE_OBJECT_MIN_SIZE) { smallObjectsTotal += size; } else { SHA1Sum sha1; sha1.update(owner->mData, owner->mLength); uint8_t digest[SHA1Sum::kHashSize]; // SHA1 digests are 20 bytes long. sha1.finish(digest); nsAutoCString digestString; for (size_t i = 0; i < sizeof(digest); i++) { digestString.AppendPrintf("%02x", digest[i]); } aHandleReport->Callback( /* process */ NS_LITERAL_CSTRING(""), nsPrintfCString( "explicit/dom/memory-file-data/large/file(length=%llu, sha1=%s)", owner->mLength, aAnonymize ? "<anonymized>" : digestString.get()), KIND_HEAP, UNITS_BYTES, size, nsPrintfCString( "Memory used to back a memory file of length %llu bytes. 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()), aData); } } if (smallObjectsTotal > 0) { aHandleReport->Callback( /* process */ NS_LITERAL_CSTRING(""), NS_LITERAL_CSTRING("explicit/dom/memory-file-data/small"), KIND_HEAP, UNITS_BYTES, smallObjectsTotal, nsPrintfCString( "Memory used to back small memory files (i.e. those taking up less " "than %zu bytes of memory 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.", LARGE_OBJECT_MIN_SIZE), aData); } return NS_OK; }