Bug 1187145 - Replace nsBaseHashtable::Enumerate() calls in gfx/ with iterators r=njn
authorSotaro Ikeda <sikeda@mozilla.com>
Thu, 24 Sep 2015 08:31:30 -0700
changeset 297631 e2149155361cd5050a3d77e989d34b41989fb564
parent 297630 08cbf0b0c9e8435d102c4c2a5e7ec491e92dbf1d
child 297632 2fd5cfcea4e567fa9dc3e200c7b675b19d97c290
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1187145
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1187145 - Replace nsBaseHashtable::Enumerate() calls in gfx/ with iterators r=njn
gfx/layers/ipc/CompositorChild.cpp
gfx/layers/ipc/CompositorChild.h
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxFontEntry.cpp
gfx/thebes/gfxGraphiteShaper.cpp
gfx/thebes/gfxHarfBuzzShaper.cpp
gfx/thebes/gfxPlatformFontList.cpp
gfx/thebes/gfxPlatformFontList.h
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -173,32 +173,27 @@ CompositorChild::AllocPLayerTransactionC
                                              bool*)
 {
   MOZ_ASSERT(mCanSend);
   LayerTransactionChild* c = new LayerTransactionChild(aId);
   c->AddIPDLReference();
   return c;
 }
 
-/*static*/ PLDHashOperator
-CompositorChild::RemoveSharedMetricsForLayersId(const uint64_t& aKey,
-                                                nsAutoPtr<SharedFrameMetricsData>& aData,
-                                                void* aLayerTransactionChild)
-{
-  uint64_t childId = static_cast<LayerTransactionChild*>(aLayerTransactionChild)->GetId();
-  if (aData->GetLayersId() == childId) {
-    return PLDHashOperator::PL_DHASH_REMOVE;
-  }
-  return PLDHashOperator::PL_DHASH_NEXT;
-}
-
 bool
 CompositorChild::DeallocPLayerTransactionChild(PLayerTransactionChild* actor)
 {
-  mFrameMetricsTable.Enumerate(RemoveSharedMetricsForLayersId, actor);
+  uint64_t childId = static_cast<LayerTransactionChild*>(actor)->GetId();
+
+  for (auto iter = mFrameMetricsTable.Iter(); !iter.Done(); iter.Next()) {
+    nsAutoPtr<SharedFrameMetricsData>& data = iter.Data();
+    if (data->GetLayersId() == childId) {
+      iter.Remove();
+    }
+  }
   static_cast<LayerTransactionChild*>(actor)->ReleaseIPDLReference();
   return true;
 }
 
 bool
 CompositorChild::RecvInvalidateAll()
 {
   if (mLayerManager) {
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -169,20 +169,16 @@ private:
     // the shared FrameMetrics
     nsRefPtr<mozilla::ipc::SharedMemoryBasic> mBuffer;
     CrossProcessMutex* mMutex;
     uint64_t mLayersId;
     // Unique ID of the APZC that is sharing the FrameMetrics
     uint32_t mAPZCId;
   };
 
-  static PLDHashOperator RemoveSharedMetricsForLayersId(const uint64_t& aKey,
-                                                        nsAutoPtr<SharedFrameMetricsData>& aData,
-                                                        void* aLayerTransactionChild);
-
   nsRefPtr<ClientLayerManager> mLayerManager;
   // When not multi-process, hold a reference to the CompositorParent to keep it
   // alive. This reference should be null in multi-process.
   nsRefPtr<CompositorParent> mCompositorParent;
 
   // The ViewID of the FrameMetrics is used as the key for this hash table.
   // While this should be safe to use since the ViewID is unique
   nsClassHashtable<nsUint64HashKey, SharedFrameMetricsData> mFrameMetricsTable;
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -1110,32 +1110,29 @@ gfxFT2FontList::AppendFacesFromOmnijarEn
     if (aCache && !faceList.IsEmpty()) {
         aCache->CacheFileInfo(aEntryName, faceList, 0, bufSize);
     }
 }
 
 // Called on each family after all fonts are added to the list;
 // this will sort faces to give priority to "standard" font files
 // if aUserArg is non-null (i.e. we're using it as a boolean flag)
-static PLDHashOperator
+static void
 FinalizeFamilyMemberList(nsStringHashKey::KeyType aKey,
                          nsRefPtr<gfxFontFamily>& aFamily,
-                         void* aUserArg)
+                         bool aSortFaces)
 {
     gfxFontFamily *family = aFamily.get();
-    bool sortFaces = (aUserArg != nullptr);
 
     family->SetHasStyles(true);
 
-    if (sortFaces) {
+    if (aSortFaces) {
         family->SortAvailableFonts();
     }
     family->CheckForSimpleFamily();
-
-    return PL_DHASH_NEXT;
 }
 
 void
 gfxFT2FontList::FindFonts()
 {
     gfxFontCache *fc = gfxFontCache::GetCache();
     if (fc)
         fc->AgeAllGenerations();
@@ -1152,18 +1149,27 @@ gfxFT2FontList::FindFonts()
         for (uint32_t i = 0, n = fonts.Length(); i < n; ++i) {
             // We don't need to identify "standard" font files here,
             // as the faces are already sorted.
             AppendFaceFromFontListEntry(fonts[i], kUnknown);
         }
         // Passing null for userdata tells Finalize that it does not need
         // to sort faces (because they were already sorted by chrome,
         // so we just maintain the existing order)
-        mFontFamilies.Enumerate(FinalizeFamilyMemberList, nullptr);
-        mHiddenFontFamilies.Enumerate(FinalizeFamilyMemberList, nullptr);
+        for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+            nsStringHashKey::KeyType key = iter.Key();
+            nsRefPtr<gfxFontFamily>& family = iter.Data();
+            FinalizeFamilyMemberList(key, family, /* aSortFaces */ false);
+        }
+        for (auto iter = mHiddenFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+            nsStringHashKey::KeyType key = iter.Key();
+            nsRefPtr<gfxFontFamily>& family = iter.Data();
+            FinalizeFamilyMemberList(key, family, /* aSortFaces */ false );
+        }
+
         LOG(("got font list from chrome process: %d faces in %d families "
              "and %d in hidden families",
             fonts.Length(), mFontFamilies.Count(),
             mHiddenFontFamilies.Count()));
         return;
     }
 
     // Chrome process: get the cached list (if any)
@@ -1232,18 +1238,26 @@ gfxFT2FontList::FindFonts()
         if (NS_SUCCEEDED(rv)) {
             FindFontsInDir(localPath, &fnc, FT2FontFamily::kVisible);
         }
     }
 
     // Finalize the families by sorting faces into standard order
     // and marking "simple" families.
     // Passing non-null userData here says that we want faces to be sorted.
-    mFontFamilies.Enumerate(FinalizeFamilyMemberList, this);
-    mHiddenFontFamilies.Enumerate(FinalizeFamilyMemberList, this);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsStringHashKey::KeyType key = iter.Key();
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        FinalizeFamilyMemberList(key, family, /* aSortFaces */ true);
+    }
+    for (auto iter = mHiddenFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsStringHashKey::KeyType key = iter.Key();
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        FinalizeFamilyMemberList(key, family, /* aSortFaces */ true);
+    }
 }
 
 void
 gfxFT2FontList::FindFontsInDir(const nsCString& aDir,
                                FontNameCache *aFNC,
                                FT2FontFamily::Visibility aVisibility)
 {
     static const char* sStandardFonts[] = {
@@ -1323,69 +1337,46 @@ gfxFT2FontList::AppendFaceFromFontListEn
             }
         }
         family->AddFontEntry(fe);
 
         fe->CheckForBrokenFont(family);
     }
 }
 
-static PLDHashOperator
-AddFamilyToFontList(nsStringHashKey::KeyType aKey,
-                    nsRefPtr<gfxFontFamily>& aFamily,
-                    void* aUserArg)
-{
-    InfallibleTArray<FontListEntry>* fontlist =
-        reinterpret_cast<InfallibleTArray<FontListEntry>*>(aUserArg);
-
-    FT2FontFamily *family = static_cast<FT2FontFamily*>(aFamily.get());
-    family->AddFacesToFontList(fontlist, FT2FontFamily::kVisible);
-
-    return PL_DHASH_NEXT;
-}
-
-static PLDHashOperator
-AddHiddenFamilyToFontList(nsStringHashKey::KeyType aKey,
-                          nsRefPtr<gfxFontFamily>& aFamily,
-                          void* aUserArg)
-{
-    InfallibleTArray<FontListEntry>* fontlist =
-        reinterpret_cast<InfallibleTArray<FontListEntry>*>(aUserArg);
-
-    FT2FontFamily *family = static_cast<FT2FontFamily*>(aFamily.get());
-    family->AddFacesToFontList(fontlist, FT2FontFamily::kHidden);
-
-    return PL_DHASH_NEXT;
-}
-
 void
 gfxFT2FontList::GetSystemFontList(InfallibleTArray<FontListEntry>* retValue)
 {
-    mFontFamilies.Enumerate(AddFamilyToFontList, retValue);
-    mHiddenFontFamilies.Enumerate(AddHiddenFamilyToFontList, retValue);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        auto family = static_cast<FT2FontFamily*>(iter.Data().get());
+        family->AddFacesToFontList(retValue, FT2FontFamily::kVisible);
+    }
+    for (auto iter = mHiddenFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        auto family = static_cast<FT2FontFamily*>(iter.Data().get());
+        family->AddFacesToFontList(retValue, FT2FontFamily::kHidden);
+    }
 }
 
 static void
 LoadSkipSpaceLookupCheck(nsTHashtable<nsStringHashKey>& aSkipSpaceLookupCheck)
 {
     nsAutoTArray<nsString, 5> skiplist;
     gfxFontUtils::GetPrefsFontList(
         "font.whitelist.skip_default_features_space_check",
         skiplist);
     uint32_t numFonts = skiplist.Length();
     for (uint32_t i = 0; i < numFonts; i++) {
         ToLowerCase(skiplist[i]);
         aSkipSpaceLookupCheck.PutEntry(skiplist[i]);
     }
 }
 
-static PLDHashOperator
+void
 PreloadAsUserFontFaces(nsStringHashKey::KeyType aKey,
-                       nsRefPtr<gfxFontFamily>& aFamily,
-                       void* aUserArg)
+                       nsRefPtr<gfxFontFamily>& aFamily)
 {
     gfxFontFamily *family = aFamily.get();
 
     auto& faces = family->GetFontList();
     size_t count = faces.Length();
     for (size_t i = 0; i < count; ++i) {
         FT2FontEntry* fe = static_cast<FT2FontEntry*>(faces[i].get());
         if (fe->mFTFontIndex != 0) {
@@ -1428,111 +1419,100 @@ PreloadAsUserFontFaces(nsStringHashKey::
         fe->mUserFontData->mRealName = fe->Name();
         fe->mUserFontData->mCRC32 = crc;
         fe->mUserFontData->mLength = buf.st_size;
 
         // Stash it persistently in the user-font cache.
         gfxUserFontSet::UserFontCache::CacheFont(
             fe, gfxUserFontSet::UserFontCache::kPersistent);
     }
-
-    return PL_DHASH_NEXT;
 }
 
 nsresult
 gfxFT2FontList::InitFontList()
 {
     // reset font lists
     gfxPlatformFontList::InitFontList();
     mHiddenFontFamilies.Clear();
-    
+
     LoadSkipSpaceLookupCheck(mSkipSpaceLookupCheckFamilies);
 
     FindFonts();
 
-    mHiddenFontFamilies.Enumerate(PreloadAsUserFontFaces, this);
-
+    for (auto iter = mHiddenFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsStringHashKey::KeyType key = iter.Key();
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        PreloadAsUserFontFaces(key, family);
+    }
     return NS_OK;
 }
 
-struct FullFontNameSearch {
-    FullFontNameSearch(const nsAString& aFullName)
-        : mFullName(aFullName), mFontEntry(nullptr)
-    { }
-
-    nsString     mFullName;
-    FT2FontEntry *mFontEntry;
-};
-
-// callback called for each family name, based on the assumption that the 
+// called for each family name, based on the assumption that the
 // first part of the full name is the family name
-static PLDHashOperator
-FindFullName(nsStringHashKey::KeyType aKey,
-             nsRefPtr<gfxFontFamily>& aFontFamily,
-             void* userArg)
-{
-    FullFontNameSearch *data = reinterpret_cast<FullFontNameSearch*>(userArg);
-
-    // does the family name match up to the length of the family name?
-    const nsString& family = aFontFamily->Name();
 
-    nsString fullNameFamily;
-    data->mFullName.Left(fullNameFamily, family.Length());
-
-    // if so, iterate over faces in this family to see if there is a match
-    if (family.Equals(fullNameFamily, nsCaseInsensitiveStringComparator())) {
-        nsTArray<nsRefPtr<gfxFontEntry> >& fontList = aFontFamily->GetFontList();
-        int index, len = fontList.Length();
-        for (index = 0; index < len; index++) {
-            gfxFontEntry* fe = fontList[index];
-            if (!fe) {
-                continue;
-            }
-            if (fe->Name().Equals(data->mFullName,
-                                  nsCaseInsensitiveStringComparator())) {
-                data->mFontEntry = static_cast<FT2FontEntry*>(fe);
-                return PL_DHASH_STOP;
-            }
-        }
-    }
-
-    return PL_DHASH_NEXT;
-}
-
-gfxFontEntry* 
+gfxFontEntry*
 gfxFT2FontList::LookupLocalFont(const nsAString& aFontName,
                                 uint16_t aWeight,
                                 int16_t aStretch,
                                 bool aItalic)
 {
     // walk over list of names
-    FullFontNameSearch data(aFontName);
+    FT2FontEntry* fontEntry = nullptr;
+    nsString fullName(aFontName);
 
     // Note that we only check mFontFamilies here, not mHiddenFontFamilies;
     // hence @font-face { src:local(...) } will not find hidden fonts.
-    mFontFamilies.Enumerate(FindFullName, &data);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        // Check family name, based on the assumption that the
+        // first part of the full name is the family name
+        nsRefPtr<gfxFontFamily>& fontFamily = iter.Data();
+
+        // does the family name match up to the length of the family name?
+        const nsString& family = fontFamily->Name();
+        nsString fullNameFamily;
+
+        fullName.Left(fullNameFamily, family.Length());
 
-    if (!data.mFontEntry) {
+        // if so, iterate over faces in this family to see if there is a match
+        if (family.Equals(fullNameFamily, nsCaseInsensitiveStringComparator())) {
+            nsTArray<nsRefPtr<gfxFontEntry> >& fontList = fontFamily->GetFontList();
+            int index, len = fontList.Length();
+            for (index = 0; index < len; index++) {
+                gfxFontEntry* fe = fontList[index];
+                if (!fe) {
+                    continue;
+                }
+                if (fe->Name().Equals(fullName,
+                                      nsCaseInsensitiveStringComparator())) {
+                    fontEntry = static_cast<FT2FontEntry*>(fe);
+                    goto searchDone;
+                }
+            }
+        }
+    }
+
+searchDone:
+    if (!fontEntry) {
         return nullptr;
     }
 
     // Clone the font entry so that we can then set its style descriptors
     // from the userfont entry rather than the actual font.
 
     // Ensure existence of mFTFace in the original entry
-    data.mFontEntry->CairoFontFace();
-    if (!data.mFontEntry->mFTFace) {
+    fontEntry->CairoFontFace();
+    if (!fontEntry->mFTFace) {
         return nullptr;
     }
 
     FT2FontEntry* fe =
-        FT2FontEntry::CreateFontEntry(data.mFontEntry->mFTFace,
-                                      data.mFontEntry->mFilename.get(),
-                                      data.mFontEntry->mFTFontIndex,
-                                      data.mFontEntry->Name(), nullptr);
+        FT2FontEntry::CreateFontEntry(fontEntry->mFTFace,
+                                      fontEntry->mFilename.get(),
+                                      fontEntry->mFTFontIndex,
+                                      fontEntry->Name(), nullptr);
     if (fe) {
         fe->mItalic = aItalic;
         fe->mWeight = aWeight;
         fe->mStretch = aStretch;
         fe->mIsLocalUserFont = true;
     }
 
     return fe;
@@ -1564,26 +1544,20 @@ gfxFT2FontList::MakePlatformFont(const n
 {
     // The FT2 font needs the font data to persist, so we do NOT free it here
     // but instead pass ownership to the font entry.
     // Deallocation will happen later, when the font face is destroyed.
     return FT2FontEntry::CreateFontEntry(aFontName, aWeight, aStretch,
                                          aItalic, aFontData, aLength);
 }
 
-static PLDHashOperator
-AppendFamily(nsStringHashKey::KeyType aKey,
-             nsRefPtr<gfxFontFamily>& aFamily,
-             void* aUserArg)
-{
-    nsTArray<nsRefPtr<gfxFontFamily> > * familyArray =
-        reinterpret_cast<nsTArray<nsRefPtr<gfxFontFamily>>*>(aUserArg);
-
-    familyArray->AppendElement(aFamily);
-    return PL_DHASH_NEXT;
-}
-
 void
 gfxFT2FontList::GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray)
 {
-    mFontFamilies.Enumerate(AppendFamily, &aFamilyArray);
-    mHiddenFontFamilies.Enumerate(AppendFamily, &aFamilyArray);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        aFamilyArray.AppendElement(family);
+    }
+    for (auto iter = mHiddenFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        aFamilyArray.AppendElement(family);
+    }
 }
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -423,17 +423,17 @@ LookupAlternateValues(gfxFontFeatureValu
 
 /* static */ void
 gfxFontShaper::MergeFontFeatures(
     const gfxFontStyle *aStyle,
     const nsTArray<gfxFontFeature>& aFontFeatures,
     bool aDisableLigatures,
     const nsAString& aFamilyName,
     bool aAddSmallCaps,
-    PLDHashOperator (*aHandleFeature)(const uint32_t&, uint32_t&, void*),
+    void (*aHandleFeature)(const uint32_t&, uint32_t&, void*),
     void* aHandleFeatureData)
 {
     uint32_t numAlts = aStyle->alternateValues.Length();
     const nsTArray<gfxFontFeature>& styleRuleFeatures =
         aStyle->featureSettings;
 
     // Bail immediately if nothing to do, which is the common case.
     if (styleRuleFeatures.IsEmpty() &&
@@ -525,17 +525,19 @@ gfxFontShaper::MergeFontFeatures(
     // add feature values from style rules
     count = styleRuleFeatures.Length();
     for (i = 0; i < count; i++) {
         const gfxFontFeature& feature = styleRuleFeatures.ElementAt(i);
         mergedFeatures.Put(feature.mTag, feature.mValue);
     }
 
     if (mergedFeatures.Count() != 0) {
-        mergedFeatures.Enumerate(aHandleFeature, aHandleFeatureData);
+        for (auto iter = mergedFeatures.Iter(); !iter.Done(); iter.Next()) {
+            aHandleFeature(iter.Key(), iter.Data(), aHandleFeatureData);
+        }
     }
 }
 
 void
 gfxShapedText::SetupClusterBoundaries(uint32_t        aOffset,
                                       const char16_t *aString,
                                       uint32_t        aLength)
 {
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -631,18 +631,18 @@ public:
     gfxFont *GetFont() const { return mFont; }
 
     static void
     MergeFontFeatures(const gfxFontStyle *aStyle,
                       const nsTArray<gfxFontFeature>& aFontFeatures,
                       bool aDisableLigatures,
                       const nsAString& aFamilyName,
                       bool aAddSmallCaps,
-                      PLDHashOperator (*aHandleFeature)(const uint32_t&,
-                                                        uint32_t&, void*),
+                      void (*aHandleFeature)(const uint32_t&,
+                                             uint32_t&, void*),
                       void* aHandleFeatureData);
 
 protected:
     // the font this shaper is working with. The font owns a nsAutoPtr reference
     // to this object, and will destroy it before it dies. Thus, mFont will always
     // be valid.
     gfxFont* MOZ_NON_OWNING_REF mFont;
 };
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -141,23 +141,16 @@ gfxFontEntry::gfxFontEntry(const nsAStri
     mHBFace(nullptr),
     mGrFace(nullptr),
     mGrFaceRefCnt(0)
 {
     memset(&mDefaultSubSpaceFeatures, 0, sizeof(mDefaultSubSpaceFeatures));
     memset(&mNonDefaultSubSpaceFeatures, 0, sizeof(mNonDefaultSubSpaceFeatures));
 }
 
-static PLDHashOperator
-DestroyHBSet(const uint32_t& aTag, hb_set_t*& aSet, void *aUserArg)
-{
-    hb_set_destroy(aSet);
-    return PL_DHASH_NEXT;
-}
-
 gfxFontEntry::~gfxFontEntry()
 {
     if (mCOLR) {
         hb_blob_destroy(mCOLR);
     }
 
     if (mCPAL) {
         hb_blob_destroy(mCPAL);
@@ -165,17 +158,20 @@ gfxFontEntry::~gfxFontEntry()
 
     // For downloaded fonts, we need to tell the user font cache that this
     // entry is being deleted.
     if (mIsDataUserFont) {
         gfxUserFontSet::UserFontCache::ForgetFont(this);
     }
 
     if (mFeatureInputs) {
-        mFeatureInputs->Enumerate(DestroyHBSet, nullptr);
+        for (auto iter = mFeatureInputs->Iter(); !iter.Done(); iter.Next()) {
+            hb_set_t*& set = iter.Data();
+            hb_set_destroy(set);
+        }
     }
 
     // By the time the entry is destroyed, all font instances that were
     // using it should already have been deleted, and so the HB and/or Gr
     // face objects should have been released.
     MOZ_ASSERT(!mHBFace);
     MOZ_ASSERT(!mGrFaceInitialized);
 }
--- a/gfx/thebes/gfxGraphiteShaper.cpp
+++ b/gfx/thebes/gfxGraphiteShaper.cpp
@@ -67,26 +67,25 @@ MakeGraphiteLangTag(uint32_t aTag)
     return grLangTag;
 }
 
 struct GrFontFeatures {
     gr_face        *mFace;
     gr_feature_val *mFeatures;
 };
 
-static PLDHashOperator
+static void
 AddFeature(const uint32_t& aTag, uint32_t& aValue, void *aUserArg)
 {
     GrFontFeatures *f = static_cast<GrFontFeatures*>(aUserArg);
 
     const gr_feature_ref* fref = gr_face_find_fref(f->mFace, aTag);
     if (fref) {
         gr_fref_set_feature_value(fref, aValue, f->mFeatures);
     }
-    return PL_DHASH_NEXT;
 }
 
 bool
 gfxGraphiteShaper::ShapeText(gfxContext      *aContext,
                              const char16_t *aText,
                              uint32_t         aOffset,
                              uint32_t         aLength,
                              int32_t          aScript,
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp
+++ b/gfx/thebes/gfxHarfBuzzShaper.cpp
@@ -1219,26 +1219,25 @@ HBUnicodeDecompose(hb_unicode_funcs_t *u
 
 #else // no ICU available, use the old nsUnicodeNormalizer
 
     return nsUnicodeNormalizer::DecomposeNonRecursively(ab, a, b);
 
 #endif
 }
 
-static PLDHashOperator
+static void
 AddOpenTypeFeature(const uint32_t& aTag, uint32_t& aValue, void *aUserArg)
 {
     nsTArray<hb_feature_t>* features = static_cast<nsTArray<hb_feature_t>*> (aUserArg);
 
     hb_feature_t feat = { 0, 0, 0, UINT_MAX };
     feat.tag = aTag;
     feat.value = aValue;
     features->AppendElement(feat);
-    return PL_DHASH_NEXT;
 }
 
 /*
  * gfxFontShaper override to initialize the text run using HarfBuzz
  */
 
 static hb_font_funcs_t * sHBFontFuncs = nullptr;
 static hb_unicode_funcs_t * sHBUnicodeFuncs = nullptr;
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -232,144 +232,103 @@ gfxPlatformFontList::InitFontList()
 
 void
 gfxPlatformFontList::GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult)
 {
     aResult = aKeyName;
     ToLowerCase(aResult);
 }
 
-struct InitOtherNamesData {
-    InitOtherNamesData(gfxPlatformFontList *aFontList,
-                       TimeStamp aStartTime)
-        : mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false)
-    {}
+#define OTHERNAMES_TIMEOUT 200
 
-    gfxPlatformFontList *mFontList;
-    TimeStamp mStartTime;
-    bool mTimedOut;
-};
-
-void 
+void
 gfxPlatformFontList::InitOtherFamilyNames()
 {
     if (mOtherFamilyNamesInitialized) {
         return;
     }
 
     TimeStamp start = TimeStamp::Now();
-
-    // iterate over all font families and read in other family names
-    InitOtherNamesData otherNamesData(this, start);
+    bool timedOut = false;
 
-    mFontFamilies.Enumerate(gfxPlatformFontList::InitOtherFamilyNamesProc,
-                            &otherNamesData);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        family->ReadOtherFamilyNames(this);
+        TimeDuration elapsed = TimeStamp::Now() - start;
+        if (elapsed.ToMilliseconds() > OTHERNAMES_TIMEOUT) {
+            timedOut = true;
+            break;
+        }
+    }
 
-    if (!otherNamesData.mTimedOut) {
+    if (!timedOut) {
         mOtherFamilyNamesInitialized = true;
     }
     TimeStamp end = TimeStamp::Now();
     Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES,
                                    start, end);
 
     if (LOG_FONTINIT_ENABLED()) {
         TimeDuration elapsed = end - start;
         LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms %s",
                       elapsed.ToMilliseconds(),
-                      (otherNamesData.mTimedOut ? "timeout" : "")));
+                      (timedOut ? "timeout" : "")));
     }
 }
 
-#define OTHERNAMES_TIMEOUT 200
-
-PLDHashOperator
-gfxPlatformFontList::InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey,
-                                              nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                                              void* userArg)
-{
-    InitOtherNamesData *data = static_cast<InitOtherNamesData*>(userArg);
-
-    aFamilyEntry->ReadOtherFamilyNames(data->mFontList);
-    TimeDuration elapsed = TimeStamp::Now() - data->mStartTime;
-    if (elapsed.ToMilliseconds() > OTHERNAMES_TIMEOUT) {
-        data->mTimedOut = true;
-        return PL_DHASH_STOP;
-    }
-    return PL_DHASH_NEXT;
-}
- 
-struct ReadFaceNamesData {
-    ReadFaceNamesData(gfxPlatformFontList *aFontList, TimeStamp aStartTime)
-        : mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false),
-          mFirstChar(0)
-    {}
-
-    gfxPlatformFontList *mFontList;
-    TimeStamp mStartTime;
-    bool mTimedOut;
-
-    // if mFirstChar is not 0, only load facenames for families
-    // that start with this character
-    char16_t mFirstChar;
-};
+// time limit for loading facename lists (ms)
+#define NAMELIST_TIMEOUT  200
 
 gfxFontEntry*
 gfxPlatformFontList::SearchFamiliesForFaceName(const nsAString& aFaceName)
 {
     TimeStamp start = TimeStamp::Now();
+    bool timedOut = false;
+    // if mFirstChar is not 0, only load facenames for families
+    // that start with this character
+    char16_t firstChar = 0;
     gfxFontEntry *lookup = nullptr;
 
-    ReadFaceNamesData faceNameListsData(this, start);
+    // iterate over familes starting with the same letter
+    firstChar = ToLowerCase(aFaceName.CharAt(0));
+
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsStringHashKey::KeyType key = iter.Key();
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
 
-    // iterate over familes starting with the same letter
-    faceNameListsData.mFirstChar = ToLowerCase(aFaceName.CharAt(0));
-    mFontFamilies.Enumerate(gfxPlatformFontList::ReadFaceNamesProc,
-                            &faceNameListsData);
+        // when filtering, skip names that don't start with the filter character
+        if (firstChar && ToLowerCase(key.CharAt(0)) != firstChar) {
+            continue;
+        }
+
+        family->ReadFaceNames(this, NeedFullnamePostscriptNames());
+
+        TimeDuration elapsed = TimeStamp::Now() - start;
+        if (elapsed.ToMilliseconds() > NAMELIST_TIMEOUT) {
+           timedOut = true;
+           break;
+        }
+    }
+
     lookup = FindFaceName(aFaceName);
 
     TimeStamp end = TimeStamp::Now();
     Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITFACENAMELISTS,
                                    start, end);
     if (LOG_FONTINIT_ENABLED()) {
         TimeDuration elapsed = end - start;
         LOG_FONTINIT(("(fontinit) SearchFamiliesForFaceName took %8.2f ms %s %s",
                       elapsed.ToMilliseconds(),
                       (lookup ? "found name" : ""),
-                      (faceNameListsData.mTimedOut ? "timeout" : "")));
+                      (timedOut ? "timeout" : "")));
     }
 
     return lookup;
 }
 
-// time limit for loading facename lists (ms)
-#define NAMELIST_TIMEOUT  200
-
-PLDHashOperator
-gfxPlatformFontList::ReadFaceNamesProc(nsStringHashKey::KeyType aKey,
-                                       nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                                       void* userArg)
-{
-    ReadFaceNamesData *data = static_cast<ReadFaceNamesData*>(userArg);
-    gfxPlatformFontList *fc = data->mFontList;
-
-    // when filtering, skip names that don't start with the filter character
-    if (data->mFirstChar && ToLowerCase(aKey.CharAt(0)) != data->mFirstChar) {
-        return PL_DHASH_NEXT;
-    }
-
-    aFamilyEntry->ReadFaceNames(fc, fc->NeedFullnamePostscriptNames());
-
-    TimeDuration elapsed = TimeStamp::Now() - data->mStartTime;
-    if (elapsed.ToMilliseconds() > NAMELIST_TIMEOUT) {
-        data->mTimedOut = true;
-        return PL_DHASH_STOP;
-    }
-    return PL_DHASH_NEXT;
-}
-
 gfxFontEntry*
 gfxPlatformFontList::FindFaceName(const nsAString& aFaceName)
 {
     gfxFontEntry *lookup;
 
     // lookup in name lookup tables, return null if not found
     if (mExtraNames &&
         ((lookup = mExtraNames->mPostscriptNames.GetWeak(aFaceName)) ||
@@ -444,94 +403,59 @@ gfxPlatformFontList::LoadBadUnderlineLis
 
 void
 gfxPlatformFontList::UpdateFontList()
 {
     InitFontList();
     RebuildLocalFonts();
 }
 
-struct FontListData {
-    FontListData(nsIAtom *aLangGroup,
-                 const nsACString& aGenericFamily,
-                 nsTArray<nsString>& aListOfFonts) :
-        mLangGroup(aLangGroup), mGenericFamily(aGenericFamily),
-        mListOfFonts(aListOfFonts) {}
-    nsIAtom *mLangGroup;
-    const nsACString& mGenericFamily;
-    nsTArray<nsString>& mListOfFonts;
-};
-
-PLDHashOperator
-gfxPlatformFontList::HashEnumFuncForFamilies(nsStringHashKey::KeyType aKey,
-                                             nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                                             void *aUserArg)
-{
-    FontListData *data = static_cast<FontListData*>(aUserArg);
-
-    // use the first variation for now.  This data should be the same
-    // for all the variations and should probably be moved up to
-    // the Family
-    gfxFontStyle style;
-    style.language = data->mLangGroup;
-    bool needsBold;
-    nsRefPtr<gfxFontEntry> aFontEntry = aFamilyEntry->FindFontForStyle(style, needsBold);
-    NS_ASSERTION(aFontEntry, "couldn't find any font entry in family");
-    if (!aFontEntry)
-        return PL_DHASH_NEXT;
-
-    /* skip symbol fonts */
-    if (aFontEntry->IsSymbolFont())
-        return PL_DHASH_NEXT;
-
-    if (aFontEntry->SupportsLangGroup(data->mLangGroup) &&
-        aFontEntry->MatchesGenericFamily(data->mGenericFamily)) {
-        nsAutoString localizedFamilyName;
-        aFamilyEntry->LocalizedName(localizedFamilyName);
-        data->mListOfFonts.AppendElement(localizedFamilyName);
-    }
-
-    return PL_DHASH_NEXT;
-}
-
 void
 gfxPlatformFontList::GetFontList(nsIAtom *aLangGroup,
                                  const nsACString& aGenericFamily,
                                  nsTArray<nsString>& aListOfFonts)
 {
-    FontListData data(aLangGroup, aGenericFamily, aListOfFonts);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        // use the first variation for now.  This data should be the same
+        // for all the variations and should probably be moved up to
+        // the Family
+        gfxFontStyle style;
+        style.language = aLangGroup;
+        bool needsBold;
+        nsRefPtr<gfxFontEntry> fontEntry = family->FindFontForStyle(style, needsBold);
+        NS_ASSERTION(fontEntry, "couldn't find any font entry in family");
+        if (!fontEntry) {
+            continue;
+        }
 
-    mFontFamilies.Enumerate(gfxPlatformFontList::HashEnumFuncForFamilies, &data);
+        /* skip symbol fonts */
+        if (fontEntry->IsSymbolFont()) {
+            continue;
+        }
+
+        if (fontEntry->SupportsLangGroup(aLangGroup) &&
+            fontEntry->MatchesGenericFamily(aGenericFamily)) {
+            nsAutoString localizedFamilyName;
+            family->LocalizedName(localizedFamilyName);
+            aListOfFonts.AppendElement(localizedFamilyName);
+        }
+    }
 
     aListOfFonts.Sort();
     aListOfFonts.Compact();
 }
 
-struct FontFamilyListData {
-    explicit FontFamilyListData(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray) 
-        : mFamilyArray(aFamilyArray)
-    {}
-
-    static PLDHashOperator AppendFamily(nsStringHashKey::KeyType aKey,
-                                        nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                                        void *aUserArg)
-    {
-        FontFamilyListData *data = static_cast<FontFamilyListData*>(aUserArg);
-        data->mFamilyArray.AppendElement(aFamilyEntry);
-        return PL_DHASH_NEXT;
-    }
-
-    nsTArray<nsRefPtr<gfxFontFamily> >& mFamilyArray;
-};
-
 void
 gfxPlatformFontList::GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray)
 {
-    FontFamilyListData data(aFamilyArray);
-    mFontFamilies.Enumerate(FontFamilyListData::AppendFamily, &data);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        aFamilyArray.AppendElement(family);
+    }
 }
 
 gfxFontEntry*
 gfxPlatformFontList::SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
                                            int32_t aRunScript,
                                            const gfxFontStyle* aStyle)
  {
     gfxFontEntry* fontEntry = nullptr;
@@ -611,28 +535,16 @@ gfxPlatformFontList::SystemFindFontForCh
 
     // track the script for which fallback occurred (incremented one make it
     // 1-based)
     Telemetry::Accumulate(Telemetry::SYSTEM_FONT_FALLBACK_SCRIPT, aRunScript + 1);
 
     return fontEntry;
 }
 
-PLDHashOperator 
-gfxPlatformFontList::FindFontForCharProc(nsStringHashKey::KeyType aKey, nsRefPtr<gfxFontFamily>& aFamilyEntry,
-     void *userArg)
-{
-    GlobalFontMatch *data = static_cast<GlobalFontMatch*>(userArg);
-
-    // evaluate all fonts in this family for a match
-    aFamilyEntry->FindFontForChar(data);
-
-    return PL_DHASH_NEXT;
-}
-
 #define NUM_FALLBACK_FONTS        8
 
 gfxFontEntry*
 gfxPlatformFontList::CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
                                         int32_t aRunScript,
                                         const gfxFontStyle* aMatchStyle,
                                         gfxFontFamily** aMatchedFamily)
 {
@@ -672,17 +584,21 @@ gfxPlatformFontList::GlobalFontFallback(
                                         const gfxFontStyle* aMatchStyle,
                                         uint32_t& aCmapCount,
                                         gfxFontFamily** aMatchedFamily)
 {
     // otherwise, try to find it among local fonts
     GlobalFontMatch data(aCh, aRunScript, aMatchStyle);
 
     // iterate over all font families to find a font that support the character
-    mFontFamilies.Enumerate(gfxPlatformFontList::FindFontForCharProc, &data);
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+      nsRefPtr<gfxFontFamily>& family = iter.Data();
+      // evaluate all fonts in this family for a match
+      family->FindFontForChar(&data);
+    }
 
     aCmapCount = data.mCmapsTested;
     *aMatchedFamily = data.mMatchedFamily;
 
     return data.mBestMatch;
 }
 
 #ifdef XP_WIN
@@ -880,32 +796,26 @@ gfxPlatformFontList::RemoveCmap(const gf
     // cmap needs to match the entry *and* be the same ptr before removing
     CharMapHashKey *found =
         mSharedCmaps.GetEntry(const_cast<gfxCharacterMap*>(aCharMap));
     if (found && found->GetKey() == aCharMap) {
         mSharedCmaps.RemoveEntry(const_cast<gfxCharacterMap*>(aCharMap));
     }
 }
 
-static PLDHashOperator AppendFamilyToList(nsStringHashKey::KeyType aKey,
-                                          nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                                          void *aUserArg)
+void
+gfxPlatformFontList::GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames)
 {
-    nsTArray<nsString> *familyNames = static_cast<nsTArray<nsString> *>(aUserArg);
-    familyNames->AppendElement(aFamilyEntry->Name());
-    return PL_DHASH_NEXT;
+    for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
+        nsRefPtr<gfxFontFamily>& family = iter.Data();
+        aFontFamilyNames.AppendElement(family->Name());
+    }
 }
 
 void
-gfxPlatformFontList::GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames)
-{
-    mFontFamilies.Enumerate(AppendFamilyToList, &aFontFamilyNames);
-}
-
-void 
 gfxPlatformFontList::InitLoader()
 {
     GetFontFamilyNames(mFontInfo->mFontFamiliesToLoad);
     mStartIndex = 0;
     mNumFamilies = mFontInfo->mFontFamiliesToLoad.Length();
     memset(&(mFontInfo->mLoadStats), 0, sizeof(mFontInfo->mLoadStats));
 }
 
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -207,20 +207,16 @@ protected:
         NS_DECL_ISUPPORTS
         NS_DECL_NSIMEMORYREPORTER
     };
 
     explicit gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
 
     static gfxPlatformFontList *sPlatformFontList;
 
-    static PLDHashOperator FindFontForCharProc(nsStringHashKey::KeyType aKey,
-                                               nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                                               void* userArg);
-
     // Lookup family name in global family list without substitutions or
     // localized family name lookup. Used for common font fallback families.
     gfxFontFamily* FindFamilyByCanonicalName(const nsAString& aFamily) {
         nsAutoString key;
         gfxFontFamily *familyEntry;
         GenerateFontListKey(aFamily, key);
         if ((familyEntry = mFontFamilies.GetWeak(key))) {
             return CheckFamily(familyEntry);
@@ -246,31 +242,21 @@ protected:
     virtual bool UsesSystemFallback() { return false; }
 
     // verifies that a family contains a non-zero font count
     gfxFontFamily* CheckFamily(gfxFontFamily *aFamily);
 
     // initialize localized family names
     void InitOtherFamilyNames();
 
-    static PLDHashOperator
-    InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey,
-                             nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                             void* userArg);
-
     // search through font families, looking for a given name, initializing
     // facename lists along the way. first checks all families with names
     // close to face name, then searchs all families if not found.
     gfxFontEntry* SearchFamiliesForFaceName(const nsAString& aFaceName);
 
-    static PLDHashOperator
-    ReadFaceNamesProc(nsStringHashKey::KeyType aKey,
-                      nsRefPtr<gfxFontFamily>& aFamilyEntry,
-                      void* userArg);
-
     // helper method for finding fullname/postscript names in facename lists
     gfxFontEntry* FindFaceName(const nsAString& aFaceName);
 
     // look up a font by name, for cases where platform font list
     // maintains explicit mappings of fullname/psname ==> font
     virtual gfxFontEntry* LookupInFaceNameLists(const nsAString& aFontName);
 
     // commonly used fonts for which the name table should be loaded at startup