Bug 472950. Restrict the lazy-parent-pointer optimization so it isn't used if we already have child frames. r=dbaron
authorRobert O'Callahan <robert@ocallahan.org>
Sat, 07 Feb 2009 21:34:27 +1300
changeset 24722 b1358e48e6ca47aa16aa845ee274f7d9c19a066f
parent 24721 08281f2915ef8d21debe6661f56cf33f6f491fc9
child 24723 a142df653655b96f2c65088068b0ac7299184213
push idunknown
push userunknown
push dateunknown
reviewersdbaron
bugs472950
milestone1.9.2a1pre
Bug 472950. Restrict the lazy-parent-pointer optimization so it isn't used if we already have child frames. r=dbaron
layout/generic/crashtests/472950-1.html
layout/generic/crashtests/crashtests.list
layout/generic/nsInlineFrame.cpp
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/472950-1.html
@@ -0,0 +1,21 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<style>div::first-letter { color: green; }</style>
+<script>
+
+function boom()
+{
+  var e = document.getElementById("e");
+  document.documentElement.style.direction = "rtl";
+  e.style.whiteSpace = "pre";
+}
+
+</script>
+</head>
+<body onload="boom();">
+
+<div><span style="direction: rtl;" id="e"><span>
+      
+    </span>A B</span></div>
+    
+</body></html></html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -175,8 +175,9 @@ load 452157-1.html
 load 452157-2.html
 load 452157-3.html
 load 455171-1.html
 load 455171-2.html
 load 455171-3.html
 load 457375.html
 load 467487-1.html
 load 468207-1.html
+load 472950-1.html
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -297,24 +297,29 @@ nsInlineFrame::Reflow(nsPresContext*    
     nsIFrame* prevOverflowFrames = prevInFlow->GetOverflowFrames(aPresContext, PR_TRUE);
 
     if (prevOverflowFrames) {
       // When pushing and pulling frames we need to check for whether any
       // views need to be reparented.
       nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, prevOverflowFrames,
                                                   prevInFlow, this);
 
-      if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
-        // If it's the initial reflow, then our child list must be empty, so
-        // just set the child list rather than calling InsertFrame(). This avoids
-        // having to get the last child frame in the list.
+      // Check if we should do the lazilySetParentPointer optimization.
+      // Only do it in simple cases where we're being reflowed for the
+      // first time, nothing (e.g. bidi resolution) has already given
+      // us children, and there's no next-in-flow, so all our frames
+      // will be taken from prevOverflowFrames.
+      if ((GetStateBits() & NS_FRAME_FIRST_REFLOW) && mFrames.IsEmpty() &&
+          !GetNextInFlow()) {
+        // If our child list is empty, just set the child list rather than
+        // calling InsertFrame(). This avoids having to get the last child
+        // frame in the list.
         // Note that we don't set the parent pointer for the new frames. Instead wait
         // to do this until we actually reflow the frame. If the overflow list contains
         // thousands of frames this is a big performance issue (see bug #5588)
-        NS_ASSERTION(mFrames.IsEmpty(), "child list is not empty for initial reflow");
         mFrames.SetFrames(prevOverflowFrames);
         lazilySetParentPointer = PR_TRUE;
       } else {
         // Assign all floats to our block if necessary
         if (lineContainer && lineContainer->GetPrevContinuation()) {
           ReparentFloatsForInlineChild(lineContainer, prevOverflowFrames, PR_TRUE);
         }
         // Insert the new frames at the beginning of the child list