Bug 734008 - DeCOMtaminate nsILanguageAtomService, make it a non-refcounted singleton and clean up various call sites. r=m_kato
authorJonathan Kew <jkew@mozilla.com>
Fri, 03 Apr 2015 21:39:23 +0200
changeset 408193 eaaf2913c680334b0426a93b7c27b0280f2a7f67
parent 408192 59b80bc77946ed59c733bdff2e364cf624f6611b
child 408194 5ef43ba36c8c519ed91d5136389cfa89d92f05a2
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs734008
milestone55.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 734008 - DeCOMtaminate nsILanguageAtomService, make it a non-refcounted singleton and clean up various call sites. r=m_kato
gfx/src/nsDeviceContext.cpp
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
gfx/thebes/gfxFontEntry.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatformFontList.cpp
gfx/thebes/gfxPlatformFontList.h
gfx/thebes/gfxTextRun.cpp
gfx/thebes/gfxTextRun.h
intl/build/nsI18nModule.cpp
intl/locale/moz.build
intl/locale/nsILanguageAtomService.h
intl/locale/nsLanguageAtomService.cpp
intl/locale/nsLanguageAtomService.h
intl/locale/nsLocaleConstructors.h
layout/base/StaticPresData.cpp
layout/base/StaticPresData.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/style/ServoStyleSet.cpp
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -19,17 +19,17 @@
 #include "mozilla/mozalloc.h"           // for operator new
 #include "nsCRT.h"                      // for nsCRT
 #include "nsDebug.h"                    // for NS_NOTREACHED, NS_ASSERTION, etc
 #include "nsFont.h"                     // for nsFont
 #include "nsFontMetrics.h"              // for nsFontMetrics
 #include "nsIAtom.h"                    // for nsIAtom, NS_Atomize
 #include "nsID.h"
 #include "nsIDeviceContextSpec.h"       // for nsIDeviceContextSpec
-#include "nsILanguageAtomService.h"     // for nsILanguageAtomService, etc
+#include "nsLanguageAtomService.h"      // for nsLanguageAtomService
 #include "nsIObserver.h"                // for nsIObserver, etc
 #include "nsIObserverService.h"         // for nsIObserverService
 #include "nsIScreen.h"                  // for nsIScreen
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsISupportsUtils.h"           // for NS_ADDREF, NS_RELEASE
 #include "nsIWidget.h"                  // for nsIWidget, NS_NATIVE_WINDOW
 #include "nsRect.h"                     // for nsRect
 #include "nsServiceManagerUtils.h"      // for do_GetService
@@ -80,21 +80,17 @@ nsFontCache::Init(nsDeviceContext* aCont
 {
     mContext = aContext;
     // register as a memory-pressure observer to free font resources
     // in low-memory situations.
     nsCOMPtr<nsIObserverService> obs = GetObserverService();
     if (obs)
         obs->AddObserver(this, "memory-pressure", false);
 
-    nsCOMPtr<nsILanguageAtomService> langService;
-    langService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
-    if (langService) {
-        mLocaleLanguage = langService->GetLocaleLanguage();
-    }
+    mLocaleLanguage = nsLanguageAtomService::GetService()->GetLocaleLanguage();
     if (!mLocaleLanguage) {
         mLocaleLanguage = NS_Atomize("x-western");
     }
 }
 
 void
 nsFontCache::Destroy()
 {
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -12,17 +12,16 @@
 #include "gfxFontFamilyList.h"
 #include "gfxFT2Utils.h"
 #include "gfxPlatform.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/TimeStamp.h"
 #include "nsGkAtoms.h"
-#include "nsILanguageAtomService.h"
 #include "nsUnicodeProperties.h"
 #include "nsUnicodeRange.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsCharSeparatedTokenizer.h"
 
 #include "mozilla/gfx/HelpersCairo.h"
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -217,18 +217,16 @@ public:
                       gfxFontEntry *aFontEntry,
                       const gfxFontStyle *aFontStyle,
                       bool aNeedsBold);
 
 protected:
     virtual ~gfxFontconfigFont();
 };
 
-class nsILanguageAtomService;
-
 class gfxFcPlatformFontList : public gfxPlatformFontList {
 public:
     gfxFcPlatformFontList();
 
     static gfxFcPlatformFontList* PlatformFontList() {
         return static_cast<gfxFcPlatformFontList*>(sPlatformFontList);
     }
 
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -3,19 +3,16 @@
  * 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/. */
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include "mozilla/Logging.h"
 
-#include "nsServiceManagerUtils.h"
-#include "nsILanguageAtomService.h"
-
 #include "gfxFontEntry.h"
 #include "gfxTextRun.h"
 #include "gfxPlatform.h"
 #include "nsGkAtoms.h"
 
 #include "gfxTypes.h"
 #include "gfxContext.h"
 #include "gfxFontConstants.h"
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -863,17 +863,16 @@ gfxPlatform::Shutdown()
       return;
     }
 
     MOZ_ASSERT(!sLayersIPCIsUp);
 
     // These may be called before the corresponding subsystems have actually
     // started up. That's OK, they can handle it.
     gfxFontCache::Shutdown();
-    gfxFontGroup::Shutdown();
     gfxGradientCache::Shutdown();
     gfxAlphaBoxBlur::ShutdownBlurCache();
     gfxGraphiteShaper::Shutdown();
     gfxPlatformFontList::Shutdown();
     ShutdownTileCache();
 
     // Free the various non-null transforms and loaded profiles
     ShutdownCMS();
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -183,16 +183,18 @@ gfxPlatformFontList::gfxPlatformFontList
 {
     mOtherFamilyNamesInitialized = false;
 
     if (aNeedFullnamePostscriptNames) {
         mExtraNames = MakeUnique<ExtraNames>();
     }
     mFaceNameListsInitialized = false;
 
+    mLangService = nsLanguageAtomService::GetService();
+
     LoadBadUnderlineList();
 
     // pref changes notification setup
     NS_ASSERTION(!gFontListPrefObserver,
                  "There has been font list pref observer already");
     gFontListPrefObserver = new gfxFontListPrefObserver();
     NS_ADDREF(gFontListPrefObserver);
     Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs);
@@ -1236,41 +1238,23 @@ void
 gfxPlatformFontList::GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames)
 {
     for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
         RefPtr<gfxFontFamily>& family = iter.Data();
         aFontFamilyNames.AppendElement(family->Name());
     }
 }
 
-void
-gfxPlatformFontList::InitLangService()
-{
-    if (!mLangService) {
-        mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
-    }
-}
-
-nsILanguageAtomService*
-gfxPlatformFontList::GetLangService()
-{
-    InitLangService();
-    NS_ASSERTION(mLangService, "no language service!");
-    return mLangService;
-}
-
 nsIAtom*
 gfxPlatformFontList::GetLangGroup(nsIAtom* aLanguage)
 {
     // map lang ==> langGroup
     nsIAtom *langGroup = nullptr;
     if (aLanguage) {
-        nsresult rv;
-        nsILanguageAtomService* langService = GetLangService();
-        langGroup = langService->GetLanguageGroup(aLanguage, &rv);
+        langGroup = mLangService->GetLanguageGroup(aLanguage);
     }
     if (!langGroup) {
         langGroup = nsGkAtoms::Unicode;
     }
     return langGroup;
 }
 
 /* static */ const char*
@@ -1344,18 +1328,18 @@ const MozLangGroupData MozLangGroups[] =
 bool
 gfxPlatformFontList::TryLangForGroup(const nsACString& aOSLang,
                                        nsIAtom* aLangGroup,
                                        nsACString& aFcLang)
 {
     // Truncate at '.' or '@' from aOSLang, and convert '_' to '-'.
     // aOSLang is in the form "language[_territory][.codeset][@modifier]".
     // fontconfig takes languages in the form "language-territory".
-    // nsILanguageAtomService takes languages in the form language-subtag,
-    // where subtag may be a territory.  fontconfig and nsILanguageAtomService
+    // nsLanguageAtomService takes languages in the form language-subtag,
+    // where subtag may be a territory.  fontconfig and nsLanguageAtomService
     // handle case-conversion for us.
     const char *pos, *end;
     aOSLang.BeginReading(pos);
     aOSLang.EndReading(end);
     aFcLang.Truncate();
     while (pos < end) {
         switch (*pos) {
             case '.':
@@ -1366,18 +1350,17 @@ gfxPlatformFontList::TryLangForGroup(con
                 aFcLang.Append('-');
                 break;
             default:
                 aFcLang.Append(*pos);
         }
         ++pos;
     }
 
-    nsILanguageAtomService* langService = GetLangService();
-    nsIAtom *atom = langService->LookupLanguage(aFcLang);
+    nsIAtom *atom = mLangService->LookupLanguage(aFcLang);
     return atom == aLangGroup;
 }
 
 void
 gfxPlatformFontList::GetSampleLangForGroup(nsIAtom* aLanguage,
                                              nsACString& aLangStr,
                                              bool aCheckEnvironment)
 {
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -16,17 +16,17 @@
 #include "gfxFontConstants.h"
 #include "gfxPlatform.h"
 #include "gfxFontFamilyList.h"
 
 #include "nsIMemoryReporter.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/RangedArray.h"
-#include "nsILanguageAtomService.h"
+#include "nsLanguageAtomService.h"
 
 class CharMapHashKey : public PLDHashEntryHdr
 {
 public:
     typedef gfxCharacterMap* KeyType;
     typedef const gfxCharacterMap* KeyTypePointer;
 
     explicit CharMapHashKey(const gfxCharacterMap *aCharMap) :
@@ -117,19 +117,16 @@ public:
     nsresult InitFontList();
 
     virtual void GetFontList(nsIAtom *aLangGroup,
                              const nsACString& aGenericFamily,
                              nsTArray<nsString>& aListOfFonts);
 
     void UpdateFontList();
 
-    // Initialize the contained mLangService (for stylo, must be done in advance on main thread)
-    void InitLangService();
-
     virtual void ClearLangGroupPrefFonts();
 
     virtual void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily> >& aFamilyArray);
 
     gfxFontEntry*
     SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
                           Script aRunScript,
                           const gfxFontStyle* aStyle);
@@ -384,18 +381,16 @@ protected:
 
     // load the bad underline blacklist from pref.
     void LoadBadUnderlineList();
 
     void GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult);
 
     virtual void GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames);
 
-    nsILanguageAtomService* GetLangService();
-
     // helper function to map lang to lang group
     nsIAtom* GetLangGroup(nsIAtom* aLanguage);
 
     // helper method for finding an appropriate lang string
     bool TryLangForGroup(const nsACString& aOSLang, nsIAtom* aLangGroup,
                          nsACString& aLang);
 
     static const char* GetGenericName(mozilla::FontFamilyType aGenericType);
@@ -494,16 +489,17 @@ protected:
     uint32_t mNumFamilies;
 
     // xxx - info for diagnosing no default font aborts
     // see bugs 636957, 1070983, 1189129
     uint32_t mFontlistInitCount; // num times InitFontList called
 
     nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
 
-    nsCOMPtr<nsILanguageAtomService> mLangService;
+    nsLanguageAtomService* mLangService;
+
     nsTArray<uint32_t> mCJKPrefLangs;
     nsTArray<mozilla::FontFamilyType> mDefaultGenericsLangGroup;
 
     bool mFontFamilyWhitelistActive;
 };
 
 #endif /* GFXPLATFORMFONTLIST_H_ */
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -7,19 +7,16 @@
 #include "gfxTextRun.h"
 #include "gfxGlyphExtents.h"
 #include "gfxPlatformFontList.h"
 #include "gfxUserFontSet.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/SizePrintfMacros.h"
 #include "mozilla/Sprintf.h"
-#include "nsGkAtoms.h"
-#include "nsILanguageAtomService.h"
-#include "nsServiceManagerUtils.h"
 
 #include "gfxContext.h"
 #include "gfxFontConstants.h"
 #include "gfxFontMissingGlyphs.h"
 #include "gfxScriptItemizer.h"
 #include "nsUnicodeProperties.h"
 #include "nsUnicodeRange.h"
 #include "nsStyleConsts.h"
@@ -3415,24 +3412,16 @@ gfxFontGroup::WhichSystemFontSupportsCha
         RefPtr<gfxFont> font =
             fe->FindOrMakeFont(&mStyle, wantBold && !fe->IsBold());
         return font.forget();
     }
 
     return nullptr;
 }
 
-/*static*/ void
-gfxFontGroup::Shutdown()
-{
-    NS_IF_RELEASE(gLangService);
-}
-
-nsILanguageAtomService* gfxFontGroup::gLangService = nullptr;
-
 void
 gfxMissingFontRecorder::Flush()
 {
     static bool mNotifiedFontsInitialized = false;
     static uint32_t mNotifiedFonts[gfxMissingFontRecorder::kNumScriptBitsWords];
     if (!mNotifiedFontsInitialized) {
         memset(&mNotifiedFonts, 0, sizeof(mNotifiedFonts));
         mNotifiedFontsInitialized = true;
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -26,17 +26,17 @@
 #include <stdio.h>
 #endif
 
 class gfxContext;
 class gfxFontGroup;
 class gfxUserFontEntry;
 class gfxUserFontSet;
 class nsIAtom;
-class nsILanguageAtomService;
+class nsLanguageAtomService;
 class gfxMissingFontRecorder;
 
 namespace mozilla {
 class SVGContextPaint;
 enum class StyleHyphens : uint8_t;
 };
 
 /**
@@ -1241,18 +1241,16 @@ protected:
    // helper methods for looking up fonts
 
     // lookup and add a font with a given name (i.e. *not* a generic!)
     void AddPlatformFont(const nsAString& aName,
                          nsTArray<gfxFontFamily*>& aFamilyList);
 
     // do style selection and add entries to list
     void AddFamilyToFontList(gfxFontFamily* aFamily);
-
-    static nsILanguageAtomService* gLangService;
 };
 
 // A "missing font recorder" is to be used during text-run creation to keep
 // a record of any scripts encountered for which font coverage was lacking;
 // when Flush() is called, it sends a notification that front-end code can use
 // to download fonts on demand (or whatever else it wants to do).
 
 #define GFX_MISSING_FONTS_NOTIFY_PREF "gfx.missing_fonts.notify"
--- a/intl/build/nsI18nModule.cpp
+++ b/intl/build/nsI18nModule.cpp
@@ -54,17 +54,16 @@ NS_DEFINE_NAMED_CID(NS_UNICHARCATEGORY_C
 NS_DEFINE_NAMED_CID(NS_ENTITYCONVERTER_CID);
 NS_DEFINE_NAMED_CID(NS_SAVEASCHARSET_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODE_NORMALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLETEXTOVERRIDE_CID);
 NS_DEFINE_NAMED_CID(NS_LOCALESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATIONFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTABLEDATEFORMAT_CID);
-NS_DEFINE_NAMED_CID(NS_LANGUAGEATOMSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_PLATFORMCHARSET_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
 
 static const mozilla::Module::CIDEntry kIntlCIDs[] = {
     { &kMOZ_LOCALESERVICE_CID, false, nullptr, mozilla::intl::LocaleServiceConstructor },
     { &kMOZ_OSPREFERENCES_CID, false, nullptr, mozilla::intl::OSPreferencesConstructor },
     { &kNS_LBRK_CID, false, nullptr, nsJISx4051LineBreakerConstructor },
     { &kNS_WBRK_CID, false, nullptr, nsSampleWordBreakerConstructor },
@@ -74,17 +73,16 @@ static const mozilla::Module::CIDEntry k
     { &kNS_ENTITYCONVERTER_CID, false, nullptr, nsEntityConverterConstructor },
     { &kNS_SAVEASCHARSET_CID, false, nullptr, nsSaveAsCharsetConstructor },
     { &kNS_UNICODE_NORMALIZER_CID, false, nullptr, nsUnicodeNormalizerConstructor },
     { &kNS_STRINGBUNDLESERVICE_CID, false, nullptr, nsStringBundleServiceConstructor },
     { &kNS_STRINGBUNDLETEXTOVERRIDE_CID, false, nullptr, nsStringBundleTextOverrideConstructor },
     { &kNS_LOCALESERVICE_CID, false, nullptr, CreateLocaleService },
     { &kNS_COLLATIONFACTORY_CID, false, nullptr, nsCollationFactoryConstructor },
     { &kNS_SCRIPTABLEDATEFORMAT_CID, false, nullptr, NS_NewScriptableDateFormat },
-    { &kNS_LANGUAGEATOMSERVICE_CID, false, nullptr, nsLanguageAtomServiceConstructor },
     { &kNS_PLATFORMCHARSET_CID, false, nullptr, nsPlatformCharsetConstructor },
     { &kNS_COLLATION_CID, false, nullptr, nsCollationConstructor },
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
     { MOZ_LOCALESERVICE_CONTRACTID, &kMOZ_LOCALESERVICE_CID },
     { MOZ_OSPREFERENCES_CONTRACTID, &kMOZ_OSPREFERENCES_CID },
@@ -96,17 +94,16 @@ static const mozilla::Module::ContractID
     { NS_ENTITYCONVERTER_CONTRACTID, &kNS_ENTITYCONVERTER_CID },
     { NS_SAVEASCHARSET_CONTRACTID, &kNS_SAVEASCHARSET_CID },
     { NS_UNICODE_NORMALIZER_CONTRACTID, &kNS_UNICODE_NORMALIZER_CID },
     { NS_STRINGBUNDLE_CONTRACTID, &kNS_STRINGBUNDLESERVICE_CID },
     { NS_STRINGBUNDLETEXTOVERRIDE_CONTRACTID, &kNS_STRINGBUNDLETEXTOVERRIDE_CID },
     { NS_LOCALESERVICE_CONTRACTID, &kNS_LOCALESERVICE_CID },
     { NS_COLLATIONFACTORY_CONTRACTID, &kNS_COLLATIONFACTORY_CID },
     { NS_SCRIPTABLEDATEFORMAT_CONTRACTID, &kNS_SCRIPTABLEDATEFORMAT_CID },
-    { NS_LANGUAGEATOMSERVICE_CONTRACTID, &kNS_LANGUAGEATOMSERVICE_CID },
     { NS_PLATFORMCHARSET_CONTRACTID, &kNS_PLATFORMCHARSET_CID },
     { NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID },
     { nullptr }
 };
 
 static const mozilla::Module kIntlModule = {
     mozilla::Module::kVersion,
     kIntlCIDs,
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -28,18 +28,18 @@ XPIDL_SOURCES += [
     'nsIScriptableDateFormat.idl',
 ]
 
 XPIDL_MODULE = 'locale'
 
 EXPORTS += [
     'DateTimeFormat.h',
     'nsCollationCID.h',
-    'nsILanguageAtomService.h',
     'nsIPlatformCharset.h',
+    'nsLanguageAtomService.h',
     'nsPosixLocale.h',
     'nsUConvPropertySearch.h',
     'nsWin32Locale.h',
 ]
 
 EXPORTS.mozilla.intl += [
     'LocaleService.h',
     'OSPreferences.h',
deleted file mode 100644
--- a/intl/locale/nsILanguageAtomService.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 nsILanguageAtomService_h_
-#define nsILanguageAtomService_h_
-
-/*
- * The nsILanguageAtomService provides a mapping from languages or charsets
- * to language groups, and access to the system locale language.
- */
-
-#include "nsISupports.h"
-#include "nsCOMPtr.h"
-#include "nsIAtom.h"
-
-#define NS_ILANGUAGEATOMSERVICE_IID \
-  {0xcb3892a0, 0x6a76, 0x461c, \
-    { 0xb0, 0x24, 0x23, 0x0e, 0xe3, 0xe0, 0x81, 0x1a }}
-
-#define NS_LANGUAGEATOMSERVICE_CONTRACTID \
-  "@mozilla.org/intl/nslanguageatomservice;1"
-
-class nsILanguageAtomService : public nsISupports
-{
- public: 
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILANGUAGEATOMSERVICE_IID)
-
-  virtual nsIAtom* LookupLanguage(const nsACString &aLanguage,
-                                  nsresult *aError = nullptr) = 0;
-  virtual already_AddRefed<nsIAtom>
-  LookupCharSet(const nsACString& aCharSet) = 0;
-
-  virtual nsIAtom* GetLocaleLanguage() = 0;
-
-  virtual nsIAtom* GetLanguageGroup(nsIAtom* aLanguage,
-                                    nsresult* aError = nullptr) = 0;
-
-  // Same as GetLanguageGroup, but will not cache anything
-  // and can be used from a different thread
-  virtual already_AddRefed<nsIAtom> GetUncachedLanguageGroup(nsIAtom* aLanguage,
-                                                             nsresult* aError = nullptr) const = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsILanguageAtomService,
-                              NS_ILANGUAGEATOMSERVICE_IID)
-
-#endif
--- a/intl/locale/nsLanguageAtomService.cpp
+++ b/intl/locale/nsLanguageAtomService.cpp
@@ -3,50 +3,54 @@
  * 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/. */
 
 #include "nsLanguageAtomService.h"
 #include "nsUConvPropertySearch.h"
 #include "nsUnicharUtils.h"
 #include "nsIAtom.h"
 #include "mozilla/ArrayUtils.h"
-#include "mozilla/Services.h"
 #include "mozilla/intl/OSPreferences.h"
-#include "nsServiceManagerUtils.h"
 #include "mozilla/dom/EncodingUtils.h"
+#include "mozilla/ClearOnShutdown.h"
 
 using namespace mozilla;
 using mozilla::intl::OSPreferences;
 
 static constexpr nsUConvProp kLangGroups[] = {
 #include "langGroups.properties.h"
 };
 
-NS_IMPL_ISUPPORTS(nsLanguageAtomService, nsILanguageAtomService)
-
-nsLanguageAtomService::nsLanguageAtomService()
+// static
+nsLanguageAtomService*
+nsLanguageAtomService::GetService()
 {
+  static UniquePtr<nsLanguageAtomService> gLangAtomService;
+  if (!gLangAtomService) {
+    gLangAtomService = MakeUnique<nsLanguageAtomService>();
+    ClearOnShutdown(&gLangAtomService);
+  }
+  return gLangAtomService.get();
 }
 
 nsIAtom*
-nsLanguageAtomService::LookupLanguage(const nsACString &aLanguage,
-                                      nsresult *aError)
+nsLanguageAtomService::LookupLanguage(const nsACString &aLanguage)
 {
   nsAutoCString lowered(aLanguage);
   ToLowerCase(lowered);
 
   nsCOMPtr<nsIAtom> lang = NS_Atomize(lowered);
-  return GetLanguageGroup(lang, aError);
+  return GetLanguageGroup(lang);
 }
 
 already_AddRefed<nsIAtom>
 nsLanguageAtomService::LookupCharSet(const nsACString& aCharSet)
 {
   nsAutoCString group;
-  mozilla::dom::EncodingUtils::LangGroupForEncoding(aCharSet, group);
+  dom::EncodingUtils::LangGroupForEncoding(aCharSet, group);
   return NS_Atomize(group);
 }
 
 nsIAtom*
 nsLanguageAtomService::GetLocaleLanguage()
 {
   do {
     if (!mLocaleLanguage) {
@@ -57,60 +61,51 @@ nsLanguageAtomService::GetLocaleLanguage
       mLocaleLanguage = NS_Atomize(locale);
     }
   } while (0);
 
   return mLocaleLanguage;
 }
 
 nsIAtom*
-nsLanguageAtomService::GetLanguageGroup(nsIAtom* aLanguage,
-                                        nsresult* aError)
+nsLanguageAtomService::GetLanguageGroup(nsIAtom *aLanguage)
 {
-  nsIAtom* retVal;
-
-  retVal = mLangToGroup.GetWeak(aLanguage);
+  nsIAtom *retVal = mLangToGroup.GetWeak(aLanguage);
 
   if (!retVal) {
     MOZ_ASSERT(NS_IsMainThread(), "Should not append to cache off main thread");
-    nsCOMPtr<nsIAtom> uncached = GetUncachedLanguageGroup(aLanguage, aError);
+    nsCOMPtr<nsIAtom> uncached = GetUncachedLanguageGroup(aLanguage);
     retVal = uncached.get();
 
     // The hashtable will keep an owning reference to the atom
     mLangToGroup.Put(aLanguage, uncached);
   }
 
   return retVal;
 }
 
 already_AddRefed<nsIAtom>
-nsLanguageAtomService::GetUncachedLanguageGroup(nsIAtom* aLanguage,
-                                                nsresult* aError) const
+nsLanguageAtomService::GetUncachedLanguageGroup(nsIAtom* aLanguage) const
 {
-  nsresult res = NS_OK;
-
   nsAutoCString langStr;
   aLanguage->ToUTF8String(langStr);
 
   nsAutoCString langGroupStr;
-  res = nsUConvPropertySearch::SearchPropertyValue(kLangGroups,
-                                                   ArrayLength(kLangGroups),
-                                                   langStr, langGroupStr);
+  nsresult res =
+    nsUConvPropertySearch::SearchPropertyValue(kLangGroups,
+                                               ArrayLength(kLangGroups),
+                                               langStr, langGroupStr);
   while (NS_FAILED(res)) {
     int32_t hyphen = langStr.RFindChar('-');
     if (hyphen <= 0) {
       langGroupStr.AssignLiteral("x-unicode");
       break;
     }
     langStr.Truncate(hyphen);
     res = nsUConvPropertySearch::SearchPropertyValue(kLangGroups,
                                                      ArrayLength(kLangGroups),
                                                      langStr, langGroupStr);
   }
 
   nsCOMPtr<nsIAtom> langGroup = NS_Atomize(langGroupStr);
 
-  if (aError) {
-    *aError = res;
-  }
-
   return langGroup.forget();
 }
--- a/intl/locale/nsLanguageAtomService.h
+++ b/intl/locale/nsLanguageAtomService.h
@@ -1,44 +1,34 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
+/*
+ * The nsILanguageAtomService provides a mapping from languages or charsets
+ * to language groups, and access to the system locale language.
+ */
+
+#ifndef nsLanguageAtomService_h_
+#define nsLanguageAtomService_h_
+
 #include "nsCOMPtr.h"
-#include "nsILanguageAtomService.h"
-#include "nsIStringBundle.h"
-#include "nsInterfaceHashtable.h"
 #include "nsIAtom.h"
-#include "nsUConvPropertySearch.h"
-#include "mozilla/Attributes.h"
+#include "nsInterfaceHashtable.h"
 
-#define NS_LANGUAGEATOMSERVICE_CID \
-  {0xB7C65853, 0x2996, 0x435E, {0x96, 0x54, 0xDC, 0xC1, 0x78, 0xAA, 0xB4, 0x8C}}
-
-class nsLanguageAtomService final : public nsILanguageAtomService
+class nsLanguageAtomService
 {
 public:
-  NS_DECL_ISUPPORTS
-
-  // nsILanguageAtomService
-  virtual nsIAtom*
-    LookupLanguage(const nsACString &aLanguage, nsresult *aError) override;
-
-  virtual already_AddRefed<nsIAtom>
-    LookupCharSet(const nsACString& aCharSet) override;
+  static nsLanguageAtomService* GetService();
 
-  virtual nsIAtom* GetLocaleLanguage() override;
-
-  virtual nsIAtom* GetLanguageGroup(nsIAtom* aLanguage,
-                                    nsresult* aError) override;
-  virtual already_AddRefed<nsIAtom> GetUncachedLanguageGroup(nsIAtom* aLanguage,
-                                                             nsresult* aError) const final;
-
-  nsLanguageAtomService();
+  nsIAtom* LookupLanguage(const nsACString &aLanguage);
+  already_AddRefed<nsIAtom> LookupCharSet(const nsACString& aCharSet);
+  nsIAtom* GetLocaleLanguage();
+  nsIAtom* GetLanguageGroup(nsIAtom* aLanguage);
+  already_AddRefed<nsIAtom> GetUncachedLanguageGroup(nsIAtom* aLanguage) const;
 
 private:
-  ~nsLanguageAtomService() { }
-
-protected:
   nsInterfaceHashtable<nsISupportsHashKey, nsIAtom> mLangToGroup;
   nsCOMPtr<nsIAtom> mLocaleLanguage;
 };
+
+#endif
--- a/intl/locale/nsLocaleConstructors.h
+++ b/intl/locale/nsLocaleConstructors.h
@@ -7,17 +7,16 @@
 #define nsLocaleConstructors_h__
 
 #include "nsCollation.h"
 #include "nsCollationCID.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsILocaleService.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsIServiceManager.h"
-#include "nsLanguageAtomService.h"
 #include "nsPlatformCharset.h"
 #include "LocaleService.h"
 #include "OSPreferences.h"
 
 #define NSLOCALE_MAKE_CTOR(ctor_, iface_, func_)          \
 static nsresult                                           \
 ctor_(nsISupports* aOuter, REFNSIID aIID, void** aResult) \
 {                                                         \
@@ -32,18 +31,16 @@ ctor_(nsISupports* aOuter, REFNSIID aIID
   }                                                       \
   return rv;                                              \
 }
 
 
 NSLOCALE_MAKE_CTOR(CreateLocaleService, nsILocaleService, NS_NewLocaleService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollation)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationFactory)
-//NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableDateTimeFormat)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLanguageAtomService)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPlatformCharset, Init)
 
 namespace mozilla {
 namespace intl {
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(LocaleService,
                                          LocaleService::GetInstanceAddRefed)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(OSPreferences,
                                          OSPreferences::GetInstanceAddRefed)
--- a/layout/base/StaticPresData.cpp
+++ b/layout/base/StaticPresData.cpp
@@ -32,17 +32,17 @@ StaticPresData*
 StaticPresData::Get()
 {
   MOZ_ASSERT(sSingleton);
   return sSingleton;
 }
 
 StaticPresData::StaticPresData()
 {
-  mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
+  mLangService = nsLanguageAtomService::GetService();
 
   mBorderWidthTable[NS_STYLE_BORDER_WIDTH_THIN] = nsPresContext::CSSPixelsToAppUnits(1);
   mBorderWidthTable[NS_STYLE_BORDER_WIDTH_MEDIUM] = nsPresContext::CSSPixelsToAppUnits(3);
   mBorderWidthTable[NS_STYLE_BORDER_WIDTH_THICK] = nsPresContext::CSSPixelsToAppUnits(5);
 }
 
 #define MAKE_FONT_PREF_KEY(_pref, _s0, _s1) \
  _pref.Assign(_s0); \
@@ -233,31 +233,29 @@ LangGroupFontPrefs::Initialize(nsIAtom* 
            font->sizeAdjust);
 #endif
   }
 }
 
 nsIAtom*
 StaticPresData::GetLangGroup(nsIAtom* aLanguage) const
 {
-  nsresult rv = NS_OK;
   nsIAtom* langGroupAtom = nullptr;
-  langGroupAtom = mLangService->GetLanguageGroup(aLanguage, &rv);
-  if (NS_FAILED(rv) || !langGroupAtom) {
+  langGroupAtom = mLangService->GetLanguageGroup(aLanguage);
+  if (!langGroupAtom) {
     langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
   }
   return langGroupAtom;
 }
 
 already_AddRefed<nsIAtom>
 StaticPresData::GetUncachedLangGroup(nsIAtom* aLanguage) const
 {
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIAtom> langGroupAtom = mLangService->GetUncachedLanguageGroup(aLanguage, &rv);
-  if (NS_FAILED(rv) || !langGroupAtom) {
+  nsCOMPtr<nsIAtom> langGroupAtom = mLangService->GetUncachedLanguageGroup(aLanguage);
+  if (!langGroupAtom) {
     langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
   }
   return langGroupAtom.forget();
 }
 
 const LangGroupFontPrefs*
 StaticPresData::GetFontPrefsForLangHelper(nsIAtom* aLanguage,
                                           const LangGroupFontPrefs* aPrefs) const
--- a/layout/base/StaticPresData.h
+++ b/layout/base/StaticPresData.h
@@ -7,17 +7,17 @@
 #ifndef mozilla_StaticPresData_h
 #define mozilla_StaticPresData_h
 
 #include "nsAutoPtr.h"
 #include "nsCoord.h"
 #include "nsCOMPtr.h"
 #include "nsFont.h"
 #include "nsIAtom.h"
-#include "nsILanguageAtomService.h"
+#include "nsLanguageAtomService.h"
 
 namespace mozilla {
 
 struct LangGroupFontPrefs {
   // Font sizes default to zero; they will be set in GetFontPreferences
   LangGroupFontPrefs()
     : mLangGroup(nullptr)
     , mMinimumFontSize(0)
@@ -161,16 +161,16 @@ public:
   }
 
   void ResetCachedFontPrefs() { mStaticLangGroupFontPrefs.Reset(); }
 
 private:
   StaticPresData();
   ~StaticPresData() {}
 
-  nsCOMPtr<nsILanguageAtomService> mLangService;
+  nsLanguageAtomService* mLangService;
   nscoord mBorderWidthTable[3];
   LangGroupFontPrefs mStaticLangGroupFontPrefs;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_StaticPresData_h
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -20,17 +20,17 @@
 #include "nsIContentViewer.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/StyleSetHandle.h"
 #include "mozilla/StyleSetHandleInlines.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsIDocument.h"
 #include "nsIPrintSettings.h"
-#include "nsILanguageAtomService.h"
+#include "nsLanguageAtomService.h"
 #include "mozilla/LookAndFeel.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsThreadUtils.h"
 #include "nsFrameManager.h"
 #include "nsLayoutUtils.h"
@@ -874,17 +874,17 @@ nsPresContext::Init(nsDeviceContext* aDe
       }
     }
 
     if (!mRefreshDriver) {
       mRefreshDriver = new nsRefreshDriver(this);
     }
   }
 
-  mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
+  mLangService = nsLanguageAtomService::GetService();
 
   // Register callbacks so we're notified when the preferences change
   Preferences::RegisterPrefixCallback(nsPresContext::PrefChangedCallback,
                                       "font.",
                                       this);
   Preferences::RegisterPrefixCallback(nsPresContext::PrefChangedCallback,
                                       "browser.display.",
                                       this);
@@ -980,20 +980,18 @@ nsPresContext::AttachShell(nsIPresShell*
       docURI->SchemeIs("resource", &isRes);
 
       if (!isChrome && !isRes)
         mImageAnimationMode = mImageAnimationModePref;
       else
         mImageAnimationMode = imgIContainer::kNormalAnimMode;
     }
 
-    if (mLangService) {
-      doc->AddCharSetObserver(this);
-      UpdateCharSet(doc->GetDocumentCharacterSet());
-    }
+    doc->AddCharSetObserver(this);
+    UpdateCharSet(doc->GetDocumentCharacterSet());
   }
 }
 
 void
 nsPresContext::DetachShell()
 {
   // Remove ourselves as the charset observer from the shell's doc, because
   // this shell may be going away for good.
@@ -1054,27 +1052,25 @@ nsPresContext::DoChangeCharSet(const nsC
   UpdateCharSet(aCharSet);
   mDeviceContext->FlushFontCache();
   RebuildAllStyleData(NS_STYLE_HINT_REFLOW, nsRestyleHint(0));
 }
 
 void
 nsPresContext::UpdateCharSet(const nsCString& aCharSet)
 {
-  if (mLangService) {
-    mLanguage = mLangService->LookupCharSet(aCharSet);
-    // this will be a language group (or script) code rather than a true language code
-
-    // bug 39570: moved from nsLanguageAtomService::LookupCharSet()
-    if (mLanguage == nsGkAtoms::Unicode) {
-      mLanguage = mLangService->GetLocaleLanguage();
-    }
-    mLangGroupFontPrefs.Reset();
-    mFontGroupCacheDirty = true;
+  mLanguage = mLangService->LookupCharSet(aCharSet);
+  // this will be a language group (or script) code rather than a true language code
+
+  // bug 39570: moved from nsLanguageAtomService::LookupCharSet()
+  if (mLanguage == nsGkAtoms::Unicode) {
+    mLanguage = mLangService->GetLocaleLanguage();
   }
+  mLangGroupFontPrefs.Reset();
+  mFontGroupCacheDirty = true;
 
   switch (GET_BIDI_OPTION_TEXTTYPE(GetBidi())) {
 
     case IBMBIDI_TEXTTYPE_LOGICAL:
       SetVisualMode(false);
       break;
 
     case IBMBIDI_TEXTTYPE_VISUAL:
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -18,16 +18,17 @@
 #include "nsRect.h"
 #include "nsFont.h"
 #include "gfxFontConstants.h"
 #include "nsIAtom.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
 #include "nsCRT.h"
 #include "nsIWidgetListener.h"
+#include "nsLanguageAtomService.h"
 #include "FramePropertyTable.h"
 #include "nsGkAtoms.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsChangeHint.h"
 #include <algorithm>
 // This also pulls in gfxTypes.h, which we cannot include directly.
 #include "gfxRect.h"
 #include "nsTArray.h"
@@ -46,17 +47,16 @@
 #include "mozilla/StyleBackendType.h"
 
 class nsAString;
 class nsBidi;
 class nsIPrintSettings;
 class nsDocShell;
 class nsIDocShell;
 class nsIDocument;
-class nsILanguageAtomService;
 class nsITheme;
 class nsIContent;
 class nsIFrame;
 class nsFrameManager;
 class nsILinkHandler;
 class nsIAtom;
 class nsIRunnable;
 class gfxUserFontEntry;
@@ -1358,17 +1358,17 @@ protected:
   float                 mFullZoom;      // Page zoom, defaults to 1.0
   float                 mOverrideDPPX;   // DPPX overrided, defaults to 0.0
   gfxSize               mLastFontInflationScreenSize;
 
   int32_t               mCurAppUnitsPerDevPixel;
   int32_t               mAutoQualityMinFontSizePixelsPref;
 
   nsCOMPtr<nsITheme> mTheme;
-  nsCOMPtr<nsILanguageAtomService> mLangService;
+  nsLanguageAtomService* mLangService;
   nsCOMPtr<nsIPrintSettings> mPrintSettings;
   nsCOMPtr<nsITimer>    mPrefChangedTimer;
 
   mozilla::UniquePtr<nsBidi> mBidiEngine;
 
   FramePropertyTable    mPropertyTable;
 
   struct TransactionInvalidations {
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -52,17 +52,16 @@ ServoStyleSet::~ServoStyleSet()
 
 void
 ServoStyleSet::Init(nsPresContext* aPresContext)
 {
   mPresContext = aPresContext;
   mRawSet.reset(Servo_StyleSet_Init(aPresContext));
 
   mPresContext->DeviceContext()->InitFontCache();
-  gfxPlatformFontList::PlatformFontList()->InitLangService();
 
   // Now that we have an mRawSet, go ahead and notify about whatever stylesheets
   // we have so far.
   for (auto& sheetArray : mSheets) {
     for (auto& sheet : sheetArray) {
       // There's no guarantee this will create a list on the servo side whose
       // ordering matches the list that would have been created had all those
       // sheets been appended/prepended/etc after we had mRawSet. That's okay