diff --git a/intl/locale/nsLanguageAtomService.cpp b/intl/locale/nsLanguageAtomService.cpp index 7a63d95dc226..eebbed08b505 100644 --- a/intl/locale/nsLanguageAtomService.cpp +++ b/intl/locale/nsLanguageAtomService.cpp @@ -21,10 +21,11 @@ static constexpr nsUConvProp encodingsGroups[] = { }; // List of mozilla internal x-* tags that map to themselves (see bug 256257) -static constexpr const char* kLangGroups[] = { +static constexpr nsStaticAtom* kLangGroups[] = { // This list must be sorted! - "x-armn", "x-cyrillic", "x-devanagari", "x-geor", "x-math", - "x-tamil", "x-unicode", "x-western" + nsGkAtoms::x_armn, nsGkAtoms::x_cyrillic, nsGkAtoms::x_devanagari, + nsGkAtoms::x_geor, nsGkAtoms::x_math, nsGkAtoms::x_tamil, + nsGkAtoms::Unicode, nsGkAtoms::x_western // These self-mappings are not necessary unless somebody use them to specify // lang in (X)HTML/XML documents, which they shouldn't. (see bug 256257) // x-beng=x-beng @@ -39,7 +40,7 @@ static constexpr const char* kLangGroups[] = { // Map ISO 15924 script codes from BCP47 lang tag to mozilla's langGroups. static constexpr struct { const char* mTag; - nsAtom* mAtom; + nsStaticAtom* mAtom; } kScriptLangGroup[] = { // This list must be sorted by script code! {"Arab", nsGkAtoms::ar}, @@ -86,7 +87,8 @@ nsLanguageAtomService* nsLanguageAtomService::GetService() { return gLangAtomService.get(); } -nsAtom* nsLanguageAtomService::LookupLanguage(const nsACString& aLanguage) { +nsStaticAtom* nsLanguageAtomService::LookupLanguage( + const nsACString& aLanguage) { nsAutoCString lowered(aLanguage); ToLowerCase(lowered); @@ -128,42 +130,41 @@ nsAtom* nsLanguageAtomService::GetLocaleLanguage() { return mLocaleLanguage; } -nsAtom* nsLanguageAtomService::GetLanguageGroup(nsAtom* aLanguage, - bool* aNeedsToCache) { - nsAtom* retVal = mLangToGroup.GetWeak(aLanguage); - - if (!retVal) { - if (aNeedsToCache) { - *aNeedsToCache = true; - return nullptr; - } - RefPtr uncached = GetUncachedLanguageGroup(aLanguage); - retVal = uncached.get(); - - AssertIsMainThreadOrServoFontMetricsLocked(); - // The hashtable will keep an owning reference to the atom - mLangToGroup.Put(aLanguage, uncached); +nsStaticAtom* nsLanguageAtomService::GetLanguageGroup(nsAtom* aLanguage, + bool* aNeedsToCache) { + if (nsStaticAtom* group = mLangToGroup.Get(aLanguage)) { + return group; } - - return retVal; + if (aNeedsToCache) { + *aNeedsToCache = true; + return nullptr; + } + AssertIsMainThreadOrServoFontMetricsLocked(); + nsStaticAtom* group = GetUncachedLanguageGroup(aLanguage); + mLangToGroup.Put(aLanguage, group); + return group; } -already_AddRefed nsLanguageAtomService::GetUncachedLanguageGroup( +nsStaticAtom* nsLanguageAtomService::GetUncachedLanguageGroup( nsAtom* aLanguage) const { nsAutoCString langStr; aLanguage->ToUTF8String(langStr); ToLowerCase(langStr); - RefPtr langGroup; if (langStr[0] == 'x' && langStr[1] == '-') { // Internal x-* langGroup codes map to themselves (see bug 256257) - size_t unused; - if (BinarySearchIf( - kLangGroups, 0, ArrayLength(kLangGroups), - [&langStr](const char* tag) -> int { return langStr.Compare(tag); }, - &unused)) { - langGroup = NS_Atomize(langStr); - return langGroup.forget(); + for (nsStaticAtom* langGroup : kLangGroups) { + if (langGroup == aLanguage) { + return langGroup; + } + if (aLanguage->IsAsciiLowercase()) { + continue; + } + // Do the slow ascii-case-insensitive comparison just if needed. + nsDependentAtomString string(langGroup); + if (string.EqualsASCII(langStr.get(), langStr.Length())) { + return langGroup; + } } } else { // If the lang code can be parsed as BCP47, look up its (likely) script @@ -174,11 +175,9 @@ already_AddRefed nsLanguageAtomService::GetUncachedLanguageGroup( } if (loc.GetScript().EqualsLiteral("Hant")) { if (loc.GetRegion().EqualsLiteral("HK")) { - langGroup = nsGkAtoms::HongKongChinese; - } else { - langGroup = nsGkAtoms::Taiwanese; + return nsGkAtoms::HongKongChinese; } - return langGroup.forget(); + return nsGkAtoms::Taiwanese; } else { size_t foundIndex; const nsCString& script = loc.GetScript(); @@ -187,14 +186,12 @@ already_AddRefed nsLanguageAtomService::GetUncachedLanguageGroup( return script.Compare(entry.mTag); }, &foundIndex)) { - langGroup = kScriptLangGroup[foundIndex].mAtom; - return langGroup.forget(); + return kScriptLangGroup[foundIndex].mAtom; } } } } // Fall back to x-unicode if no match was found - langGroup = nsGkAtoms::Unicode; - return langGroup.forget(); + return nsGkAtoms::Unicode; } diff --git a/intl/locale/nsLanguageAtomService.h b/intl/locale/nsLanguageAtomService.h index 58817408654a..d453ac384ecb 100644 --- a/intl/locale/nsLanguageAtomService.h +++ b/intl/locale/nsLanguageAtomService.h @@ -14,7 +14,7 @@ #include "mozilla/NotNull.h" #include "nsCOMPtr.h" #include "nsAtom.h" -#include "nsRefPtrHashtable.h" +#include "nsDataHashtable.h" namespace mozilla { class Encoding; @@ -28,7 +28,7 @@ class nsLanguageAtomService final { public: static nsLanguageAtomService* GetService(); - nsAtom* LookupLanguage(const nsACString& aLanguage); + nsStaticAtom* LookupLanguage(const nsACString& aLanguage); already_AddRefed LookupCharSet(NotNull aCharSet); nsAtom* GetLocaleLanguage(); @@ -47,11 +47,12 @@ class nsLanguageAtomService final { // get a true *aNeedsToCache outparam value should make an effort // to re-call GetLanguageGroup when it is safe to cache, to avoid // recomputing the language group again later. - nsAtom* GetLanguageGroup(nsAtom* aLanguage, bool* aNeedsToCache = nullptr); - already_AddRefed GetUncachedLanguageGroup(nsAtom* aLanguage) const; + nsStaticAtom* GetLanguageGroup(nsAtom* aLanguage, + bool* aNeedsToCache = nullptr); + nsStaticAtom* GetUncachedLanguageGroup(nsAtom* aLanguage) const; private: - nsRefPtrHashtable, nsAtom> mLangToGroup; + nsDataHashtable, nsStaticAtom*> mLangToGroup; RefPtr mLocaleLanguage; }; diff --git a/layout/base/StaticPresData.h b/layout/base/StaticPresData.h index 5f612148dc57..dc5c100340d4 100644 --- a/layout/base/StaticPresData.h +++ b/layout/base/StaticPresData.h @@ -105,7 +105,7 @@ struct LangGroupFontPrefs { } } - RefPtr mLangGroup; + nsStaticAtom* mLangGroup; nscoord mMinimumFontSize; nsFont mDefaultVariableFont; nsFont mDefaultFixedFont; @@ -151,13 +151,12 @@ class StaticPresData { * to re-call GetLanguageGroup when it is safe to cache, to avoid * recomputing the language group again later. */ - nsAtom* GetLangGroup(nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const; + nsStaticAtom* GetLangGroup(nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const; /** * Same as GetLangGroup, but will not cache the result - * */ - already_AddRefed GetUncachedLangGroup(nsAtom* aLanguage) const; + nsStaticAtom* GetUncachedLangGroup(nsAtom* aLanguage) const; /** * Fetch the user's font preferences for the given aLanguage's @@ -183,7 +182,7 @@ class StaticPresData { private: StaticPresData(); - ~StaticPresData() {} + ~StaticPresData() = default; nsLanguageAtomService* mLangService; }; diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp index 2b05d474f066..2068613bddf0 100644 --- a/layout/style/GeckoBindings.cpp +++ b/layout/style/GeckoBindings.cpp @@ -1967,13 +1967,11 @@ void FontSizePrefs::CopyFrom(const LangGroupFontPrefs& prefs) { FontSizePrefs Gecko_GetBaseSize(nsAtom* aLanguage) { LangGroupFontPrefs prefs; - RefPtr langGroupAtom = + nsStaticAtom* langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage); - prefs.Initialize(langGroupAtom); FontSizePrefs sizes; sizes.CopyFrom(prefs); - return sizes; }