Bug 1277908 - Keep visited rule node alive while creating non-visited style context; r=dholbert, a=lizzard
authorBrian Birtles <birtles@gmail.com>
Fri, 08 Jul 2016 13:17:42 +0900
changeset 339959 2be3abd8eea3b1186dc7cd2a94386821b8ec609e
parent 339958 40ae0b4863fdabc0b98cdcc2e499f19b205e90b2
child 339960 383d49d1d47096aae43b49e5d94cbfe90a1ef3e7
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, lizzard
bugs1277908
milestone49.0a2
Bug 1277908 - Keep visited rule node alive while creating non-visited style context; r=dholbert, a=lizzard MozReview-Commit-ID: Eqti28E14Jp
layout/style/nsStyleSet.cpp
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -910,16 +910,23 @@ nsStyleSet::GetContext(nsStyleContext* a
 #ifdef NOISY_DEBUG
   if (result)
     fprintf(stdout, "--- SharedSC %d ---\n", ++gSharedCount);
   else
     fprintf(stdout, "+++ NewSC %d +++\n", ++gNewCount);
 #endif
 
   if (!result) {
+    // |aVisitedRuleNode| may have a ref-count of zero since we are yet
+    // to create the style context that will hold an owning reference to it.
+    // As a result, we need to make sure it stays alive until that point
+    // in case something in the first call to NS_NewStyleContext triggers a
+    // GC sweep of rule nodes.
+    RefPtr<nsRuleNode> kungFuDeathGrip{aVisitedRuleNode};
+
     result = NS_NewStyleContext(aParentContext, aPseudoTag, aPseudoType,
                                 aRuleNode,
                                 aFlags & eSkipParentDisplayBasedStyleFixup);
     if (aVisitedRuleNode) {
       RefPtr<nsStyleContext> resultIfVisited =
         NS_NewStyleContext(parentIfVisited, aPseudoTag, aPseudoType,
                            aVisitedRuleNode,
                            aFlags & eSkipParentDisplayBasedStyleFixup);