mRectListHead.x needs a sentinel value (not y). Clarify the use of nscoord sentinel values and handle float nscoord too. b=541869 r=roc r=jonitis
authorMats Palmgren <matspal@gmail.com>
Wed, 27 Jan 2010 09:35:37 +0100
changeset 37534 f155f30508750f0856eabf2bc0934b6c4c8e2b2b
parent 37533 263b6541c83fead708070cf98df0ee49bf4c79c4
child 37535 5f631340007c22da2d33ddcd06810f989b4718a2
push id11363
push usermpalmgren@mozilla.com
push dateWed, 27 Jan 2010 08:35:53 +0000
treeherdermozilla-central@5f631340007c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, jonitis
bugs541869
milestone1.9.3a1pre
mRectListHead.x needs a sentinel value (not y). Clarify the use of nscoord sentinel values and handle float nscoord too. b=541869 r=roc r=jonitis
gfx/src/nsRegion.cpp
layout/base/crashtests/541869-1.xhtml
layout/base/crashtests/541869-2.html
layout/base/crashtests/crashtests.list
--- a/gfx/src/nsRegion.cpp
+++ b/gfx/src/nsRegion.cpp
@@ -33,16 +33,32 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "prlock.h"
 #include "nsRegion.h"
 #include "nsISupportsImpl.h"
 
+/*
+ * The SENTINEL values below guaranties that a < or >
+ * comparison with it will be false for all values of the
+ * underlying nscoord type.  E.g. this is always false:
+ *   aCoord > NS_COORD_GREATER_SENTINEL
+ * Setting the mRectListHead dummy rectangle to these values
+ * allows us to loop without checking for the list end.
+ */
+#ifdef NS_COORD_IS_FLOAT
+#define NS_COORD_LESS_SENTINEL nscoord_MIN
+#define NS_COORD_GREATER_SENTINEL nscoord_MAX
+#else
+#define NS_COORD_LESS_SENTINEL PR_INT32_MIN
+#define NS_COORD_GREATER_SENTINEL PR_INT32_MAX
+#endif
+
 // Fast inline analogues of nsRect methods for nsRegion::nsRectFast.
 // Check for emptiness is not required - it is guaranteed by caller.
 
 inline PRBool nsRegion::nsRectFast::Contains (const nsRect& aRect) const
 {
   return (PRBool) ((aRect.x >= x) && (aRect.y >= y) &&
                    (aRect.XMost () <= XMost ()) && (aRect.YMost () <= YMost ()));
 }
@@ -344,51 +360,49 @@ inline void nsRegion::RestoreLinkChain (
 void nsRegion::InsertInPlace (RgnRect* aRect, PRBool aOptimizeOnFly)
 {
   if (mRectCount == 0)
     InsertAfter (aRect, &mRectListHead);
   else
   {
     if (aRect->y > mCurRect->y)
     {
-      mRectListHead.y = PR_INT32_MAX;
-
+      mRectListHead.y = NS_COORD_GREATER_SENTINEL;
       while (aRect->y > mCurRect->next->y)
         mCurRect = mCurRect->next;
 
+      mRectListHead.x = NS_COORD_GREATER_SENTINEL;
       while (aRect->y == mCurRect->next->y && aRect->x > mCurRect->next->x)
         mCurRect = mCurRect->next;
 
       InsertAfter (aRect, mCurRect);
     } else
     if (aRect->y < mCurRect->y)
     {
-      mRectListHead.y = PR_INT32_MIN;
-
+      mRectListHead.y = NS_COORD_LESS_SENTINEL;
       while (aRect->y < mCurRect->prev->y)
         mCurRect = mCurRect->prev;
 
+      mRectListHead.x = NS_COORD_LESS_SENTINEL;
       while (aRect->y == mCurRect->prev->y && aRect->x < mCurRect->prev->x)
         mCurRect = mCurRect->prev;
 
       InsertBefore (aRect, mCurRect);
     } else
     {
       if (aRect->x > mCurRect->x)
       {
-        mRectListHead.y = PR_INT32_MAX;
-
+        mRectListHead.x = NS_COORD_GREATER_SENTINEL;
         while (aRect->y == mCurRect->next->y && aRect->x > mCurRect->next->x)
           mCurRect = mCurRect->next;
 
         InsertAfter (aRect, mCurRect);
       } else
       {
-        mRectListHead.y = PR_INT32_MIN;
-
+        mRectListHead.x = NS_COORD_LESS_SENTINEL;
         while (aRect->y == mCurRect->prev->y && aRect->x < mCurRect->prev->x)
           mCurRect = mCurRect->prev;
 
         InsertBefore (aRect, mCurRect);
       }
     }
   }
 
@@ -666,18 +680,18 @@ nsRegion& nsRegion::And (const nsRegion&
             pSrcRgn1 = pSrcRgn2;
             pSrcRgn2 = Tmp;
           }
 
 
           SetToElements (0);
           pSrcRgn2->SaveLinkChain ();
 
-          pSrcRgn1->mRectListHead.y = PR_INT32_MAX;
-          pSrcRgn2->mRectListHead.y = PR_INT32_MAX;
+          pSrcRgn1->mRectListHead.y = NS_COORD_GREATER_SENTINEL;
+          pSrcRgn2->mRectListHead.y = NS_COORD_GREATER_SENTINEL;
 
           for (RgnRect* pSrcRect1 = pSrcRgn1->mRectListHead.next ;
                pSrcRect1->y < pSrcRgn2->mBoundRect.YMost () ; pSrcRect1 = pSrcRect1->next)
           {
             if (pSrcRect1->Intersects (pSrcRgn2->mBoundRect))   // Rectangle intersects region. Process each rectangle
             {
               RgnRect* pPrev2 = &pSrcRgn2->mRectListHead;
 
@@ -746,17 +760,17 @@ nsRegion& nsRegion::And (const nsRegion&
 
           if (&aRegion == this)   // Copy region if it is both source and result
           {
             TmpRegion.Copy (aRegion);
             pSrcRegion = &TmpRegion;
           }
 
           SetToElements (0);
-          pSrcRegion->mRectListHead.y = PR_INT32_MAX;
+          pSrcRegion->mRectListHead.y = NS_COORD_GREATER_SENTINEL;
 
           for (const RgnRect* pSrcRect = pSrcRegion->mRectListHead.next ;
                pSrcRect->y < aRectFast.YMost () ; pSrcRect = pSrcRect->next)
           {
             if (TmpRect.IntersectRect (*pSrcRect, aRectFast))
               InsertInPlace (new RgnRect (TmpRect));
           }
 
@@ -1071,17 +1085,17 @@ void nsRegion::SubRect (const nsRectFast
   if (&aResult == this)           // Copy region if it is both source and result
   {
     TmpRegion.Copy (*this);
     pSrcRegion = &TmpRegion;
   }
 
   aResult.SetToElements (0);
 
-  (const_cast<nsRegion*>(pSrcRegion))->mRectListHead.y = PR_INT32_MAX;
+  const_cast<nsRegion*>(pSrcRegion)->mRectListHead.y = NS_COORD_GREATER_SENTINEL;
   const RgnRect* pSrcRect = pSrcRegion->mRectListHead.next;
 
   for ( ; pSrcRect->y < aRect.YMost () ; pSrcRect = pSrcRect->next)
   {
     nsRectFast TmpRect;
 
     // If bottom of current rectangle is above the top of aRect then this rectangle
     // could be moved to aCompleted region. Successive aRect rectangles from ordered
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/541869-1.xhtml
@@ -0,0 +1,5 @@
+<html xmlns="http://www.w3.org/1999/xhtml"  style="right: 10000px; top: 11121164%; position: fixed;"><div>X</div>
+<script>
+window.addEventListener("load", function() { document.documentElement.style.letterSpacing = '21em'; }, false);
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/541869-2.html
@@ -0,0 +1,5 @@
+<html style="padding: 9007199254740991%;">
+<body onload="document.getElementById('f').style.border = 'none';" style="display: inline">
+<iframe id="f"></iframe>
+</body>
+</html>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -270,8 +270,10 @@ load 501878-1.html
 load 503936-1.html
 load 526378-1.xul
 load 535721-1.xhtml
 load 535911-1.xhtml
 load 536623-1.xhtml
 load 537059-1.xhtml
 load 537141-1.xhtml
 load 537562-1.xhtml
+load 541869-1.xhtml
+load 541869-2.html