Bug 1289868 - Part 2: stylo: Compare all structs in CalcStyleDifference so that Servo can accurately determine whether to stop traversal. r=emilio draft
authorCameron McCormack <cam@mcc.id.au>
Fri, 19 May 2017 17:39:14 +0800
changeset 581906 8dd1fba6b35e80714e98a4114bd70e3705027eca
parent 581904 710492f48c6c2242916754baed86eb39f2850b40
child 629616 44a81a7d77264474c1712567e93c5592731a8ce8
push id59912
push userbmo:cam@mcc.id.au
push dateSat, 20 May 2017 03:29:00 +0000
reviewersemilio
bugs1289868
milestone55.0a1
Bug 1289868 - Part 2: stylo: Compare all structs in CalcStyleDifference so that Servo can accurately determine whether to stop traversal. r=emilio MozReview-Commit-ID: I0WK2gDsMMu
layout/style/nsStyleContext.cpp
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -1027,30 +1027,49 @@ nsStyleContext::CalcStyleDifferenceInter
       *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
     }
   } else {
     *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
   }
 
   DebugOnly<int> styleStructCount = 1;  // count Variables already
 
+  // Servo's optimization to stop the cascade when there are no style changes
+  // that children need to be recascade for relies on comparing all of the
+  // structs, not just those that are returned from PeekStyleData, although
+  // if PeekStyleData does return null we still don't want to accumulate
+  // any change hints for those structs.
+  bool checkUnrequestedServoStructs = mSource.IsServoComputedValues();
+
 #define DO_STRUCT_DIFFERENCE(struct_)                                         \
   PR_BEGIN_MACRO                                                              \
     const nsStyle##struct_* this##struct_ = PeekStyle##struct_();             \
+    bool unrequestedStruct;                                                   \
     if (this##struct_) {                                                      \
+      unrequestedStruct = false;                                              \
       structsFound |= NS_STYLE_INHERIT_BIT(struct_);                          \
+    } else if (checkUnrequestedServoStructs) {                                \
+      this##struct_ =                                                         \
+        Servo_GetStyle##struct_(mSource.AsServoComputedValues());             \
+      unrequestedStruct = true;                                               \
+    } else {                                                                  \
+      unrequestedStruct = false;                                              \
+    }                                                                         \
+    if (this##struct_) {                                                      \
       const nsStyle##struct_* other##struct_ = aNewContext->Style##struct_(); \
       if (this##struct_ == other##struct_) {                                  \
         /* The very same struct, so we know that there will be no */          \
         /* differences.                                           */          \
         *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                      \
       } else {                                                                \
         nsChangeHint difference =                                             \
           this##struct_->CalcDifference(*other##struct_ EXTRA_DIFF_ARGS);     \
-        hint |= difference;                                                   \
+        if (!unrequestedStruct) {                                             \
+          hint |= difference;                                                 \
+        }                                                                     \
         if (!difference) {                                                    \
           *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                    \
         }                                                                     \
       }                                                                       \
     } else {                                                                  \
       *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_);                        \
     }                                                                         \
     styleStructCount++;                                                       \