mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 993546 - refactor malloc-wrapping memory reporter implementations; r=njn
This commit is contained in:
parent
e48ee4a3eb
commit
8886a78c1f
@ -48,63 +48,11 @@
|
||||
*/
|
||||
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "mozHunspellAllocator.h"
|
||||
|
||||
extern void HunspellReportMemoryAllocation(void*);
|
||||
extern void HunspellReportMemoryDeallocation(void*);
|
||||
|
||||
inline void* hunspell_malloc(size_t size)
|
||||
{
|
||||
void* result = moz_malloc(size);
|
||||
HunspellReportMemoryAllocation(result);
|
||||
return result;
|
||||
}
|
||||
#define malloc(size) hunspell_malloc(size)
|
||||
|
||||
inline void* hunspell_calloc(size_t count, size_t size)
|
||||
{
|
||||
void* result = moz_calloc(count, size);
|
||||
HunspellReportMemoryAllocation(result);
|
||||
return result;
|
||||
}
|
||||
#define calloc(count, size) hunspell_calloc(count, size)
|
||||
|
||||
inline void hunspell_free(void* ptr)
|
||||
{
|
||||
HunspellReportMemoryDeallocation(ptr);
|
||||
moz_free(ptr);
|
||||
}
|
||||
#define free(ptr) hunspell_free(ptr)
|
||||
|
||||
inline void* hunspell_realloc(void* ptr, size_t size)
|
||||
{
|
||||
HunspellReportMemoryDeallocation(ptr);
|
||||
void* result = moz_realloc(ptr, size);
|
||||
if (result) {
|
||||
HunspellReportMemoryAllocation(result);
|
||||
} else {
|
||||
// realloc failed; undo the HunspellReportMemoryDeallocation from above
|
||||
HunspellReportMemoryAllocation(ptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#define realloc(ptr, size) hunspell_realloc(ptr, size)
|
||||
|
||||
inline char* hunspell_strdup(const char* str)
|
||||
{
|
||||
char* result = moz_strdup(str);
|
||||
HunspellReportMemoryAllocation(result);
|
||||
return result;
|
||||
}
|
||||
#define strdup(str) hunspell_strdup(str)
|
||||
|
||||
#if defined(HAVE_STRNDUP)
|
||||
inline char* hunspell_strndup(const char* str, size_t size)
|
||||
{
|
||||
char* result = moz_strndup(str, size);
|
||||
HunspellReportMemoryAllocation(result);
|
||||
return result;
|
||||
}
|
||||
#define strndup(str, size) hunspell_strndup(str, size)
|
||||
#endif
|
||||
#define malloc(size) HunspellAllocator::CountingMalloc(size)
|
||||
#define calloc(count, size) HunspellAllocator::CountingCalloc(count, size)
|
||||
#define free(ptr) HunspellAllocator::CountingFree(ptr)
|
||||
#define realloc(ptr, size) HunspellAllocator::CountingRealloc(ptr, size)
|
||||
|
||||
#endif
|
||||
|
@ -96,22 +96,14 @@ NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
|
||||
mEncoder,
|
||||
mDecoder)
|
||||
|
||||
int64_t mozHunspell::sAmount = 0;
|
||||
|
||||
// WARNING: hunspell_alloc_hooks.h uses these two functions.
|
||||
void HunspellReportMemoryAllocation(void* ptr) {
|
||||
mozHunspell::OnAlloc(ptr);
|
||||
}
|
||||
void HunspellReportMemoryDeallocation(void* ptr) {
|
||||
mozHunspell::OnFree(ptr);
|
||||
}
|
||||
template<> mozilla::Atomic<size_t> mozilla::CountingAllocatorBase<HunspellAllocator>::sAmount(0);
|
||||
|
||||
mozHunspell::mozHunspell()
|
||||
: mHunspell(nullptr)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
// being static.
|
||||
// There must be only one instance of this class: it reports memory based on
|
||||
// a single static count in HunspellAllocator.
|
||||
static bool hasRun = false;
|
||||
MOZ_ASSERT(!hasRun);
|
||||
hasRun = true;
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozHunspellAllocator.h"
|
||||
|
||||
#define MOZ_HUNSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1"
|
||||
#define MOZ_HUNSPELL_CID \
|
||||
@ -101,17 +102,11 @@ public:
|
||||
// helper method for converting a word to the charset of the dictionary
|
||||
nsresult ConvertCharset(const char16_t* aStr, char ** aDst);
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
|
||||
|
||||
static void OnAlloc(void* ptr) { sAmount += MallocSizeOfOnAlloc(ptr); }
|
||||
static void OnFree (void* ptr) { sAmount -= MallocSizeOfOnFree (ptr); }
|
||||
|
||||
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData)
|
||||
{
|
||||
return MOZ_COLLECT_REPORT(
|
||||
"explicit/spell-check", KIND_HEAP, UNITS_BYTES, sAmount,
|
||||
"explicit/spell-check", KIND_HEAP, UNITS_BYTES, HunspellAllocator::MemoryAllocated(),
|
||||
"Memory used by the spell-checking engine.");
|
||||
}
|
||||
|
||||
@ -131,8 +126,6 @@ protected:
|
||||
nsCOMArray<nsIFile> mDynamicDirectories;
|
||||
|
||||
Hunspell *mHunspell;
|
||||
|
||||
static int64_t sAmount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
16
extensions/spellcheck/hunspell/src/mozHunspellAllocator.h
Normal file
16
extensions/spellcheck/hunspell/src/mozHunspellAllocator.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozHunspellAllocator_h__
|
||||
#define mozHunspellAllocator_h__
|
||||
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
class HunspellAllocator : public mozilla::CountingAllocatorBase<HunspellAllocator>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
@ -40,67 +40,40 @@ using namespace mozilla::gfx;
|
||||
|
||||
static FT_Library gPlatformFTLibrary = nullptr;
|
||||
|
||||
class FreetypeReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
class FreetypeReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||
public CountingAllocatorBase<FreetypeReporter>
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
FreetypeReporter()
|
||||
static void* Malloc(FT_Memory, long size)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
// being static.
|
||||
static bool hasRun = false;
|
||||
MOZ_ASSERT(!hasRun);
|
||||
hasRun = true;
|
||||
#endif
|
||||
return CountingMalloc(size);
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
|
||||
|
||||
static void* CountingAlloc(FT_Memory, long size)
|
||||
static void Free(FT_Memory, void* p)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void CountingFree(FT_Memory, void* p)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
free(p);
|
||||
return CountingFree(p);
|
||||
}
|
||||
|
||||
static void*
|
||||
CountingRealloc(FT_Memory, long cur_size, long new_size, void* p)
|
||||
Realloc(FT_Memory, long cur_size, long new_size, void* p)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
void *pnew = realloc(p, new_size);
|
||||
if (pnew) {
|
||||
sAmount += MallocSizeOfOnAlloc(pnew);
|
||||
} else {
|
||||
// realloc failed; undo the decrement from above
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
}
|
||||
return pnew;
|
||||
return CountingRealloc(p, new_size);
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData)
|
||||
{
|
||||
return MOZ_COLLECT_REPORT(
|
||||
"explicit/freetype", KIND_HEAP, UNITS_BYTES, sAmount,
|
||||
"explicit/freetype", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
|
||||
"Memory used by Freetype.");
|
||||
}
|
||||
|
||||
private:
|
||||
static int64_t sAmount;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(FreetypeReporter, nsIMemoryReporter)
|
||||
|
||||
int64_t FreetypeReporter::sAmount = 0;
|
||||
template<> Atomic<size_t> CountingAllocatorBase<FreetypeReporter>::sAmount(0);
|
||||
|
||||
static FT_MemoryRec_ sFreetypeMemoryRecord;
|
||||
|
||||
@ -108,9 +81,9 @@ gfxAndroidPlatform::gfxAndroidPlatform()
|
||||
{
|
||||
// A custom allocator. It counts allocations, enabling memory reporting.
|
||||
sFreetypeMemoryRecord.user = nullptr;
|
||||
sFreetypeMemoryRecord.alloc = FreetypeReporter::CountingAlloc;
|
||||
sFreetypeMemoryRecord.free = FreetypeReporter::CountingFree;
|
||||
sFreetypeMemoryRecord.realloc = FreetypeReporter::CountingRealloc;
|
||||
sFreetypeMemoryRecord.alloc = FreetypeReporter::Malloc;
|
||||
sFreetypeMemoryRecord.free = FreetypeReporter::Free;
|
||||
sFreetypeMemoryRecord.realloc = FreetypeReporter::Realloc;
|
||||
|
||||
// These two calls are equivalent to FT_Init_FreeType(), but allow us to
|
||||
// provide a custom memory allocator.
|
||||
|
@ -401,6 +401,7 @@ interface nsIMemoryReporterManager : nsISupports
|
||||
#include "js/TypeDecls.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
|
||||
@ -530,6 +531,116 @@ void RunReportersForThisProcess();
|
||||
return moz_malloc_size_of(aPtr); \
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// This CRTP class handles several details of wrapping allocators and should
|
||||
// be preferred to manually counting with MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC
|
||||
// and MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE. The typical use is in a memory
|
||||
// reporter for a particular third party library:
|
||||
//
|
||||
// class MyMemoryReporter : public CountingAllocatorBase<MyMemoryReporter>
|
||||
// {
|
||||
// ...
|
||||
// NS_IMETHODIMP
|
||||
// CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
|
||||
// {
|
||||
// return MOZ_COLLECT_REPORTER(
|
||||
// "explicit/path/to/somewhere", KIND_HEAP, UNITS_BYTES,
|
||||
// MemoryAllocated(),
|
||||
// "A description of what we are reporting."
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// ...somewhere later in the code...
|
||||
// SetThirdPartyMemoryFunctions(MyMemoryReporter::CountingAlloc,
|
||||
// MyMemoryReporter::CountingFree);
|
||||
template<typename T>
|
||||
class CountingAllocatorBase
|
||||
{
|
||||
public:
|
||||
CountingAllocatorBase()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount| being
|
||||
// static.
|
||||
static bool hasRun = false;
|
||||
MOZ_ASSERT(!hasRun);
|
||||
hasRun = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static size_t
|
||||
MemoryAllocated()
|
||||
{
|
||||
return sAmount;
|
||||
}
|
||||
|
||||
static void*
|
||||
CountingMalloc(size_t size)
|
||||
{
|
||||
void* p = malloc(size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void*
|
||||
CountingCalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void* p = calloc(nmemb, size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void*
|
||||
CountingRealloc(void* p, size_t size)
|
||||
{
|
||||
size_t oldsize = MallocSizeOfOnFree(p);
|
||||
void *pnew = realloc(p, size);
|
||||
if (pnew) {
|
||||
size_t newsize = MallocSizeOfOnAlloc(pnew);
|
||||
sAmount += newsize - oldsize;
|
||||
} else if (size == 0) {
|
||||
// We asked for a 0-sized (re)allocation of some existing pointer
|
||||
// and received NULL in return. 0-sized allocations are permitted
|
||||
// to either return NULL or to allocate a unique object per call (!).
|
||||
// For a malloc implementation that chooses the second strategy,
|
||||
// that allocation may fail (unlikely, but possible).
|
||||
//
|
||||
// Given a NULL return value and an allocation size of 0, then, we
|
||||
// don't know if that means the original pointer was freed or if
|
||||
// the allocation of the unique object failed. If the original
|
||||
// pointer was freed, then we have nothing to do here. If the
|
||||
// allocation of the unique object failed, the original pointer is
|
||||
// still valid and we ought to undo the decrement from above.
|
||||
// However, we have no way of knowing how the underlying realloc
|
||||
// implementation is behaving. Assuming that the original pointer
|
||||
// was freed is the safest course of action. We do, however, need
|
||||
// to note that we freed memory.
|
||||
sAmount -= oldsize;
|
||||
} else {
|
||||
// realloc failed. The amount allocated hasn't changed.
|
||||
}
|
||||
return pnew;
|
||||
}
|
||||
|
||||
static void
|
||||
CountingFree(void* p)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
private:
|
||||
// |sAmount| can be (implicitly) accessed by multiple threads, so it
|
||||
// must be thread-safe.
|
||||
static Atomic<size_t> sAmount;
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// This macro assumes the presence of appropriate |aHandleReport| and |aData|
|
||||
// variables.
|
||||
#define MOZ_COLLECT_REPORT(path, kind, units, amount, description) \
|
||||
|
@ -341,215 +341,81 @@ NS_InitXPCOM(nsIServiceManager* *result,
|
||||
return NS_InitXPCOM2(result, binDirectory, nullptr);
|
||||
}
|
||||
|
||||
class ICUReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
class ICUReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||
public CountingAllocatorBase<ICUReporter>
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
ICUReporter()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
// being static.
|
||||
static bool hasRun = false;
|
||||
MOZ_ASSERT(!hasRun);
|
||||
hasRun = true;
|
||||
#endif
|
||||
sAmount = 0;
|
||||
}
|
||||
|
||||
static void* Alloc(const void*, size_t size)
|
||||
{
|
||||
void* p = malloc(size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
return CountingMalloc(size);
|
||||
}
|
||||
|
||||
static void* Realloc(const void*, void* p, size_t size)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
void *pnew = realloc(p, size);
|
||||
if (pnew) {
|
||||
sAmount += MallocSizeOfOnAlloc(pnew);
|
||||
} else {
|
||||
// realloc failed; undo the decrement from above
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
}
|
||||
return pnew;
|
||||
return CountingRealloc(p, size);
|
||||
}
|
||||
|
||||
static void Free(const void*, void* p)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
free(p);
|
||||
return CountingFree(p);
|
||||
}
|
||||
|
||||
private:
|
||||
// |sAmount| can be (implicitly) accessed by multiple JSRuntimes, so it
|
||||
// must be thread-safe.
|
||||
static Atomic<size_t> sAmount;
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
|
||||
{
|
||||
return MOZ_COLLECT_REPORT(
|
||||
"explicit/icu", KIND_HEAP, UNITS_BYTES, sAmount,
|
||||
"explicit/icu", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
|
||||
"Memory used by ICU, a Unicode and globalization support library.");
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ICUReporter, nsIMemoryReporter)
|
||||
|
||||
/* static */ Atomic<size_t> ICUReporter::sAmount;
|
||||
/* static */ template<> Atomic<size_t> CountingAllocatorBase<ICUReporter>::sAmount(0);
|
||||
|
||||
class OggReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
class OggReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||
public CountingAllocatorBase<OggReporter>
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
OggReporter()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
// being static.
|
||||
static bool hasRun = false;
|
||||
MOZ_ASSERT(!hasRun);
|
||||
hasRun = true;
|
||||
#endif
|
||||
sAmount = 0;
|
||||
}
|
||||
|
||||
static void* Alloc(size_t size)
|
||||
{
|
||||
void* p = malloc(size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void* Realloc(void* p, size_t size)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
void *pnew = realloc(p, size);
|
||||
if (pnew) {
|
||||
sAmount += MallocSizeOfOnAlloc(pnew);
|
||||
} else {
|
||||
// realloc failed; undo the decrement from above
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
}
|
||||
return pnew;
|
||||
}
|
||||
|
||||
static void* Calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void* p = calloc(nmemb, size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void Free(void* p)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
private:
|
||||
// |sAmount| can be (implicitly) accessed by multiple threads, so it
|
||||
// must be thread-safe.
|
||||
static Atomic<size_t> sAmount;
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
|
||||
{
|
||||
return MOZ_COLLECT_REPORT(
|
||||
"explicit/media/libogg", KIND_HEAP, UNITS_BYTES, sAmount,
|
||||
"explicit/media/libogg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
|
||||
"Memory allocated through libogg for Ogg, Theora, and related media files.");
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(OggReporter, nsIMemoryReporter)
|
||||
|
||||
/* static */ Atomic<size_t> OggReporter::sAmount;
|
||||
/* static */ template<> Atomic<size_t> CountingAllocatorBase<OggReporter>::sAmount(0);
|
||||
|
||||
#ifdef MOZ_VPX
|
||||
class VPXReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
class VPXReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||
public CountingAllocatorBase<VPXReporter>
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
VPXReporter()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
// being static.
|
||||
static bool hasRun = false;
|
||||
MOZ_ASSERT(!hasRun);
|
||||
hasRun = true;
|
||||
#endif
|
||||
sAmount = 0;
|
||||
}
|
||||
|
||||
static void* Alloc(size_t size)
|
||||
{
|
||||
void* p = malloc(size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void* Realloc(void* p, size_t size)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
void *pnew = realloc(p, size);
|
||||
if (pnew) {
|
||||
sAmount += MallocSizeOfOnAlloc(pnew);
|
||||
} else {
|
||||
// realloc failed; undo the decrement from above
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
}
|
||||
return pnew;
|
||||
}
|
||||
|
||||
static void* Calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void* p = calloc(nmemb, size);
|
||||
sAmount += MallocSizeOfOnAlloc(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void Free(void* p)
|
||||
{
|
||||
sAmount -= MallocSizeOfOnFree(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
private:
|
||||
// |sAmount| can be (implicitly) accessed by multiple threads, so it
|
||||
// must be thread-safe.
|
||||
static Atomic<size_t> sAmount;
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
|
||||
{
|
||||
return MOZ_COLLECT_REPORT(
|
||||
"explicit/media/libvpx", KIND_HEAP, UNITS_BYTES, sAmount,
|
||||
"explicit/media/libvpx", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
|
||||
"Memory allocated through libvpx for WebM media files.");
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(VPXReporter, nsIMemoryReporter)
|
||||
|
||||
/* static */ Atomic<size_t> VPXReporter::sAmount;
|
||||
/* static */ template<> Atomic<size_t> CountingAllocatorBase<VPXReporter>::sAmount(0);
|
||||
#endif /* MOZ_VPX */
|
||||
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
@ -706,17 +572,17 @@ NS_InitXPCOM2(nsIServiceManager* *result,
|
||||
mozilla::SetICUMemoryFunctions();
|
||||
|
||||
// Do the same for libogg.
|
||||
ogg_set_mem_functions(OggReporter::Alloc,
|
||||
OggReporter::Calloc,
|
||||
OggReporter::Realloc,
|
||||
OggReporter::Free);
|
||||
ogg_set_mem_functions(OggReporter::CountingMalloc,
|
||||
OggReporter::CountingCalloc,
|
||||
OggReporter::CountingRealloc,
|
||||
OggReporter::CountingFree);
|
||||
|
||||
#ifdef MOZ_VPX
|
||||
// And for VPX.
|
||||
vpx_mem_set_functions(VPXReporter::Alloc,
|
||||
VPXReporter::Calloc,
|
||||
VPXReporter::Realloc,
|
||||
VPXReporter::Free,
|
||||
vpx_mem_set_functions(VPXReporter::CountingMalloc,
|
||||
VPXReporter::CountingCalloc,
|
||||
VPXReporter::CountingRealloc,
|
||||
VPXReporter::CountingFree,
|
||||
memcpy,
|
||||
memset,
|
||||
memmove);
|
||||
|
Loading…
Reference in New Issue
Block a user