Fix a hang by using a dedicated state bit instead of overloading NS_FRAME_IS_DIRTY. Bug 964821, r=roc
authorSimon Montagu <smontagu@smontagu.org>
Mon, 17 Feb 2014 14:46:40 -0800
changeset 169143 b732738b75f89122d9ad0cab4396194d7ca27de0
parent 169142 9945bc3b7d36c659395bf69f2306f7ba74427ddb
child 169144 0f78e7bb808cd11027647b99c8ab428ad67549d3
push id39878
push usersmontagu@mozilla.com
push dateMon, 17 Feb 2014 22:47:09 +0000
treeherdermozilla-inbound@b732738b75f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs964821
milestone30.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
Fix a hang by using a dedicated state bit instead of overloading NS_FRAME_IS_DIRTY. Bug 964821, r=roc
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsFrameStateBits.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -10097,24 +10097,30 @@ nsCSSFrameConstructor::RemoveFloatingFir
   // Remove placeholder frame and the float
   RemoveFrame(kPrincipalList, placeholderFrame);
 
   // Now that the old frames are gone, we can start pointing to our
   // new primary frame.
   textContent->SetPrimaryFrame(newTextFrame);
 
   // Wallpaper bug 822910.
-  if (prevSibling && prevSibling->GetType() == nsGkAtoms::textFrame) {
-    prevSibling->AddStateBits(NS_FRAME_IS_DIRTY);
+  bool offsetsNeedFixing =
+    prevSibling && prevSibling->GetType() == nsGkAtoms::textFrame;
+  if (offsetsNeedFixing) {
+    prevSibling->AddStateBits(TEXT_OFFSETS_NEED_FIXING);
   }
 
   // Insert text frame in its place
   nsFrameList textList(newTextFrame, newTextFrame);
   InsertFrames(parentFrame, kPrincipalList, prevSibling, textList);
 
+  if (offsetsNeedFixing) {
+    prevSibling->RemoveStateBits(TEXT_OFFSETS_NEED_FIXING);
+  }
+
   return NS_OK;
 }
 
 nsresult
 nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
                                                nsIPresShell* aPresShell,
                                                nsIFrame* aFrame,
                                                nsIFrame* aBlockFrame,
@@ -10148,24 +10154,30 @@ nsCSSFrameConstructor::RemoveFirstLetter
       // Next rip out the kid and replace it with the text frame
       RemoveFrame(kPrincipalList, kid);
 
       // Now that the old frames are gone, we can start pointing to our
       // new primary frame.
       textContent->SetPrimaryFrame(textFrame);
 
       // Wallpaper bug 822910.
-      if (prevSibling && prevSibling->GetType() == nsGkAtoms::textFrame) {
-        prevSibling->AddStateBits(NS_FRAME_IS_DIRTY);
+      bool offsetsNeedFixing =
+        prevSibling && prevSibling->GetType() == nsGkAtoms::textFrame;
+      if (offsetsNeedFixing) {
+        prevSibling->AddStateBits(TEXT_OFFSETS_NEED_FIXING);
       }
 
       // Insert text frame in its place
       nsFrameList textList(textFrame, textFrame);
       InsertFrames(aFrame, kPrincipalList, prevSibling, textList);
 
+      if (offsetsNeedFixing) {
+        prevSibling->RemoveStateBits(TEXT_OFFSETS_NEED_FIXING);
+      }
+
       *aStopLooking = true;
       NS_ASSERTION(!aBlockFrame->GetPrevContinuation(),
                    "should have the first continuation here");
       aBlockFrame->RemoveStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
       break;
     }
     else if (IsInlineFrame(kid)) {
       // Look inside child inline frame for the letter frame
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -4772,19 +4772,19 @@ nsBlockFrame::InsertFrames(ChildListID a
 
 static bool
 ShouldPutNextSiblingOnNewLine(nsIFrame* aLastFrame)
 {
   nsIAtom* type = aLastFrame->GetType();
   if (type == nsGkAtoms::brFrame) {
     return true;
   }
-  // XXX the IS_DIRTY check is a wallpaper for bug 822910.
+  // XXX the TEXT_OFFSETS_NEED_FIXING check is a wallpaper for bug 822910.
   if (type == nsGkAtoms::textFrame &&
-      !(aLastFrame->GetStateBits() & NS_FRAME_IS_DIRTY)) {
+      !(aLastFrame->GetStateBits() & TEXT_OFFSETS_NEED_FIXING)) {
     return aLastFrame->HasSignificantTerminalNewline();
   }
   return false;
 }
 
 void
 nsBlockFrame::AddFrames(nsFrameList& aFrameList, nsIFrame* aPrevSibling)
 {
--- a/layout/generic/nsFrameStateBits.h
+++ b/layout/generic/nsFrameStateBits.h
@@ -375,16 +375,20 @@ FRAME_STATE_BIT(Text, 27, TEXT_IS_ONLY_W
 // Set this bit if the textframe is known to be not only collapsible whitespace.
 FRAME_STATE_BIT(Text, 28, TEXT_ISNOT_ONLY_WHITESPACE)
 
 // -- Other state bits --------------------------------------------------------
 
 // Set when this text frame is mentioned in the userdata for mTextRun
 FRAME_STATE_BIT(Text, 29, TEXT_IN_TEXTRUN_USER_DATA)
 
+// This state bit is set on frames whose character data offsets need to be
+// fixed up
+FRAME_STATE_BIT(Text, 30, TEXT_OFFSETS_NEED_FIXING)
+
 // This state bit is set on frames that have some non-collapsed characters after
 // reflow
 FRAME_STATE_BIT(Text, 31, TEXT_HAS_NONCOLLAPSED_CHARACTERS)
 
 // This state bit is set on children of token MathML elements.
 // NOTE: TEXT_IS_IN_TOKEN_MATHML has a global state bit value that is shared
 //       with NS_FRAME_IS_PUSHED_FLOAT.
 FRAME_STATE_BIT(Text, 32, TEXT_IS_IN_TOKEN_MATHML)