Bug 649142 - Part 1: Add macros and flags for defining logical properties and don't allocate storage for them in nsRuleData. r=dbaron
☠☠ backed out by e7c43c3f8398 ☠ ☠
authorCameron McCormack <cam@mcc.id.au>
Wed, 31 Dec 2014 12:18:12 +1100
changeset 238436 b0eb691d6695b03ff6f8572a748370c6203384ec
parent 238435 e1dd807b8b2a2f8e72b964e7f11e2c007ceb0646
child 238437 b5725cd39a3152c75d1a84ccb88a9767a337e356
push id7472
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 20:36:27 +0000
treeherdermozilla-aurora@300ca104f8fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs649142
milestone37.0a1
Bug 649142 - Part 1: Add macros and flags for defining logical properties and don't allocate storage for them in nsRuleData. r=dbaron We define a new flag CSS_PROPERTY_LOGICAL to be used for logical longhand properties and a new CSS_PROP_LOGICAL macro in nsCSSPropList.h to define them. When using CSS_PROP to capture all properties, includers must now explicitly indicate whether logical properties are included or not, by defining CSS_PROP_LIST_EXCLUDE_LOGICAL (to exclude them), CSS_PROP_LIST_INCLUDE_LOGICAL (to include them), or CSS_PROP_LOGICAL (to capture them separately from other properties).
dom/webidl/CSS2PropertiesProps.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropList.h
layout/style/nsCSSProperty.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsDOMCSSDeclaration.h
layout/style/nsRuleData.h
layout/style/test/ListCSSProperties.cpp
--- a/dom/webidl/CSS2PropertiesProps.h
+++ b/dom/webidl/CSS2PropertiesProps.h
@@ -12,19 +12,21 @@
   [ #name, #method, #id, PROP_STRINGIFY(flags), pref ],
 #define CSS_PROP(name, id, method, flags, pref, parsevariant, kwtable, \
 		 stylestruct, stylestructofset, animtype) \
   DO_PROP(name, method, id, flags, pref)
 #define CSS_PROP_SHORTHAND(name, id, method, flags, pref) \
   DO_PROP(name, method, id, flags, pref)
 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_
 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 
 #include "nsCSSPropList.h"
 
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 #undef CSS_PROP_SHORTHAND
 #undef CSS_PROP
 
 #define CSS_PROP_ALIAS(name, id, method, pref) \
   DO_PROP(name, method, id, 0, pref)
 
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -54,17 +54,19 @@ using namespace mozilla;
 
 typedef nsCSSProps::KTableValue KTableValue;
 
 const uint32_t
 nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   parsevariant_,
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 };
 
 // Maximum number of repetitions for the repeat() function
 // in the grid-template-columns and grid-template-rows properties,
 // to limit high memory usage from small stylesheets.
 // Must be a positive integer. Should be large-ish.
 #define GRID_TEMPLATE_MAX_REPETITIONS 10000
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -12,17 +12,17 @@
 
   This file contains the list of all parsed CSS properties.  It is
   designed to be used as inline input through the magic of C
   preprocessing.  All entries must be enclosed in the appropriate
   CSS_PROP_* macro which will have cruel and unusual things done to it.
   It is recommended (but not strictly necessary) to keep all entries in
   alphabetical order.
 
-  The arguments to CSS_PROP and CSS_PROP_* are:
+  The arguments to CSS_PROP, CSS_PROP_LOGICAL and CSS_PROP_* are:
 
   -. 'name' entries represent a CSS property name and *must* use only
   lowercase characters.
 
   -. 'id' should be the same as 'name' except that all hyphens ('-')
   in 'name' are converted to underscores ('_') in 'id'. For properties
   on a standards track, any '-moz-' prefix is removed in 'id'. This
   lets us do nice things with the macros without having to copy/convert
@@ -46,30 +46,35 @@
   or if the boolean property whose name is 'pref' is set to true.
 
   -. 'parsevariant', to be passed to ParseVariant in the parser.
 
   -. 'kwtable', which is either nullptr or the name of the appropriate
   keyword table member of class nsCSSProps, for use in
   nsCSSProps::LookupPropertyValue.
 
-  -. 'stylestruct_' [used only for CSS_PROP, not CSS_PROP_*] gives the
-  name of the style struct.  Can be used to make nsStyle##stylestruct_
-  and eStyleStruct_##stylestruct_
+  -. 'stylestruct_' [used only for CSS_PROP and CSS_PROP_LOGICAL, not
+  CSS_PROP_*] gives the name of the style struct.  Can be used to make
+  nsStyle##stylestruct_ and eStyleStruct_##stylestruct_
 
   -. 'stylestructoffset_' [not used for CSS_PROP_BACKENDONLY] gives the
   result of offsetof(nsStyle*, member).  Ignored (and generally
   CSS_PROP_NO_OFFSET, or -1) for properties whose animtype_ is
   eStyleAnimType_None.
 
   -. 'animtype_' [not used for CSS_PROP_BACKENDONLY] gives the
   animation type (see nsStyleAnimType) of this property.
 
   CSS_PROP_SHORTHAND only takes 1-5.
 
+  CSS_PROP_LOGICAL should be used instead of CSS_PROP_struct when
+  defining logical properties (which also must be defined with the
+  CSS_PROPERTY_LOGICAL flag).  Logical shorthand properties should still
+  be defined with CSS_PROP_SHORTHAND.
+
  ******/
 
 
 /*************************************************************************/
 
 
 // All includers must explicitly define CSS_PROP_SHORTHAND if they
 // want it.
@@ -82,16 +87,36 @@
   CSS_PROP_PUBLIC_OR_PRIVATE(Moz ## name_, name_)
 
 #define CSS_PROP_NO_OFFSET (-1)
 
 // Callers may define CSS_PROP_LIST_EXCLUDE_INTERNAL if they want to
 // exclude internal properties that are not represented in the DOM (only
 // the DOM style code defines this).
 
+// When capturing all properties by defining CSS_PROP, callers must also
+// define one of the following three macros:
+//
+//   CSS_PROP_LIST_EXCLUDE_LOGICAL
+//     Does not include logical properties (defined with CSS_PROP_LOGICAL,
+//     such as -moz-margin-start) when capturing properties to CSS_PROP.
+//
+//   CSS_PROP_LIST_INCLUDE_LOGICAL
+//     Does include logical properties when capturing properties to
+//     CSS_PROP.
+//
+//   CSS_PROP_LOGICAL
+//     Captures logical properties separately to CSS_PROP_LOGICAL.
+//
+// (CSS_PROP_LIST_EXCLUDE_LOGICAL is used for example to ensure
+// gPropertyCountInStruct and gPropertyIndexInStruct do not allocate any
+// storage to logical properties, since the result of the cascade, stored
+// in an nsRuleData, does not need to store both logical and physical
+// property values.)
+
 // Callers may also define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND
 // to exclude properties that are not considered to be components of the 'all'
 // shorthand property.  Currently this excludes 'direction' and 'unicode-bidi',
 // as required by the CSS Cascading and Inheritance specification, and any
 // internal properties that cannot be changed by using CSS syntax.  For example,
 // the internal '-moz-system-font' property is not excluded, as it is set by the
 // 'font' shorthand, while '-x-lang' is excluded as there is no way to set this
 // internal property from a style sheet.
@@ -129,22 +154,46 @@
 // For properties that are stored in the CSS backend but are not
 // computed.  An includer may define this in addition to CSS_PROP, but
 // otherwise we treat it as the same.
 #ifndef CSS_PROP_BACKENDONLY
 #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_) CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, BackendOnly, CSS_PROP_NO_OFFSET, eStyleAnimType_None)
 #define DEFINED_CSS_PROP_BACKENDONLY
 #endif
 
+// And similarly for logical properties.  An includer can define
+// CSS_PROP_LOGICAL to capture all logical properties, but otherwise they
+// are included in CSS_PROP (as long as CSS_PROP_LIST_INCLUDE_LOGICAL is
+// defined).
+#if defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL) || defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL)
+#error Do not define more than one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP.
+#endif
+
+#ifndef CSS_PROP_LOGICAL
+#ifdef CSS_PROP_LIST_INCLUDE_LOGICAL
+#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_)
+#else
+#ifndef CSS_PROP_LIST_EXCLUDE_LOGICAL
+#error Must define exactly one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP.
+#endif
+#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */
+#endif
+#define DEFINED_CSS_PROP_LOGICAL
+#endif
+
 #else /* !defined(CSS_PROP) */
 
 // An includer who does not define CSS_PROP can define any or all of the
 // per-struct macros that are equivalent to it, and the rest will be
 // ignored.
 
+#if defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LIST_INCLUDE_LOGICAL)
+#error Do not define CSS_PROP_LIST_EXCLUDE_LOGICAL or CSS_PROP_LIST_INCLUDE_LOGICAL when not capturing properties using CSS_PROP.
+#endif
+
 #ifndef CSS_PROP_FONT
 #define CSS_PROP_FONT(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */
 #define DEFINED_CSS_PROP_FONT
 #endif
 #ifndef CSS_PROP_COLOR
 #define CSS_PROP_COLOR(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */
 #define DEFINED_CSS_PROP_COLOR
 #endif
@@ -236,16 +285,20 @@
 #define CSS_PROP_VARIABLES(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */
 #define DEFINED_CSS_PROP_VARIABLES
 #endif
 
 #ifndef CSS_PROP_BACKENDONLY
 #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_) /* nothing */
 #define DEFINED_CSS_PROP_BACKENDONLY
 #endif
+#ifndef CSS_PROP_LOGICAL
+#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */
+#define DEFINED_CSS_PROP_LOGICAL
+#endif
 
 #endif /* !defined(CSS_PROP) */
 
 /*************************************************************************/
 
 // For notes XXX bug 3935 below, the names being parsed do not correspond
 // to the constants used internally.  It would be nice to bring the
 // constants into line sometime.
@@ -4184,10 +4237,14 @@ CSS_PROP_FONT(
 #endif
 
 #endif /* !defined(USED_CSS_PROP) */
 
 #ifdef DEFINED_CSS_PROP_SHORTHAND
 #undef CSS_PROP_SHORTHAND
 #undef DEFINED_CSS_PROP_SHORTHAND
 #endif
+#ifdef DEFINED_CSS_PROP_LOGICAL
+#undef CSS_PROP_LOGICAL
+#undef DEFINED_CSS_PROP_LOGICAL
+#endif
 
 #undef CSS_PROP_DOMPROP_PREFIXED
--- a/layout/style/nsCSSProperty.h
+++ b/layout/style/nsCSSProperty.h
@@ -16,17 +16,19 @@
 
  */
 enum nsCSSProperty {
   eCSSProperty_UNKNOWN = -1,
 
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     eCSSProperty_##id_,
+  #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #include "nsCSSPropList.h"
+  #undef CSS_PROP_LIST_INCLUDE_LOGICAL
   #undef CSS_PROP
 
   eCSSProperty_COUNT_no_shorthands,
   // Make the count continue where it left off:
   eCSSProperty_COUNT_DUMMY = eCSSProperty_COUNT_no_shorthands - 1,
 
   #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
     eCSSProperty_##id_,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -31,17 +31,19 @@ typedef nsCSSProps::KTableValue KTableVa
 // required to make the symbol external, so that TestCSSPropertyLookup.cpp can link with it
 extern const char* const kCSSRawProperties[];
 
 // define an array of all CSS properties
 const char* const kCSSRawProperties[eCSSProperty_COUNT_with_aliases] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   #name_,
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) #name_,
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SHORTHAND
 #define CSS_PROP_ALIAS(aliasname_, id_, method_, pref_) #aliasname_,
 #include "nsCSSPropAliasList.h"
 #undef CSS_PROP_ALIAS
 };
@@ -164,17 +166,19 @@ nsCSSProps::AddRefTable(void)
         if (pref_[0]) {                                                       \
           Preferences::AddBoolVarCache(&gPropertyEnabled[id_],                \
                                        pref_);                                \
         }
 
       #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                        kwtable_, stylestruct_, stylestructoffset_, animtype_) \
         OBSERVE_PROP(pref_, eCSSProperty_##id_)
+      #define CSS_PROP_LIST_INCLUDE_LOGICAL
       #include "nsCSSPropList.h"
+      #undef CSS_PROP_LIST_INCLUDE_LOGICAL
       #undef CSS_PROP
 
       #define  CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
         OBSERVE_PROP(pref_, eCSSProperty_##id_)
       #include "nsCSSPropList.h"
       #undef CSS_PROP_SHORTHAND
 
       #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)    \
@@ -2114,17 +2118,19 @@ nsCSSProps::ValueToKeyword(int32_t aValu
   }
 }
 
 /* static */ const KTableValue* const
 nsCSSProps::kKeywordTableTable[eCSSProperty_COUNT_no_shorthands] = {
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     kwtable_,
+  #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #include "nsCSSPropList.h"
+  #undef CSS_PROP_LIST_INCLUDE_LOGICAL
   #undef CSS_PROP
 };
 
 const nsAFlatCString&
 nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, int32_t aValue)
 {
   NS_ABORT_IF_FALSE(aProp >= 0 && aProp < eCSSProperty_COUNT,
                     "property out of range");
@@ -2160,58 +2166,68 @@ bool nsCSSProps::GetColorName(int32_t aP
 
 const nsStyleStructID nsCSSProps::kSIDTable[eCSSProperty_COUNT_no_shorthands] = {
     // Note that this uses the special BackendOnly style struct ID
     // (which does need to be valid for storing in the
     // nsCSSCompressedDataBlock::mStyleBits bitfield).
     #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                      kwtable_, stylestruct_, stylestructoffset_, animtype_) \
         eStyleStruct_##stylestruct_,
+    #define CSS_PROP_LIST_INCLUDE_LOGICAL
 
     #include "nsCSSPropList.h"
 
+    #undef CSS_PROP_LIST_INCLUDE_LOGICAL
     #undef CSS_PROP
 };
 
 const nsStyleAnimType
 nsCSSProps::kAnimTypeTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   animtype_,
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 };
 
 const ptrdiff_t
 nsCSSProps::kStyleStructOffsetTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   stylestructoffset_,
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 };
 
 const uint32_t nsCSSProps::kFlagsTable[eCSSProperty_COUNT] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   flags_,
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) flags_,
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SHORTHAND
 };
 
 static const nsCSSProperty gAllSubpropTable[] = {
 #define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   eCSSProperty_##id_,
 #include "nsCSSPropList.h"
 #undef CSS_PROP
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gAnimationSubpropTable[] = {
   eCSSProperty_animation_duration,
   eCSSProperty_animation_timing_function,
   eCSSProperty_animation_delay,
@@ -2970,35 +2986,59 @@ nsCSSProps::gPropertyCountInStruct[nsSty
 };
 
 /* static */ const size_t
 nsCSSProps::gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands] = {
 
   #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \
                                parsevariant_, kwtable_)            \
       size_t(-1),
+  #define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \
+                           kwtable_, stylestruct_, stylestructoffset_,        \
+                           animtype_)                                         \
+      size_t(-1),
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     ePropertyIndex_for_##id_,
   #include "nsCSSPropList.h"
   #undef CSS_PROP
+  #undef CSS_PROP_LOGICAL
   #undef CSS_PROP_BACKENDONLY
 
 };
 
 /* static */ bool
 nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = {
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     true,
+  #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #include "nsCSSPropList.h"
+  #undef CSS_PROP_LIST_INCLUDE_LOGICAL
   #undef CSS_PROP
 
   #define  CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
     true,
   #include "nsCSSPropList.h"
   #undef CSS_PROP_SHORTHAND
 
   #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
     true,
   #include "nsCSSPropAliasList.h"
   #undef CSS_PROP_ALIAS
 };
+
+// Check that all properties defined using CSS_PROP_*_LOGICAL macros use
+// the CSS_PROPERTY_LOGICAL flag.
+#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,         \
+                 kwtable_, stylestruct_, stylestructoffset_, animtype_)     \
+  static_assert(!((flags_) & CSS_PROPERTY_LOGICAL),                         \
+                "only properties defined with CSS_PROP_LOGICAL can use "    \
+                "the CSS_PROPERTY_LOGICAL flag");
+#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \
+                         kwtable_, stylestruct_, stylestructoffset_,        \
+                         animtype_)                                         \
+  static_assert((flags_) & CSS_PROPERTY_LOGICAL,                            \
+                "properties defined with CSS_PROP_LOGICAL must also use "   \
+                "the CSS_PROPERTY_LOGICAL flag");
+#include "nsCSSPropList.h"
+#undef CSS_PROP_LOGICAL
+#undef CSS_PROP
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -211,16 +211,19 @@ static_assert((CSS_PROPERTY_PARSE_PROPER
 // use of that alias in privileged content will still be ignored unless the
 // pref is enabled. In other words, this bit has no effect on the use of
 // aliases.
 #define CSS_PROPERTY_ALWAYS_ENABLED_IN_CHROME_OR_CERTIFIED_APP (1<<23)
 
 // This property's unitless values are pixels.
 #define CSS_PROPERTY_NUMBERS_ARE_PIXELS           (1<<24)
 
+// This property is a logical property (such as padding-inline-start).
+#define CSS_PROPERTY_LOGICAL                      (1<<25)
+
 /**
  * Types of animatable values.
  */
 enum nsStyleAnimType {
   // requires a custom implementation in
   // StyleAnimationValue::ExtractComputedValue
   eStyleAnimType_Custom,
 
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5863,28 +5863,32 @@ nsComputedDOMStyle::RegisterPrefChangeCa
   nsComputedStyleMap* data = GetComputedStyleMap();
 #define REGISTER_CALLBACK(pref_)                                             \
   if (pref_[0]) {                                                            \
     Preferences::RegisterCallback(MarkComputedStyleMapDirty, pref_, data);   \
   }
 #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_,          \
                  kwtable_, stylestruct_, stylestructoffset_, animtype_)      \
   REGISTER_CALLBACK(pref_)
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #undef REGISTER_CALLBACK
 }
 
 /* static */ void
 nsComputedDOMStyle::UnregisterPrefChangeCallbacks()
 {
   nsComputedStyleMap* data = GetComputedStyleMap();
 #define UNREGISTER_CALLBACK(pref_)                                             \
   if (pref_[0]) {                                                              \
     Preferences::UnregisterCallback(MarkComputedStyleMapDirty, pref_, data);   \
   }
 #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_,            \
                  kwtable_, stylestruct_, stylestructoffset_, animtype_)        \
   UNREGISTER_CALLBACK(pref_)
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #undef UNREGISTER_CALLBACK
 }
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -74,26 +74,28 @@ public:
                                                                              \
   void                                                                       \
   Set##method_(const nsAString& aValue, mozilla::ErrorResult& rv)            \
   {                                                                          \
     rv = SetPropertyValue(eCSSProperty_##id_, aValue);                       \
   }
 
 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_)  \
   CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X)
 #include "nsCSSPropList.h"
 
 #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
   CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X)
 #include "nsCSSPropAliasList.h"
 #undef CSS_PROP_ALIAS
 
 #undef CSS_PROP_SHORTHAND
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 #undef CSS_PROP
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 
   virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) MOZ_OVERRIDE;
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -111,17 +111,19 @@ struct nsRuleData
       return mValueStorage + mValueOffsets[sid] + indexInStruct;             \
     }                                                                        \
     const nsCSSValue* ValueFor##method_() const {                            \
       return const_cast<nsRuleData*>(this)->ValueFor##method_();             \
     }
   #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_,           \
                              parsevariant_, kwtable_)                        \
     /* empty; backend-only structs are not in nsRuleData  */
+  #define CSS_PROP_LIST_EXCLUDE_LOGICAL
   #include "nsCSSPropList.h"
+  #undef CSS_PROP_LIST_EXCLUDE_LOGICAL
   #undef CSS_PROP
   #undef CSS_PROP_PUBLIC_OR_PRIVATE
   #undef CSS_PROP_BACKENDONLY
 
 private:
   inline size_t GetPoisonOffset();
 
 };
--- a/layout/style/test/ListCSSProperties.cpp
+++ b/layout/style/test/ListCSSProperties.cpp
@@ -16,38 +16,42 @@ struct PropertyInfo {
 };
 
 const PropertyInfo gLonghandProperties[] = {
 
 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
     { #name_, #method_, pref_ },
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 
 #include "nsCSSPropList.h"
 
+#undef CSS_PROP_LIST_EXCLUDE_LOGICAL
 #undef CSS_PROP
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 
 };
 
 /*
  * These are the properties for which domName in the above list should
  * be used.  They're in the same order as the above list, with some
  * items skipped.
  */
 const char* gLonghandPropertiesWithDOMProp[] = {
 
 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
     #name_,
+#define CSS_PROP_LIST_INCLUDE_LOGICAL
 
 #include "nsCSSPropList.h"
 
+#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 
 };
 
 const PropertyInfo gShorthandProperties[] = {
 
 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_