Backout fix for bug 523468 due to crashing tests
authorRobert O'Callahan <robert@ocallahan.org>
Tue, 27 Oct 2009 21:46:39 +1300
changeset 34219 2e01e97f9ded0a13bf80ec60e6ffe5bbe8409a6d
parent 34217 5f94ccf6935e11b1f1e22957876f9de9b46dc35f (current diff)
parent 34218 ab761cbc7e1349a019808e9d11b0e729bb77d254 (diff)
child 34220 61ad31ff9d9e3ce67af1e39687e510d2d139601a
push id9956
push userrocallahan@mozilla.com
push dateTue, 27 Oct 2009 08:46:56 +0000
treeherdermozilla-central@2e01e97f9ded [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs523468
milestone1.9.3a1pre
Backout fix for bug 523468 due to crashing tests
layout/reftests/bugs/523468-1-ref.html
layout/reftests/bugs/523468-1.html
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -3665,27 +3665,16 @@ nsBlockFrame::DoReflowInlineFrames(nsBlo
       }
     }
   }
 #ifdef DEBUG
   if (gNoisyReflow) {
     printf("Line reflow status = %s\n", LineReflowStatusNames[lineReflowStatus]);
   }
 #endif
-
-  if (aLineLayout.GetDirtyNextLine()) {
-    nsBlockInFlowLineIterator iter(this, aLine, PR_FALSE);
-    if (iter.Next() && iter.GetLine()->IsInline()) {
-      iter.GetLine()->MarkDirty();
-      if (iter.GetContainer() != this) {
-        aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
-      }
-    }
-  }
-
   *aLineReflowStatus = lineReflowStatus;
 
   return rv;
 }
 
 /**
  * Reflow an inline frame. The reflow status is mapped from the frames
  * reflow status to the lines reflow status (not to our reflow status).
@@ -3716,17 +3705,26 @@ nsBlockFrame::ReflowInlineFrame(nsBlockR
   // Reflow the inline frame
   nsReflowStatus frameReflowStatus;
   PRBool         pushedFrame;
   nsresult rv = aLineLayout.ReflowFrame(aFrame, frameReflowStatus,
                                         nsnull, pushedFrame);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (frameReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) {
-    aLineLayout.SetDirtyNextLine();
+    // we need to ensure that the frame's nextinflow gets reflowed.
+    aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
+    nsBlockFrame* ourNext = static_cast<nsBlockFrame*>(GetNextInFlow());
+    if (ourNext && aFrame->GetNextInFlow()) {
+      PRBool isValid;
+      nsBlockInFlowLineIterator iter(ourNext, aFrame->GetNextInFlow(), &isValid);
+      if (isValid) {
+        iter.GetLine()->MarkDirty();
+      }
+    }
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 #ifdef REALLY_NOISY_REFLOW_CHILD
   nsFrame::ListTag(stdout, aFrame);
   printf(": status=%x\n", frameReflowStatus);
 #endif
 
@@ -3803,17 +3801,22 @@ nsBlockFrame::ReflowInlineFrame(nsBlockR
       aLine->SetBreakTypeAfter(breakType);
       if (NS_FRAME_IS_COMPLETE(frameReflowStatus)) {
         // Split line, but after the frame just reflowed
         rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (NS_INLINE_IS_BREAK_AFTER(frameReflowStatus) &&
             !aLineLayout.GetLineEndsInBR()) {
-          aLineLayout.SetDirtyNextLine();
+          // Mark next line dirty in case SplitLine didn't end up
+          // pushing any frames.
+          nsLineList_iterator next = aLine.next();
+          if (next != end_lines() && !next->IsBlock()) {
+            next->MarkDirty();
+          }
         }
       }
     }
   }
   else if (NS_FRAME_IS_TRUNCATED(frameReflowStatus) &&
            nsGkAtoms::placeholderFrame == aFrame->GetType()) {
     // if the frame is a placeholder and was complete but truncated (and not at the top
     // of page), the entire line will be pushed to give it another chance to not truncate.
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -372,17 +372,16 @@ nsInlineFrame::Reflow(nsPresContext*    
     return NS_OK;
   }
 
   // Set our own reflow state (additional state above and beyond
   // aReflowState)
   InlineReflowState irs;
   irs.mPrevFrame = nsnull;
   irs.mLineContainer = lineContainer;
-  irs.mLineLayout = aReflowState.mLineLayout;
   irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
   irs.mSetParentPointer = lazilySetParentPointer;
 
   nsresult rv;
   if (mFrames.IsEmpty()) {
     // Try to pull over one frame before starting so that we know
     // whether we have an anonymous block or not.
     PRBool complete;
@@ -664,17 +663,17 @@ nsInlineFrame::ReflowInlineFrame(nsPresC
     if (NS_INLINE_IS_BREAK_BEFORE(aStatus)) {
       if (aFrame != mFrames.FirstChild()) {
         // Change break-before status into break-after since we have
         // already placed at least one child frame. This preserves the
         // break-type so that it can be propagated upward.
         aStatus = NS_FRAME_NOT_COMPLETE |
           NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER |
           (aStatus & NS_INLINE_BREAK_TYPE_MASK);
-        PushFrames(aPresContext, aFrame, irs.mPrevFrame, irs);
+        PushFrames(aPresContext, aFrame, irs.mPrevFrame);
       }
       else {
         // Preserve reflow status when breaking-before our first child
         // and propagate it upward without modification.
         // Note: if we're lazily setting the frame pointer for our child 
         // frames, then we need to set it now. Don't return and leave the
         // remaining child frames in our child list with the wrong parent
         // frame pointer...
@@ -696,17 +695,17 @@ nsInlineFrame::ReflowInlineFrame(nsPresC
         rv = CreateNextInFlow(aPresContext, aFrame, newFrame);
         if (NS_FAILED(rv)) {
           return rv;
         }
       }
       nsIFrame* nextFrame = aFrame->GetNextSibling();
       if (nextFrame) {
         NS_FRAME_SET_INCOMPLETE(aStatus);
-        PushFrames(aPresContext, nextFrame, aFrame, irs);
+        PushFrames(aPresContext, nextFrame, aFrame);
       }
       else if (nsnull != GetNextInFlow()) {
         // We must return an incomplete status if there are more child
         // frames remaining in a next-in-flow that follows this frame.
         nsInlineFrame* nextInFlow = (nsInlineFrame*) GetNextInFlow();
         while (nsnull != nextInFlow) {
           if (nextInFlow->mFrames.NotEmpty()) {
             NS_FRAME_SET_INCOMPLETE(aStatus);
@@ -730,17 +729,17 @@ nsInlineFrame::ReflowInlineFrame(nsPresC
       nsIFrame* newFrame;
       rv = CreateNextInFlow(aPresContext, aFrame, newFrame);
       if (NS_FAILED(rv)) {
         return rv;
       }
       if (!reflowingFirstLetter) {
         nsIFrame* nextFrame = aFrame->GetNextSibling();
         if (nextFrame) {
-          PushFrames(aPresContext, nextFrame, aFrame, irs);
+          PushFrames(aPresContext, nextFrame, aFrame);
         }
       }
     }
   }
   return rv;
 }
 
 nsIFrame*
@@ -762,51 +761,44 @@ nsInlineFrame::PullOneFrame(nsPresContex
         // The blockChildren.ContainsFrame check performed by
         // ReparentFloatsForInlineChild will be fast because frame's ancestor
         // will be the first child of its containing block.
         ReparentFloatsForInlineChild(irs.mLineContainer, frame, PR_FALSE);
       }
       nextInFlow->mFrames.RemoveFirstChild();
       mFrames.InsertFrame(this, irs.mPrevFrame, frame);
       isComplete = PR_FALSE;
-      if (irs.mLineLayout) {
-        irs.mLineLayout->SetDirtyNextLine();
-      }
       nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, nextInFlow, this);
       break;
     }
     nextInFlow = (nsInlineFrame*) nextInFlow->GetNextInFlow();
     irs.mNextInFlow = nextInFlow;
   }
 
   *aIsComplete = isComplete;
   return frame;
 }
 
 void
 nsInlineFrame::PushFrames(nsPresContext* aPresContext,
                           nsIFrame* aFromChild,
-                          nsIFrame* aPrevSibling,
-                          InlineReflowState& aState)
+                          nsIFrame* aPrevSibling)
 {
   NS_PRECONDITION(aFromChild, "null pointer");
   NS_PRECONDITION(aPrevSibling, "pushing first child");
   NS_PRECONDITION(aPrevSibling->GetNextSibling() == aFromChild, "bad prev sibling");
 
 #ifdef NOISY_PUSHING
   printf("%p pushing aFromChild %p, disconnecting from prev sib %p\n", 
          this, aFromChild, aPrevSibling);
 #endif
 
   // Add the frames to our overflow list (let our next in flow drain
   // our overflow list when it is ready)
   SetOverflowFrames(aPresContext, mFrames.RemoveFramesAfter(aPrevSibling));
-  if (aState.mLineLayout) {
-    aState.mLineLayout->SetDirtyNextLine();
-  }
 }
 
 
 //////////////////////////////////////////////////////////////////////
 
 PRIntn
 nsInlineFrame::GetSkipSides() const
 {
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -149,25 +149,23 @@ public:
   }
 
 protected:
   // Additional reflow state used during our reflow methods
   struct InlineReflowState {
     nsIFrame* mPrevFrame;
     nsInlineFrame* mNextInFlow;
     nsIFrame*      mLineContainer;
-    nsLineLayout*  mLineLayout;
     PRPackedBool mSetParentPointer;  // when reflowing child frame first set its
                                      // parent frame pointer
 
     InlineReflowState()  {
       mPrevFrame = nsnull;
       mNextInFlow = nsnull;
       mLineContainer = nsnull;
-      mLineLayout = nsnull;
       mSetParentPointer = PR_FALSE;
     }
   };
 
   nsInlineFrame(nsStyleContext* aContext) : nsInlineFrameSuper(aContext) {}
 
   virtual PRIntn GetSkipSides() const;
 
@@ -193,18 +191,17 @@ protected:
                                     PRBool aReparentSiblings);
 
   virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
                                  InlineReflowState& rs,
                                  PRBool* aIsComplete);
 
   virtual void PushFrames(nsPresContext* aPresContext,
                           nsIFrame* aFromChild,
-                          nsIFrame* aPrevSibling,
-                          InlineReflowState& aState);
+                          nsIFrame* aPrevSibling);
 
 };
 
 //----------------------------------------------------------------------
 
 /**
  * Variation on inline-frame used to manage lines for line layout in
  * special situations (:first-line style in particular).
--- a/layout/generic/nsLineLayout.h
+++ b/layout/generic/nsLineLayout.h
@@ -151,18 +151,17 @@ protected:
 #define LL_LASTFLOATWASLETTERFRAME     0x00000080
 #define LL_LINEISEMPTY                 0x00000100
 #define LL_LINEENDSINBR                0x00000200
 #define LL_NEEDBACKUP                  0x00000400
 #define LL_INFIRSTLINE                 0x00000800
 #define LL_GOTLINEBOX                  0x00001000
 #define LL_INFIRSTLETTER               0x00002000
 #define LL_HASBULLET                   0x00004000
-#define LL_DIRTYNEXTLINE               0x00008000
-#define LL_LASTFLAG                    LL_DIRTYNEXTLINE
+#define LL_LASTFLAG                    LL_HASBULLET
 
   void SetFlag(PRUint32 aFlag, PRBool aValue)
   {
     NS_ASSERTION(aFlag<=LL_LASTFLAG, "bad flag");
     NS_ASSERTION(aValue==PR_FALSE || aValue==PR_TRUE, "bad value");
     if (aValue) { // set flag
       mFlags |= aFlag;
     }
@@ -242,25 +241,16 @@ public:
   PRBool GetInFirstLine() const {
     return GetFlag(LL_INFIRSTLINE);
   }
 
   void SetInFirstLine(PRBool aSetting) {
     SetFlag(LL_INFIRSTLINE, aSetting);
   }
 
-  // Calling this during block reflow ensures that the next line of inlines
-  // will be marked dirty, if there is one.
-  void SetDirtyNextLine() {
-    SetFlag(LL_DIRTYNEXTLINE, PR_TRUE);
-  }
-  PRBool GetDirtyNextLine() {
-    return GetFlag(LL_DIRTYNEXTLINE);
-  }
-
   //----------------------------------------
 
   nsPresContext* mPresContext;
 
   /**
    * Record where an optional break could have been placed. During line reflow,
    * frames containing optional break points (e.g., whitespace in text frames)
    * can call SetLastOptionalBreakPosition to record where a break could
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -5982,17 +5982,24 @@ nsTextFrame::SetLength(PRInt32 aLength, 
   // pulled, content is moving to or from the next line and the next line
   // must be reflowed.
   // If the next-continuation is dirty, then we should dirty the next line now
   // because we may have skipped doing it if we dirtied it in
   // CharacterDataChanged. This is ugly but teaching FrameNeedsReflow
   // and ChildIsDirty to handle a range of frames would be worse.
   if (aLineLayout &&
       (end != f->mContentOffset || (f->GetStateBits() & NS_FRAME_IS_DIRTY))) {
-    aLineLayout->SetDirtyNextLine();
+    const nsLineList::iterator* line = aLineLayout->GetLine();
+    nsBlockFrame* block = do_QueryFrame(aLineLayout->GetLineContainerFrame());
+    if (line && block) {
+      nsLineList::iterator next = line->next();
+      if (next != block->end_lines() && !next->IsBlock()) {
+        next->MarkDirty();
+      }
+    }
   }
 
   if (end < f->mContentOffset) {
     // Our frame is shrinking. Give the text to our next in flow.
     f->mContentOffset = end;
     if (f->GetTextRun() != mTextRun) {
       ClearTextRun();
       f->ClearTextRun();
deleted file mode 100644
--- a/layout/reftests/bugs/523468-1-ref.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-c<br>
-da<br>
-b
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/523468-1.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML>
-<html style="width:1px">
-<body><span><span id="y"></span>a b</span>
-<script>
-var y = document.getElementById("y");
-document.documentElement.offsetHeight;
-y.appendChild(document.createTextNode("c d"));
-</script>
-</body>
-</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1325,11 +1325,10 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") ==
 == 513318-1.xul 513318-1-ref.xul
 != 513318-2.xul 513318-2-ref.xul
 != 513318-3.xul 513318-3-ref.xul
 == 521525-1.html 521525-1-ref.html
 == 521525-2.html 521525-2-ref.html
 == 521539-1.html 521539-1-ref.html
 == 520421-1.html 520421-1-ref.html
 == 521685-1.html 521685-1-ref.html
+== 524175-1.html 524175-1-ref.html
 == 523096-1.html 523096-1-ref.html
-== 523468-1.html 523468-1-ref.html
-== 524175-1.html 524175-1-ref.html