bug 688125 - part 1 - add memory reporting for the platform font list. r=njn

This commit is contained in:
Jonathan Kew 2012-03-23 12:14:06 +00:00
parent 1324886d80
commit c278b0a18f
13 changed files with 477 additions and 41 deletions

View File

@ -249,6 +249,23 @@ gfxDWriteFontFamily::LocalizedName(nsAString &aLocalizedName)
aLocalizedName = nsDependentString(famName.Elements());
}
void
gfxDWriteFontFamily::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
gfxFontFamily::SizeOfExcludingThis(aMallocSizeOf, aSizes);
// TODO:
// This doesn't currently account for |mDWFamily|
}
void
gfxDWriteFontFamily::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
////////////////////////////////////////////////////////////////////////////////
// gfxDWriteFontEntry
@ -377,7 +394,8 @@ gfxDWriteFontEntry::ReadCMAP()
unicodeFont, symbolFont);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
@ -424,7 +442,8 @@ gfxDWriteFontEntry::ReadCMAP()
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
@ -544,6 +563,23 @@ gfxDWriteFontEntry::IsCJKFont()
return mIsCJK;
}
void
gfxDWriteFontEntry::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
gfxFontEntry::SizeOfExcludingThis(aMallocSizeOf, aSizes);
// TODO:
// This doesn't currently account for the |mFont| and |mFontFile| members
}
void
gfxDWriteFontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
////////////////////////////////////////////////////////////////////////////////
// gfxDWriteFontList
@ -587,7 +623,6 @@ gfxFontEntry *
gfxDWriteFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
const nsAString& aFullname)
{
bool found;
gfxFontEntry *lookup;
// initialize name lookup tables if needed
@ -596,8 +631,8 @@ gfxDWriteFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
}
// lookup in name lookup tables, return null if not found
if (!(lookup = mPostscriptNames.GetWeak(aFullname, &found)) &&
!(lookup = mFullnames.GetWeak(aFullname, &found)))
if (!(lookup = mPostscriptNames.GetWeak(aFullname)) &&
!(lookup = mFullnames.GetWeak(aFullname)))
{
return nsnull;
}
@ -1182,8 +1217,8 @@ gfxDWriteFontList::ResolveFontName(const nsAString& aFontName,
nsAutoString keyName(aFontName);
BuildKeyNameFromFontName(keyName);
nsRefPtr<gfxFontFamily> ff;
if (mFontSubstitutes.Get(keyName, &ff)) {
gfxFontFamily *ff = mFontSubstitutes.GetWeak(keyName);
if (ff) {
aResolvedFontName = ff->Name();
return true;
}
@ -1195,6 +1230,32 @@ gfxDWriteFontList::ResolveFontName(const nsAString& aFontName,
return gfxPlatformFontList::ResolveFontName(aFontName, aResolvedFontName);
}
void
gfxDWriteFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
gfxPlatformFontList::SizeOfExcludingThis(aMallocSizeOf, aSizes);
aSizes->mFontListSize +=
mFontSubstitutes.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis,
aMallocSizeOf);
aSizes->mFontListSize +=
mNonExistingFonts.SizeOfExcludingThis(aMallocSizeOf);
for (PRUint32 i = 0; i < mNonExistingFonts.Length(); ++i) {
aSizes->mFontListSize +=
mNonExistingFonts[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
}
void
gfxDWriteFontList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
static nsresult GetFamilyName(IDWriteFont *aFont, nsString& aFamilyName)
{
HRESULT hr;

View File

@ -79,6 +79,11 @@ public:
void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
protected:
/** This font family's directwrite fontfamily object */
nsRefPtr<IDWriteFontFamily> mDWFamily;
@ -179,6 +184,11 @@ public:
void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
bool GetForceGDIClassic() { return mForceGDIClassic; }
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
protected:
friend class gfxDWriteFont;
friend class gfxDWriteFontList;
@ -380,6 +390,11 @@ public:
gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; }
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
private:
friend class gfxDWriteFontFamily;
@ -401,7 +416,7 @@ private:
*/
nsTArray<nsString> mNonExistingFonts;
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<gfxFontFamily> > FontTable;
typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontTable;
/**
* Table of font substitutes, we grab this from the registry to get

View File

@ -389,6 +389,23 @@ FT2FontEntry::GetFontTable(PRUint32 aTableTag,
return NS_OK;
}
void
FT2FontEntry::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
gfxFontEntry::SizeOfExcludingThis(aMallocSizeOf, aSizes);
aSizes->mFontListSize +=
mFilename.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
void
FT2FontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
/*
* FT2FontFamily
* A standard gfxFontFamily; just adds a method used to support sending

View File

@ -102,6 +102,11 @@ public:
nsresult ReadCMAP();
nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
FT_Face mFTFace;
cairo_font_face_t *mFontFace;

View File

@ -402,6 +402,44 @@ gfxFontEntry::CheckForGraphiteTables()
}
#endif
/* static */ size_t
gfxFontEntry::FontTableHashEntry::SizeOfEntryExcludingThis
(FontTableHashEntry *aEntry,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
if (aEntry->mBlob) {
FontListSizes *sizes = static_cast<FontListSizes*>(aUserArg);
sizes->mFontTableCacheSize += aMallocSizeOf(aEntry->mBlob);
sizes->mFontTableCacheSize +=
aMallocSizeOf(hb_blob_get_data(aEntry->mBlob, NULL));
}
// the size of the blob is recorded in the FontListSizes record,
// so we return 0 here for the function result
return 0;
}
void
gfxFontEntry::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontTableCacheSize +=
mFontTableCache.SizeOfExcludingThis(
FontTableHashEntry::SizeOfEntryExcludingThis,
aMallocSizeOf, aSizes);
}
void
gfxFontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
//////////////////////////////////////////////////////////////////////////////
//
// class gfxFontFamily
@ -976,6 +1014,32 @@ gfxFontFamily::FindFont(const nsAString& aPostscriptName)
return nsnull;
}
void
gfxFontFamily::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize +=
mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontListSize +=
mAvailableFonts.SizeOfExcludingThis(aMallocSizeOf);
for (PRUint32 i = 0; i < mAvailableFonts.Length(); ++i) {
gfxFontEntry *fe = mAvailableFonts[i];
if (fe) {
fe->SizeOfIncludingThis(aMallocSizeOf, aSizes);
}
}
}
void
gfxFontFamily::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
/*
* gfxFontCache - global cache of gfxFont instances.
* Expires unused fonts after a short interval;

View File

@ -90,6 +90,8 @@ struct THEBES_API gfxFontFeature {
// to features that select among multiple alternatives
};
struct FontListSizes;
inline bool
operator<(const gfxFontFeature& a, const gfxFontFeature& b)
{
@ -313,6 +315,12 @@ public:
hb_blob_t *ShareFontTableAndGetBlob(PRUint32 aTag,
FallibleTArray<PRUint8>* aTable);
// For memory reporting
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
nsString mName;
bool mItalic : 1;
@ -467,6 +475,11 @@ private:
void Clear();
static size_t
SizeOfEntryExcludingThis(FontTableHashEntry *aEntry,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg);
private:
static void DeleteFontTableBlobData(void *aBlobData);
// not implemented
@ -633,6 +646,12 @@ public:
// if so set the mIsSimpleFamily flag (defaults to False before we've checked)
void CheckForSimpleFamily();
// For memory reporter
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
protected:
// fills in an array with weights of faces that match style,
// returns whether any matching entries found

View File

@ -264,14 +264,18 @@ public:
}
}
PRUint32 GetSize() {
PRUint32 size = 0;
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
size_t total = mBlocks.SizeOfExcludingThis(aMallocSizeOf);
for (PRUint32 i = 0; i < mBlocks.Length(); i++) {
if (mBlocks[i])
size += sizeof(Block);
size += sizeof(nsAutoPtr<Block>);
if (mBlocks[i]) {
total += aMallocSizeOf(mBlocks[i]);
}
}
return size;
return total;
}
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
// clear out all blocks in the array

View File

@ -246,7 +246,8 @@ GDIFontEntry::ReadCMAP()
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
@ -459,6 +460,14 @@ GDIFontEntry::CreateFontEntry(const nsAString& aName,
return fe;
}
void
GDIFontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
/***************************************************************
*
* GDIFontFamily
@ -658,7 +667,7 @@ gfxGDIFontList::GetFontSubstitutes()
nsAutoString substituteName;
substituteName.AssignLiteral("Courier");
BuildKeyNameFromFontName(substituteName);
if (!mFontSubstitutes.Get(substituteName)) {
if (!mFontSubstitutes.GetWeak(substituteName)) {
gfxFontFamily *ff;
nsAutoString actualFontName;
actualFontName.AssignLiteral("Courier New");
@ -743,7 +752,6 @@ gfxFontEntry*
gfxGDIFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
const nsAString& aFullname)
{
bool found;
gfxFontEntry *lookup;
// initialize name lookup tables if needed
@ -752,8 +760,8 @@ gfxGDIFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
}
// lookup in name lookup tables, return null if not found
if (!(lookup = mPostscriptNames.GetWeak(aFullname, &found)) &&
!(lookup = mFullnames.GetWeak(aFullname, &found)))
if (!(lookup = mPostscriptNames.GetWeak(aFullname)) &&
!(lookup = mFullnames.GetWeak(aFullname)))
{
return nsnull;
}
@ -1038,8 +1046,8 @@ gfxGDIFontList::ResolveFontName(const nsAString& aFontName, nsAString& aResolved
nsAutoString keyName(aFontName);
BuildKeyNameFromFontName(keyName);
nsRefPtr<gfxFontFamily> ff;
if (mFontSubstitutes.Get(keyName, &ff)) {
gfxFontFamily *ff = mFontSubstitutes.GetWeak(keyName);
if (ff) {
aResolvedFontName = ff->Name();
return true;
}
@ -1052,3 +1060,27 @@ gfxGDIFontList::ResolveFontName(const nsAString& aFontName, nsAString& aResolved
return false;
}
void
gfxGDIFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
gfxPlatformFontList::SizeOfExcludingThis(aMallocSizeOf, aSizes);
aSizes->mFontListSize +=
mFontSubstitutes.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis,
aMallocSizeOf);
aSizes->mFontListSize +=
mNonExistingFonts.SizeOfExcludingThis(aMallocSizeOf);
for (PRUint32 i = 0; i < mNonExistingFonts.Length(); ++i) {
aSizes->mFontListSize +=
mNonExistingFonts[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
}
void
gfxGDIFontList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}

View File

@ -274,6 +274,9 @@ public:
virtual bool TestCharacterMap(PRUint32 aCh);
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
// create a font entry for a font with a given name
static GDIFontEntry* CreateFontEntry(const nsAString& aName,
gfxWindowsFontType aFontType,
@ -347,6 +350,11 @@ public:
virtual bool ResolveFontName(const nsAString& aFontName,
nsAString& aResolvedFontName);
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
private:
friend class gfxWindowsPlatform;
@ -361,7 +369,7 @@ private:
DWORD fontType,
LPARAM lParam);
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<gfxFontFamily> > FontTable;
typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontTable;
FontTable mFontSubstitutes;
nsTArray<nsString> mNonExistingFonts;

View File

@ -111,6 +111,9 @@ public:
virtual nsresult GetFontTable(PRUint32 aTableTag,
FallibleTArray<PRUint8>& aBuffer);
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
protected:
virtual bool HasFontTable(PRUint32 aTableTag);
@ -134,6 +137,9 @@ public:
virtual nsresult GetFontTable(PRUint32 aTableTag,
FallibleTArray<PRUint8>& aBuffer);
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
protected:
virtual bool HasFontTable(PRUint32 aTableTag);
};

View File

@ -270,7 +270,7 @@ MacOSFontEntry::ReadCMAP()
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
NS_ConvertUTF16toUTF8(mName).get(),
mCharacterMap.GetSize()));
mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
@ -398,6 +398,14 @@ ATSFontEntry::HasFontTable(PRUint32 aTableTag)
(::ATSFontGetTable(fontRef, aTableTag, 0, 0, 0, &size) == noErr);
}
void
ATSFontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
/* CGFontEntry - used on Mac OS X 10.6+ */
#pragma mark-
@ -486,6 +494,14 @@ CGFontEntry::HasFontTable(PRUint32 aTableTag)
return true;
}
void
CGFontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}
/* gfxMacFontFamily */
#pragma mark-
@ -811,10 +827,9 @@ gfxMacPlatformFontList::InitSingleFaceList()
#endif
// add only if doesn't exist already
bool found;
gfxFontFamily *familyEntry;
if (!(familyEntry = mFontFamilies.GetWeak(key, &found))) {
familyEntry = new gfxSingleFaceMacFontFamily(familyName);
if (!mFontFamilies.GetWeak(key)) {
gfxFontFamily *familyEntry =
new gfxSingleFaceMacFontFamily(familyName);
familyEntry->AddFontEntry(fontEntry);
familyEntry->SetHasStyles(true);
mFontFamilies.Put(key, familyEntry);

View File

@ -130,6 +130,60 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
return NS_OK;
}
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryMultiReporter)
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf, "font-list")
NS_IMETHODIMP
gfxPlatformFontList::MemoryReporter::GetName(nsACString &aName)
{
aName.AssignLiteral("font-list");
return NS_OK;
}
NS_IMETHODIMP
gfxPlatformFontList::MemoryReporter::CollectReports
(nsIMemoryMultiReporterCallback* aCb,
nsISupports* aClosure)
{
FontListSizes sizes;
gfxPlatformFontList::PlatformFontList()->SizeOfIncludingThis(&FontListMallocSizeOf,
&sizes);
aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-list"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
sizes.mFontListSize,
NS_LITERAL_CSTRING("Memory used to manage the list of font families and faces."),
aClosure);
aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-charmaps"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
sizes.mCharMapsSize,
NS_LITERAL_CSTRING("Memory used to record the character coverage of individual fonts."),
aClosure);
if (sizes.mFontTableCacheSize) {
aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-tables"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
sizes.mFontTableCacheSize,
NS_LITERAL_CSTRING("Memory used for cached font metrics and layout tables."),
aClosure);
}
return NS_OK;
}
NS_IMETHODIMP
gfxPlatformFontList::MemoryReporter::GetExplicitNonHeap(PRInt64* aAmount)
{
// This reporter only measures heap memory.
*aAmount = 0;
return NS_OK;
}
gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
: mNeedFullnamePostscriptNames(aNeedFullnamePostscriptNames),
@ -184,6 +238,8 @@ gfxPlatformFontList::InitFontList()
mCodepointsWithNoFonts.SetRange(0,0x1f); // C0 controls
mCodepointsWithNoFonts.SetRange(0x7f,0x9f); // C1 controls
NS_RegisterMemoryMultiReporter(new MemoryReporter);
sPlatformFontList = this;
return NS_OK;
@ -244,12 +300,11 @@ gfxPlatformFontList::PreloadNamesList()
PRUint32 numFonts = preloadFonts.Length();
for (PRUint32 i = 0; i < numFonts; i++) {
bool found;
nsAutoString key;
GenerateFontListKey(preloadFonts[i], key);
// only search canonical names!
gfxFontFamily *familyEntry = mFontFamilies.GetWeak(key, &found);
gfxFontFamily *familyEntry = mFontFamilies.GetWeak(key);
if (familyEntry) {
familyEntry->ReadOtherFamilyNames(this);
}
@ -549,18 +604,17 @@ gfxPlatformFontList::FindFamily(const nsAString& aFamily)
{
nsAutoString key;
gfxFontFamily *familyEntry;
bool found;
GenerateFontListKey(aFamily, key);
NS_ASSERTION(mFontFamilies.Count() != 0, "system font list was not initialized correctly");
// lookup in canonical (i.e. English) family name list
if ((familyEntry = mFontFamilies.GetWeak(key, &found))) {
if ((familyEntry = mFontFamilies.GetWeak(key))) {
return familyEntry;
}
// lookup in other family names list (mostly localized names)
if ((familyEntry = mOtherFamilyNames.GetWeak(key, &found)) != nsnull) {
if ((familyEntry = mOtherFamilyNames.GetWeak(key)) != nsnull) {
return familyEntry;
}
@ -571,7 +625,7 @@ gfxPlatformFontList::FindFamily(const nsAString& aFamily)
// in practice so avoid pulling in names at startup
if (!mOtherFamilyNamesInitialized && !IsASCII(aFamily)) {
InitOtherFamilyNames();
if ((familyEntry = mOtherFamilyNames.GetWeak(key, &found)) != nsnull) {
if ((familyEntry = mOtherFamilyNames.GetWeak(key)) != nsnull) {
return familyEntry;
}
}
@ -608,10 +662,9 @@ void
gfxPlatformFontList::AddOtherFamilyName(gfxFontFamily *aFamilyEntry, nsAString& aOtherFamilyName)
{
nsAutoString key;
bool found;
GenerateFontListKey(aOtherFamilyName, key);
if (!mOtherFamilyNames.GetWeak(key, &found)) {
if (!mOtherFamilyNames.GetWeak(key)) {
mOtherFamilyNames.Put(key, aFamilyEntry);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-otherfamily) canonical family: %s, "
@ -627,9 +680,7 @@ gfxPlatformFontList::AddOtherFamilyName(gfxFontFamily *aFamilyEntry, nsAString&
void
gfxPlatformFontList::AddFullname(gfxFontEntry *aFontEntry, nsAString& aFullname)
{
bool found;
if (!mFullnames.GetWeak(aFullname, &found)) {
if (!mFullnames.GetWeak(aFullname)) {
mFullnames.Put(aFullname, aFontEntry);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-fullname) name: %s, fullname: %s\n",
@ -642,9 +693,7 @@ gfxPlatformFontList::AddFullname(gfxFontEntry *aFontEntry, nsAString& aFullname)
void
gfxPlatformFontList::AddPostscriptName(gfxFontEntry *aFontEntry, nsAString& aPostscriptName)
{
bool found;
if (!mPostscriptNames.GetWeak(aPostscriptName, &found)) {
if (!mPostscriptNames.GetWeak(aPostscriptName)) {
mPostscriptNames.Put(aPostscriptName, aFontEntry);
#ifdef PR_LOGGING
LOG_FONTLIST(("(fontlist-postscript) name: %s, psname: %s\n",
@ -714,3 +763,111 @@ gfxPlatformFontList::FinishLoader()
mFontFamiliesToLoad.Clear();
mNumFamilies = 0;
}
// Support for memory reporting
static size_t
SizeOfFamilyEntryExcludingThis(const nsAString& aKey,
const nsRefPtr<gfxFontFamily>& aFamily,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
FontListSizes *sizes = static_cast<FontListSizes*>(aUserArg);
aFamily->SizeOfExcludingThis(aMallocSizeOf, sizes);
sizes->mFontListSize += aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
// we return zero here because the measurements have been added directly
// to the relevant fields of the FontListSizes record
return 0;
}
// this is also used by subclasses that hold additional hashes of family names
/*static*/ size_t
gfxPlatformFontList::SizeOfFamilyNameEntryExcludingThis
(const nsAString& aKey,
const nsRefPtr<gfxFontFamily>& aFamily,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
// we don't count the size of the family here, because this is an *extra*
// reference to a family that will have already been counted in the main list
return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
static size_t
SizeOfFontNameEntryExcludingThis(const nsAString& aKey,
const nsRefPtr<gfxFontEntry>& aFont,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
// the font itself is counted by its owning family; here we only care about
// the name stored in the hashtable key
return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
static size_t
SizeOfPrefFontEntryExcludingThis
(const PRUint32& aKey,
const nsTArray<nsRefPtr<gfxFontFamily> >& aList,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
// again, we only care about the size of the array itself; we don't follow
// the refPtrs stored in it, because they point to entries already owned
// and accounted-for by the main font list
return aList.SizeOfExcludingThis(aMallocSizeOf);
}
static size_t
SizeOfStringEntryExcludingThis(nsStringHashKey* aHashEntry,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg)
{
return aHashEntry->GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
void
gfxPlatformFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize +=
mFontFamilies.SizeOfExcludingThis(SizeOfFamilyEntryExcludingThis,
aMallocSizeOf, aSizes);
aSizes->mFontListSize +=
mOtherFamilyNames.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis,
aMallocSizeOf);
if (mNeedFullnamePostscriptNames) {
aSizes->mFontListSize +=
mFullnames.SizeOfExcludingThis(SizeOfFontNameEntryExcludingThis,
aMallocSizeOf);
aSizes->mFontListSize +=
mPostscriptNames.SizeOfExcludingThis(SizeOfFontNameEntryExcludingThis,
aMallocSizeOf);
}
aSizes->mFontListSize +=
mCodepointsWithNoFonts.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontListSize +=
mReplacementCharFallbackFamily.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
aSizes->mFontListSize +=
mFontFamiliesToLoad.SizeOfExcludingThis(aMallocSizeOf);
aSizes->mFontListSize +=
mPrefFonts.SizeOfExcludingThis(SizeOfPrefFontEntryExcludingThis,
aMallocSizeOf);
aSizes->mFontListSize +=
mBadUnderlineFamilyNames.SizeOfExcludingThis(SizeOfStringEntryExcludingThis,
aMallocSizeOf);
}
void
gfxPlatformFontList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const
{
aSizes->mFontListSize += aMallocSizeOf(this);
SizeOfExcludingThis(aMallocSizeOf, aSizes);
}

View File

@ -47,6 +47,7 @@
#include "gfxFont.h"
#include "gfxPlatform.h"
#include "nsIMemoryReporter.h"
#include "mozilla/FunctionTimer.h"
// gfxPlatformFontList is an abstract class for the global font list on the system;
@ -57,6 +58,18 @@
// Much of this is based on the old gfxQuartzFontCache, but adapted for use on all platforms.
struct FontListSizes {
FontListSizes()
: mFontListSize(0), mFontTableCacheSize(0), mCharMapsSize(0)
{ }
size_t mFontListSize; // size of the font list and dependent objects
// (font family and face names, etc), but NOT
// including the font table cache and the cmaps
size_t mFontTableCacheSize; // memory used for the gfxFontEntry table caches
size_t mCharMapsSize; // memory used for cmap coverage info
};
class gfxPlatformFontList : protected gfxFontInfoLoader
{
public:
@ -141,7 +154,20 @@ public:
// (platforms may override, eg Mac)
virtual bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
FontListSizes* aSizes) const;
protected:
class MemoryReporter
: public nsIMemoryMultiReporter
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER
};
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
static gfxPlatformFontList *sPlatformFontList;
@ -200,6 +226,13 @@ protected:
virtual bool RunLoader();
virtual void FinishLoader();
// used by memory reporter to accumulate sizes of family names in the hash
static size_t
SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey,
const nsRefPtr<gfxFontFamily>& aFamily,
nsMallocSizeOfFun aMallocSizeOf,
void* aUserArg);
// canonical family name ==> family entry (unique, one name per family entry)
nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mFontFamilies;