Bug 1351200 - Part 3: stylo: Bypass cache when fetching font size prefs from Stylo; r?emilio draft
authorManish Goregaokar <manishearth@gmail.com>
Tue, 04 Apr 2017 11:11:27 -0700
changeset 559269 af0804ad4ddf910e530c78d396e1b6c4bc28f415
parent 559268 c6689e36485b1ee6e0ce4ff344cde815369db04f
child 623338 847e27004930196048b3cdbfae2d4a68966cabd5
push id53032
push userbmo:manishearth@gmail.com
push dateSun, 09 Apr 2017 10:30:28 +0000
reviewersemilio
bugs1351200
milestone55.0a1
Bug 1351200 - Part 3: stylo: Bypass cache when fetching font size prefs from Stylo; r?emilio MozReview-Commit-ID: 7WBduQ6lBTC
intl/locale/nsILanguageAtomService.h
intl/locale/nsLanguageAtomService.cpp
intl/locale/nsLanguageAtomService.h
layout/base/StaticPresData.cpp
layout/base/StaticPresData.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
--- a/intl/locale/nsILanguageAtomService.h
+++ b/intl/locale/nsILanguageAtomService.h
@@ -30,16 +30,21 @@ class nsILanguageAtomService : public ns
 
   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;
+  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
@@ -57,49 +57,59 @@ nsLanguageAtomService::GetLocaleLanguage
       mLocaleLanguage = NS_Atomize(locale);
     }
   } while (0);
 
   return mLocaleLanguage;
 }
 
 nsIAtom*
-nsLanguageAtomService::GetLanguageGroup(nsIAtom *aLanguage,
-                                        nsresult *aError)
+nsLanguageAtomService::GetLanguageGroup(nsIAtom* aLanguage,
+                                        nsresult* aError)
 {
-  nsIAtom *retVal;
-  nsresult res = NS_OK;
+  nsIAtom* retVal;
 
   retVal = mLangToGroup.GetWeak(aLanguage);
 
   if (!retVal) {
-    nsAutoCString langStr;
-    aLanguage->ToUTF8String(langStr);
+    nsCOMPtr<nsIAtom> uncached = GetUncachedLanguageGroup(aLanguage, aError);
+    retVal = uncached.get();
+
+    // The hashtable will keep an owning reference to the atom
+    mLangToGroup.Put(aLanguage, uncached);
+  }
+
+  return retVal;
+}
 
-    nsAutoCString langGroupStr;
+already_AddRefed<nsIAtom>
+nsLanguageAtomService::GetUncachedLanguageGroup(nsIAtom* aLanguage,
+                                                nsresult* aError) const
+{
+  nsresult res = NS_OK;
+
+  nsAutoCString langStr;
+  aLanguage->ToUTF8String(langStr);
+
+  nsAutoCString langGroupStr;
+  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);
-    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);
-
-    // The hashtable will keep an owning reference to the atom
-    mLangToGroup.Put(aLanguage, langGroup);
-    retVal = langGroup.get();
-  }
+  nsCOMPtr<nsIAtom> langGroup = NS_Atomize(langGroupStr);
 
   if (aError) {
     *aError = res;
   }
 
-  return retVal;
+  return langGroup.forget();
 }
--- a/intl/locale/nsLanguageAtomService.h
+++ b/intl/locale/nsLanguageAtomService.h
@@ -23,18 +23,20 @@ public:
   virtual nsIAtom*
     LookupLanguage(const nsACString &aLanguage, nsresult *aError) override;
 
   virtual already_AddRefed<nsIAtom>
     LookupCharSet(const nsACString& aCharSet) override;
 
   virtual nsIAtom* GetLocaleLanguage() override;
 
-  virtual nsIAtom* GetLanguageGroup(nsIAtom *aLanguage,
-                                                nsresult *aError) override;
+  virtual nsIAtom* GetLanguageGroup(nsIAtom* aLanguage,
+                                    nsresult* aError) override;
+  virtual already_AddRefed<nsIAtom> GetUncachedLanguageGroup(nsIAtom* aLanguage,
+                                                             nsresult* aError) const final;
 
   nsLanguageAtomService();
 
 private:
   ~nsLanguageAtomService() { }
 
 protected:
   nsInterfaceHashtable<nsISupportsHashKey, nsIAtom> mLangToGroup;
--- a/layout/base/StaticPresData.cpp
+++ b/layout/base/StaticPresData.cpp
@@ -242,16 +242,27 @@ StaticPresData::GetLangGroup(nsIAtom* aL
   nsIAtom* langGroupAtom = nullptr;
   langGroupAtom = mLangService->GetLanguageGroup(aLanguage, &rv);
   if (NS_FAILED(rv) || !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) {
+    langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
+  }
+  return langGroupAtom.forget();
+}
+
 const LangGroupFontPrefs*
 StaticPresData::GetFontPrefsForLangHelper(nsIAtom* aLanguage,
                                           const LangGroupFontPrefs* aPrefs) const
 {
   // Get language group for aLanguage:
   MOZ_ASSERT(aLanguage);
   MOZ_ASSERT(mLangService);
   MOZ_ASSERT(aPrefs);
--- a/layout/base/StaticPresData.h
+++ b/layout/base/StaticPresData.h
@@ -96,16 +96,22 @@ public:
   /**
    * Given a language, get the language group name, which can
    * be used as an argument to LangGroupFontPrefs::Initialize()
    *
    */
   nsIAtom* GetLangGroup(nsIAtom* aLanguage) const;
 
   /**
+   * Same as GetLangGroup, but will not cache the result
+   *
+   */
+  already_AddRefed<nsIAtom> GetUncachedLangGroup(nsIAtom* aLanguage) const;
+
+  /**
    * Fetch the user's font preferences for the given aLanguage's
    * langugage group.
    *
    * The original code here is pretty old, and includes an optimization
    * whereby language-specific prefs are read per-document, and the
    * results are stored in a linked list, which is assumed to be very short
    * since most documents only ever use one language.
    *
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1572,20 +1572,37 @@ Gecko_nsStyleFont_SetLang(nsStyleFont* a
 }
 
 void
 Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource)
 {
   aFont->mLanguage = aSource->mLanguage;
 }
 
-nscoord
-Gecko_nsStyleFont_GetBaseSize(const nsStyleFont* aFont, RawGeckoPresContextBorrowed aPresContext)
+FontSizePrefs::FontSizePrefs(const LangGroupFontPrefs& prefs)
+  : mDefaultVariableSize(prefs.mDefaultVariableFont.size),
+    mDefaultFixedSize(prefs.mDefaultFixedFont.size),
+    mDefaultSerifSize(prefs.mDefaultSerifFont.size),
+    mDefaultSansSerifSize(prefs.mDefaultSansSerifFont.size),
+    mDefaultMonospaceSize(prefs.mDefaultMonospaceFont.size),
+    mDefaultCursiveSize(prefs.mDefaultCursiveFont.size),
+    mDefaultFantasySize(prefs.mDefaultFantasyFont.size)
 {
-  return aPresContext->GetDefaultFont(aFont->mGenericID, aFont->mLanguage)->size;
+}
+
+FontSizePrefs
+Gecko_GetBaseSize(nsIAtom* aLanguage)
+{
+  LangGroupFontPrefs prefs;
+  nsCOMPtr<nsIAtom> langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage);
+
+  prefs.Initialize(langGroupAtom);
+  FontSizePrefs sizes(prefs);
+
+  return sizes;
 }
 
 void
 Gecko_LoadStyleSheet(css::Loader* aLoader,
                      ServoStyleSheet* aParent,
                      RawServoStyleSheetBorrowed aChildSheet,
                      RawGeckoURLExtraData* aBaseURLData,
                      const uint8_t* aURLString,
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -35,16 +35,17 @@ namespace mozilla {
   class ServoStyleSheet;
   class FontFamilyList;
   enum FontFamilyType : uint32_t;
   struct Keyframe;
   namespace css {
     struct URLValue;
   };
   enum class UpdateAnimationsTasks : uint8_t;
+  struct LangGroupFontPrefs;
 }
 using mozilla::FontFamilyList;
 using mozilla::FontFamilyType;
 using mozilla::ServoElementSnapshot;
 class nsCSSFontFaceRule;
 struct nsMediaFeature;
 struct nsStyleList;
 struct nsStyleImage;
@@ -89,16 +90,28 @@ class ServoBundledURI
 {
 public:
   already_AddRefed<mozilla::css::URLValue> IntoCssUrl();
   const uint8_t* mURLString;
   uint32_t mURLStringLength;
   mozilla::URLExtraData* mExtraData;
 };
 
+struct FontSizePrefs
+{
+  FontSizePrefs(const mozilla::LangGroupFontPrefs&);
+  nscoord mDefaultVariableSize;
+  nscoord mDefaultFixedSize;
+  nscoord mDefaultSerifSize;
+  nscoord mDefaultSansSerifSize;
+  nscoord mDefaultMonospaceSize;
+  nscoord mDefaultCursiveSize;
+  nscoord mDefaultFantasySize;
+};
+
 // DOM Traversal.
 uint32_t Gecko_ChildrenCount(RawGeckoNodeBorrowed node);
 bool Gecko_NodeIsElement(RawGeckoNodeBorrowed node);
 bool Gecko_IsInDocument(RawGeckoNodeBorrowed node);
 bool Gecko_FlattenedTreeParentIsParent(RawGeckoNodeBorrowed node);
 bool Gecko_IsSignificantChild(RawGeckoNodeBorrowed node,
                               bool text_is_significant,
                               bool whitespace_is_significant);
@@ -376,17 +389,17 @@ void Gecko_CSSValue_SetArray(nsCSSValueB
 void Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut css_value, ServoBundledURI uri);
 void Gecko_CSSValue_SetInt(nsCSSValueBorrowedMut css_value, int32_t integer, nsCSSUnit unit);
 void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value);
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
 bool Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id);
 
 void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsIAtom* atom);
 void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource);
-nscoord Gecko_nsStyleFont_GetBaseSize(const nsStyleFont* font, RawGeckoPresContextBorrowed pres_context);
+FontSizePrefs Gecko_GetBaseSize(nsIAtom* lang);
 
 const nsMediaFeature* Gecko_GetMediaFeatures();
 
 // Font face rule
 // Creates and returns a new (already-addrefed) nsCSSFontFaceRule object.
 nsCSSFontFaceRule* Gecko_CSSFontFaceRule_Create();
 void Gecko_CSSFontFaceRule_GetCssText(const nsCSSFontFaceRule* rule, nsAString* result);
 NS_DECL_FFI_REFCOUNTING(nsCSSFontFaceRule, CSSFontFaceRule);