Bug 1338936 - Part 1: stylo: Add stubbed-out ServoSpecifiedValues interface, use it for pres attr mapping; r=bz,emilio
authorManish Goregaokar <manishearth@gmail.com>
Sun, 12 Feb 2017 16:02:29 -0800
changeset 343740 a0c56ecc911127591ea25904486bfa019836f0c2
parent 343739 b53a9cea93fd598ea2baa8314e5cad63cfa4bf5d
child 343741 28d72f228244590ced658878c5ac42a7a7ee6aea
push id31387
push usercbook@mozilla.com
push dateMon, 20 Feb 2017 13:03:57 +0000
treeherdermozilla-central@66739e3ff974 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, emilio
bugs1338936
milestone54.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 1338936 - Part 1: stylo: Add stubbed-out ServoSpecifiedValues interface, use it for pres attr mapping; r=bz,emilio MozReview-Commit-ID: 6wg32flypt7
dom/base/nsMappedAttributes.cpp
dom/base/nsMappedAttributes.h
layout/style/GenericSpecifiedValues.h
layout/style/GenericSpecifiedValuesInlines.h
layout/style/ServoSpecifiedValues.cpp
layout/style/ServoSpecifiedValues.h
layout/style/moz.build
layout/style/nsHTMLStyleSheet.cpp
layout/style/nsRuleData.h
--- a/dom/base/nsMappedAttributes.cpp
+++ b/dom/base/nsMappedAttributes.cpp
@@ -12,16 +12,17 @@
 #include "nsMappedAttributes.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsRuleData.h"
 #include "nsRuleWalker.h"
 #include "mozilla/GenericSpecifiedValues.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ServoDeclarationBlock.h"
+#include "mozilla/ServoSpecifiedValues.h"
 
 using namespace mozilla;
 
 nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet,
                                        nsMapRuleToAttributesFunc aMapRuleFunc)
   : mAttrCount(0),
     mSheet(aSheet),
     mRuleMapper(aMapRuleFunc),
@@ -284,24 +285,19 @@ nsMappedAttributes::SizeOfIncludingThis(
   size_t n = aMallocSizeOf(this);
   for (uint16_t i = 0; i < mAttrCount; ++i) {
     n += Attrs()[i].mValue.SizeOfExcludingThis(aMallocSizeOf);
   }
   return n;
 }
 
 void
-nsMappedAttributes::LazilyResolveServoDeclaration(nsRuleData* aRuleData,
-                                                  nsCSSPropertyID* aIndexToIdMapping,
-                                                  size_t aRuleDataSize)
+nsMappedAttributes::LazilyResolveServoDeclaration(nsPresContext* aContext)
 {
-  MapRuleInfoInto(aRuleData);
 
   MOZ_ASSERT(!mServoStyle,
              "LazilyResolveServoDeclaration should not be called if mServoStyle is already set");
-  mServoStyle = Servo_DeclarationBlock_CreateEmpty().Consume();
-  for (size_t i = 0; i < aRuleDataSize; i++) {
-    nsCSSValue& val = aRuleData->mValueStorage[i];
-    if (val.GetUnit() != eCSSUnit_Null) {
-      Servo_DeclarationBlock_AddPresValue(mServoStyle.get(), aIndexToIdMapping[i], &val);
-    }
+  if (mRuleMapper) {
+    mServoStyle = Servo_DeclarationBlock_CreateEmpty().Consume();
+    ServoSpecifiedValues servo = ServoSpecifiedValues(aContext, mServoStyle.get());
+    (*mRuleMapper)(this, &servo);
   }
 }
--- a/dom/base/nsMappedAttributes.h
+++ b/dom/base/nsMappedAttributes.h
@@ -67,26 +67,19 @@ public:
     return &Attrs()[aPos].mValue;
   }
   // Remove the attr at position aPos.  The value of the attr is placed in
   // aValue; any value that was already in aValue is destroyed.
   void RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
   const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
   int32_t IndexOfAttr(nsIAtom* aLocalName) const;
 
-  // Apply the contained mapper to an empty nsRuleData object
-  // that is able to contain all properties. Set contained servo declaration block
-  // to result of this computation.
-  // aIndexToIdMapping is
-  // a table that maps from an index in the rule data to the corresponding
-  // property ID. aRuleDataSize is the length of the backing storage
-  // of the rule data.
-  void LazilyResolveServoDeclaration(nsRuleData* aRuleData,
-                                     nsCSSPropertyID* aIndexToIdMapping,
-                                     size_t aRuleDataSize);
+  // Apply the contained mapper to the contained set of servo rules,
+  // unless the servo rules have already been initialized.
+  void LazilyResolveServoDeclaration(nsPresContext* aPresContext);
 
   // Obtain the contained servo declaration block
   // May return null if called before the inner block
   // has been (lazily) resolved
   const RefPtr<RawServoDeclarationBlock>& GetServoStyle() const
   {
     return mServoStyle;
   }
--- a/layout/style/GenericSpecifiedValues.h
+++ b/layout/style/GenericSpecifiedValues.h
@@ -14,28 +14,32 @@
 #define mozilla_GenericSpecifiedValues_h
 
 #include "mozilla/ServoUtils.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsPresContext.h"
 
 struct nsRuleData;
+
 namespace mozilla {
+
+class ServoSpecifiedValues;
+
 // This provides a common interface for attribute mappers (MapAttributesIntoRule)
 // to use regardless of the style backend. If the style backend is Gecko,
 // this will contain an nsRuleData. If it is Servo, it will be a PropertyDeclarationBlock.
 class GenericSpecifiedValues {
 protected:
     explicit GenericSpecifiedValues(StyleBackendType aType, nsPresContext* aPresContext,
                                     uint32_t aSIDs)
         : mType(aType), mPresContext(aPresContext), mSIDs(aSIDs) {}
 
 public:
-    MOZ_DECL_STYLO_METHODS(nsRuleData, nsRuleData)
+    MOZ_DECL_STYLO_METHODS(nsRuleData, ServoSpecifiedValues)
 
     // Check if we already contain a certain longhand
     inline bool PropertyIsSet(nsCSSPropertyID aId);
     // Check if we are able to hold longhands from a given
     // style struct. Pass the result of NS_STYLE_INHERIT_BIT to this
     // function. Can accept multiple inherit bits or'd together.
     inline bool ShouldComputeStyleStruct(uint64_t aInheritBits) {
         return aInheritBits & mSIDs;
--- a/layout/style/GenericSpecifiedValuesInlines.h
+++ b/layout/style/GenericSpecifiedValuesInlines.h
@@ -11,20 +11,21 @@
  * in stylo mode.
  */
 
 #ifndef mozilla_GenericSpecifiedValuesInlines_h
 #define mozilla_GenericSpecifiedValuesInlines_h
 
 #include "nsRuleData.h"
 #include "mozilla/GenericSpecifiedValues.h"
+#include "mozilla/ServoSpecifiedValues.h"
 
 namespace mozilla {
 
-MOZ_DEFINE_STYLO_METHODS(GenericSpecifiedValues, nsRuleData, nsRuleData)
+MOZ_DEFINE_STYLO_METHODS(GenericSpecifiedValues, nsRuleData, ServoSpecifiedValues)
 
 bool
 GenericSpecifiedValues::PropertyIsSet(nsCSSPropertyID aId)
 {
   MOZ_STYLO_FORWARD(PropertyIsSet, (aId))
 }
 
 void
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoSpecifiedValues.cpp
@@ -0,0 +1,27 @@
+/* -*- 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/. */
+
+#include "mozilla/ServoSpecifiedValues.h"
+
+namespace {
+
+#define STYLE_STRUCT(name, checkdata_cb) | NS_STYLE_INHERIT_BIT(name)
+const uint64_t ALL_SIDS = 0
+#include "nsStyleStructList.h"
+;
+#undef STYLE_STRUCT
+
+} // anonymous namespace
+
+using namespace mozilla;
+
+ServoSpecifiedValues::ServoSpecifiedValues(nsPresContext* aContext,
+                                           RawServoDeclarationBlock* aDecl)
+
+  : GenericSpecifiedValues(StyleBackendType::Servo, aContext, ALL_SIDS)
+  ,  mDecl(aDecl)
+{
+
+}
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoSpecifiedValues.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/*
+ * Servo-backed specified value store, to be used when mapping presentation
+ * attributes
+ */
+
+#ifndef mozilla_ServoSpecifiedValues_h
+#define mozilla_ServoSpecifiedValues_h
+
+#include "mozilla/GenericSpecifiedValues.h"
+#include "mozilla/ServoBindings.h"
+
+namespace mozilla {
+
+class ServoSpecifiedValues final: public GenericSpecifiedValues
+{
+public:
+
+  ServoSpecifiedValues(nsPresContext* aContext, RawServoDeclarationBlock* aDecl);
+
+  // GenericSpecifiedValues overrides
+  bool PropertyIsSet(nsCSSPropertyID aId) {
+    return false;
+  }
+
+  void SetIdentStringValue(nsCSSPropertyID aId,
+                           const nsString& aValue) {
+
+  }
+
+  void SetIdentStringValueIfUnset(nsCSSPropertyID aId,
+                                  const nsString& aValue) {
+
+  }
+
+  void SetKeywordValue(nsCSSPropertyID aId,
+                       int32_t aValue) {
+  }
+
+  void SetKeywordValueIfUnset(nsCSSPropertyID aId,
+                              int32_t aValue) {
+
+  }
+
+
+  void SetIntValue(nsCSSPropertyID aId,
+                   int32_t aValue) {
+  }
+
+  void SetPixelValue(nsCSSPropertyID aId,
+                     float aValue) {
+  }
+
+  void SetPixelValueIfUnset(nsCSSPropertyID aId,
+                            float aValue) {
+  }
+
+  void SetPercentValue(nsCSSPropertyID aId,
+                       float aValue) {
+  }
+
+  void SetAutoValue(nsCSSPropertyID aId) {
+  }
+
+  void SetAutoValueIfUnset(nsCSSPropertyID aId) {
+  }
+
+  void SetPercentValueIfUnset(nsCSSPropertyID aId,
+                              float aValue) {
+
+  }
+
+  void SetCurrentColor(nsCSSPropertyID aId) {
+
+  }
+
+  void SetCurrentColorIfUnset(nsCSSPropertyID aId) {
+
+  }
+
+  void SetColorValue(nsCSSPropertyID aId,
+                     nscolor aValue) {
+
+  }
+
+  void SetColorValueIfUnset(nsCSSPropertyID aId,
+                            nscolor aValue) {
+
+  }
+
+  void SetFontFamily(const nsString& aValue) {
+
+  }
+  void SetTextDecorationColorOverride() {
+
+  }
+
+private:
+  RefPtr<RawServoDeclarationBlock> mDecl;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ServoSpecifiedValues_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -97,16 +97,17 @@ EXPORTS.mozilla += [
     'ServoArcTypeList.h',
     'ServoBindingList.h',
     'ServoBindings.h',
     'ServoBindingTypes.h',
     'ServoCSSRuleList.h',
     'ServoDeclarationBlock.h',
     'ServoElementSnapshot.h',
     'ServoPropPrefList.h',
+    'ServoSpecifiedValues.h',
     'ServoStyleRule.h',
     'ServoStyleSet.h',
     'ServoStyleSheet.h',
     'ServoTypes.h',
     'ServoUtils.h',
     'SheetType.h',
     'StyleAnimationValue.h',
     'StyleAnimationValueInlines.h',
@@ -225,16 +226,17 @@ UNIFIED_SOURCES += [
 # - nsCSSRuleProcessor.cpp needs to be built separately because it uses
 # plarena.h.
 # - nsLayoutStylesheetCache.cpp needs to be built separately because it uses
 # nsExceptionHandler.h, which includes windows.h.
 SOURCES += [
     'BindingStyleRule.cpp',
     'nsCSSRuleProcessor.cpp',
     'nsLayoutStylesheetCache.cpp',
+    'ServoSpecifiedValues.cpp',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '../base',
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -549,104 +549,27 @@ nsHTMLStyleSheet::DropMappedAttributes(n
   uint32_t entryCount = mMappedAttrTable.EntryCount() - 1;
 #endif
 
   mMappedAttrTable.Remove(aMapped);
 
   NS_ASSERTION(entryCount == mMappedAttrTable.EntryCount(), "not removed");
 }
 
-namespace {
-  // Struct containing once-initialized information about
-  // our synthesized rule data
-  struct StaticRuleDataInfo
-  {
-    // the bitmask used.
-    uint64_t mMask;
-    // the number of properties contained
-    size_t mPropCount;
-    // offset of given style struct in array
-    size_t mOffsets[nsStyleStructID_Length];
-    // location of property in given array
-    nsCSSPropertyID* mIndexToPropertyMapping;
-  };
-}
-
-static void
-CalculateIndexArray(StaticRuleDataInfo* aInfo)
-{
-  // this will leak at shutdown, but it's not much and this code is temporary
-  // anyway.
-  aInfo->mIndexToPropertyMapping = new nsCSSPropertyID[aInfo->mPropCount];
-  size_t structOffset;
-  size_t propertyIndex;
-  #define CSS_PROP_LIST_EXCLUDE_LOGICAL
-  #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
-                   kwtable_, stylestruct_, stylestructoffset_, animtype_) \
-    structOffset = aInfo->mOffsets[eStyleStruct_##stylestruct_]; \
-    propertyIndex = nsCSSProps::PropertyIndexInStruct(eCSSProperty_##id_); \
-    aInfo->mIndexToPropertyMapping[structOffset + propertyIndex] = eCSSProperty_##id_;
-  #include "nsCSSPropList.h"
-  #undef CSS_PROP
-  #undef CSS_PROP_LIST_EXCLUDE_LOGICAL
-}
-
-static StaticRuleDataInfo
-CalculateRuleDataInfo()
-{
-  StaticRuleDataInfo sizes;
-  sizes.mMask = 0;
-  sizes.mPropCount = 0;
-#define STYLE_STRUCT(name, checkdata_cb) \
-  sizes.mMask |= NS_STYLE_INHERIT_BIT(name); \
-  sizes.mOffsets[eStyleStruct_##name] = sizes.mPropCount; \
-  sizes.mPropCount += nsCSSProps::PropertyCountInStruct(eStyleStruct_##name);
-#include "nsStyleStructList.h"
-#undef STYLE_STRUCT
-
-  CalculateIndexArray(&sizes);
-
-  return sizes;
-}
-
-
-
 void
 nsHTMLStyleSheet::CalculateMappedServoDeclarations()
 {
-  // avoid recalculating or reallocating
-  static StaticRuleDataInfo sizes = CalculateRuleDataInfo();
-
-  if (!mMappedAttrsDirty) {
-    return;
-  }
-  mMappedAttrsDirty = false;
-
-  void* dataStorage = alloca(sizes.mPropCount * sizeof(nsCSSValue));
+  nsPresContext* presContext = mDocument->GetShell()->GetPresContext();
   for (auto iter = mMappedAttrTable.Iter(); !iter.Done(); iter.Next()) {
     MappedAttrTableEntry* attr = static_cast<MappedAttrTableEntry*>(iter.Get());
     if (attr->mAttributes->GetServoStyle()) {
       // Only handle cases which haven't been filled in already
       continue;
     }
-    // Construction cleans up any values we may have set
-    AutoCSSValueArray dataArray(dataStorage, sizes.mPropCount);
-
-    // synthesized ruleData
-    // we pass null for the style context because the code we call into
-    // doesn't deal with the style context. This is temporary.
-    nsRuleData ruleData(sizes.mMask, dataArray.get(),
-                        mDocument->GetShell()->GetPresContext(), nullptr);
-    // Copy the offsets; ruleData won't know where to find properties otherwise
-    mozilla::PodCopy(ruleData.mValueOffsets,
-                     sizes.mOffsets,
-                     nsStyleStructID_Length);
-    attr->mAttributes->LazilyResolveServoDeclaration(&ruleData,
-                                                     sizes.mIndexToPropertyMapping,
-                                                     sizes.mPropCount);
+    attr->mAttributes->LazilyResolveServoDeclaration(presContext);
   }
 }
 
 nsIStyleRule*
 nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage)
 {
   auto entry =
     static_cast<LangRuleTableEntry*>(mLangRuleTable.Add(&aLanguage, fallible));
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -208,18 +208,14 @@ struct nsRuleData final: mozilla::Generi
     if (!PropertyIsSet(aId)) {
       SetColorValue(aId, aValue);
     }
   }
 
   void SetFontFamily(const nsString& aValue);
   void SetTextDecorationColorOverride();
 
-  nsRuleData* AsRuleData() {
-    return this;
-  }
-
 private:
   inline size_t GetPoisonOffset();
 
 };
 
 #endif