Bug 256180 layout part - Increase MAX_REFLOW_DEPTH to reduce the probability of content going silently missing. draft
authorHenri Sivonen <hsivonen@hsivonen.fi>
Thu, 14 Sep 2017 11:01:06 +0300
changeset 668180 579a9e65ddc6af22b2a63eea318f50f6eb7c397b
parent 664796 1a277ee143edcb7cfc96da8dcf229558c174d2ee
child 668181 eddb79d545b78660e0ae3c4188d5bcb2ac9857e5
push id80955
push userbmo:hsivonen@hsivonen.fi
push dateThu, 21 Sep 2017 08:11:26 +0000
bugs256180
milestone57.0a1
Bug 256180 layout part - Increase MAX_REFLOW_DEPTH to reduce the probability of content going silently missing. MozReview-Commit-ID: 7Ui0tVlLEQM
layout/generic/nsIFrame.h
layout/reftests/bugs/256180-1-ref.html
layout/reftests/bugs/256180-1.html
layout/reftests/bugs/256180-2-ref.html
layout/reftests/bugs/256180-2.html
layout/reftests/bugs/256180-3-ref.html
layout/reftests/bugs/256180-3.html
layout/reftests/bugs/256180-4-ref.html
layout/reftests/bugs/256180-4.html
layout/reftests/bugs/reftest.list
layout/tools/reftest/reftest.jsm
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -8,17 +8,28 @@
 
 #ifndef nsIFrame_h___
 #define nsIFrame_h___
 
 #ifndef MOZILLA_INTERNAL_API
 #error This header/class should only be used within Mozilla code. It should not be used by extensions.
 #endif
 
-#define MAX_REFLOW_DEPTH 200
+#if (defined(XP_WIN) && !defined(HAVE_64BIT_BUILD)) || defined(ANDROID)
+// Blink's magic depth limit from its HTML parser plus a little. Involves only
+// a small increase to the default runtime stack size on 32-bit Windows with
+// display: block and fits within the default stack available on 32-bit Android
+// on ARM.
+#define MAX_REFLOW_DEPTH 590
+#else
+// Blink's magic depth limit from its HTML parser times two. Also just about fits
+// within the system default runtime stack limit on Mac and Linux with
+// display: table-cell.
+#define MAX_REFLOW_DEPTH 1026
+#endif
 
 /* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually
    going to be eliminated, and all callers will use nsFrame instead.  At the moment
    we're midway through this process, so you will see inlined functions and member
    variables in this file.  -dwh */
 
 #include <algorithm>
 #include <stdio.h>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-1-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>1026-deep display: table-cell</title>
+</head>
+<body>
+<h1>1026-element-deep display: table-cell</h1>
+<p>Actual depth (including text leaves): 1027
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-1.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>1026-element-deep display: table-cell</title>
+<script>
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+function count() {
+    var depth = 0;
+    var deepest = 0;
+    var current = document;
+    var next = null;
+    outer: for (;;) {
+        if ((next = current.firstChild)) {
+            depth++;
+            if (depth > deepest) {
+                deepest = depth;
+            }
+            current = next;
+            continue;
+        }
+        for (;;) {
+            if ((next = current.nextSibling)) {
+                current = next;
+                break;
+            }
+            current = current.parentNode;
+            depth--;
+            if (current == document) {
+                break outer;
+            }
+        }
+    }
+
+    var h1 = document.getElementsByTagName("h1")[0];
+    var p = document.createElement("p");
+    var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
+    p.appendChild(t);
+    h1.parentNode.insertBefore(p, h1.nextSibling);
+}
+
+function deep() {
+    var t = document.createTextNode("PASS");
+    var div = document.createElement("div");
+    div.appendChild(t);
+    for (var i = 0; i < 1023; i++) {
+        var another = document.createElement("div");
+        another.appendChild(div);
+        div = another;
+    }
+    document.body.appendChild(div);
+    count();
+}
+
+window.addEventListener('DOMContentLoaded', deep, false);
+</script>
+<style>
+    div {
+        display: table-cell;
+    }
+</style>
+</head>
+<body>
+<h1>1026-element-deep display: table-cell</h1>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-2-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>585-deep display: table-cell</title>
+</head>
+<body>
+<h1>585-element-deep display: table-cell</h1>
+<p>Actual depth (including text leaves): 586
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-2.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>585-element-deep display: table-cell</title>
+<script>
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+function count() {
+    var depth = 0;
+    var deepest = 0;
+    var current = document;
+    var next = null;
+    outer: for (;;) {
+        if ((next = current.firstChild)) {
+            depth++;
+            if (depth > deepest) {
+                deepest = depth;
+            }
+            current = next;
+            continue;
+        }
+        for (;;) {
+            if ((next = current.nextSibling)) {
+                current = next;
+                break;
+            }
+            current = current.parentNode;
+            depth--;
+            if (current == document) {
+                break outer;
+            }
+        }
+    }
+
+    var h1 = document.getElementsByTagName("h1")[0];
+    var p = document.createElement("p");
+    var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
+    p.appendChild(t);
+    h1.parentNode.insertBefore(p, h1.nextSibling);
+}
+
+function deep() {
+    var t = document.createTextNode("PASS");
+    var div = document.createElement("div");
+    div.appendChild(t);
+    for (var i = 0; i < 582; i++) {
+        var another = document.createElement("div");
+        another.appendChild(div);
+        div = another;
+    }
+    document.body.appendChild(div);
+    count();
+}
+
+window.addEventListener('DOMContentLoaded', deep, false);
+</script>
+<style>
+    div {
+        display: table-cell;
+    }
+</style>
+</head>
+<body>
+<h1>585-element-deep display: table-cell</h1>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-3-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>1026-deep display: block</title>
+</head>
+<body>
+<h1>1026-element-deep display: block</h1>
+<p>Actual depth (including text leaves): 1027
+<div>PASS</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-3.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>1026-element-deep display: block</title>
+<script>
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+function count() {
+    var depth = 0;
+    var deepest = 0;
+    var current = document;
+    var next = null;
+    outer: for (;;) {
+        if ((next = current.firstChild)) {
+            depth++;
+            if (depth > deepest) {
+                deepest = depth;
+            }
+            current = next;
+            continue;
+        }
+        for (;;) {
+            if ((next = current.nextSibling)) {
+                current = next;
+                break;
+            }
+            current = current.parentNode;
+            depth--;
+            if (current == document) {
+                break outer;
+            }
+        }
+    }
+
+    var h1 = document.getElementsByTagName("h1")[0];
+    var p = document.createElement("p");
+    var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
+    p.appendChild(t);
+    h1.parentNode.insertBefore(p, h1.nextSibling);
+}
+
+function deep() {
+    var t = document.createTextNode("PASS");
+    var div = document.createElement("div");
+    div.appendChild(t);
+    for (var i = 0; i < 1023; i++) {
+        var another = document.createElement("div");
+        another.appendChild(div);
+        div = another;
+    }
+    document.body.appendChild(div);
+    count();
+}
+
+window.addEventListener('DOMContentLoaded', deep, false);
+</script>
+</head>
+<body>
+<h1>1026-element-deep display: block</h1>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-4-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>585-deep display: block</title>
+</head>
+<body>
+<h1>585-element-deep display: block</h1>
+<p>Actual depth (including text leaves): 586
+<div>PASS</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/256180-4.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>585-element-deep display: block</title>
+<script>
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+function count() {
+    var depth = 0;
+    var deepest = 0;
+    var current = document;
+    var next = null;
+    outer: for (;;) {
+        if ((next = current.firstChild)) {
+            depth++;
+            if (depth > deepest) {
+                deepest = depth;
+            }
+            current = next;
+            continue;
+        }
+        for (;;) {
+            if ((next = current.nextSibling)) {
+                current = next;
+                break;
+            }
+            current = current.parentNode;
+            depth--;
+            if (current == document) {
+                break outer;
+            }
+        }
+    }
+
+    var h1 = document.getElementsByTagName("h1")[0];
+    var p = document.createElement("p");
+    var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
+    p.appendChild(t);
+    h1.parentNode.insertBefore(p, h1.nextSibling);
+}
+
+function deep() {
+    var t = document.createTextNode("PASS");
+    var div = document.createElement("div");
+    div.appendChild(t);
+    for (var i = 0; i < 582; i++) {
+        var another = document.createElement("div");
+        another.appendChild(div);
+        div = another;
+    }
+    document.body.appendChild(div);
+    count();
+}
+
+window.addEventListener('DOMContentLoaded', deep, false);
+</script>
+</head>
+<body>
+<h1>585-element-deep display: block</h1>
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -33,16 +33,20 @@ HTTP(..) == 10209-3.html 10209-3-ref.htm
 == 18217-zorder-1.html 18217-zorder-ref.html
 == 18217-zorder-2.html 18217-zorder-ref.html
 == 18217-zorder-3.html 18217-zorder-ref-inline.html
 == 18217-zorder-4.html 18217-zorder-ref-inline-table.html
 == 18217-zorder-5.html 18217-zorder-ref-inline-table.html
 == 23604-1.html 23604-1-ref.html
 == 23604-2.html 23604-2-ref.html
 != 24998-1.html 24998-1-ref.html
+skip-if(isDebugBuild||Android||AddressSanitizer||(winWidget&&(!is64Bit))) == 256180-1.html 256180-1-ref.html
+skip-if(isDebugBuild||(Android&&is64Bit)) == 256180-2.html 256180-2-ref.html
+skip-if(isDebugBuild||Android||AddressSanitizer||(winWidget&&(!is64Bit))) == 256180-3.html 256180-3-ref.html
+skip-if(isDebugBuild||(Android&&is64Bit)) == 256180-4.html 256180-4-ref.html
 == 25888-1l.html 25888-1l-ref.html
 != 25888-1l.html 25888-1l-notref.html
 == 25888-1r.html 25888-1r-ref.html
 != 25888-1r.html 25888-1r-notref.html
 == 25888-2l.html 25888-2l-ref.html
 == 25888-2r.html 25888-2r-ref.html
 == 25888-3l.html 25888-3l-ref.html
 == 25888-3r.html 25888-3r-ref.html
--- a/layout/tools/reftest/reftest.jsm
+++ b/layout/tools/reftest/reftest.jsm
@@ -729,16 +729,18 @@ function BuildConditionSandbox(aURL) {
     // Shortcuts for widget toolkits.
     sandbox.Android = xr.OS == "Android";
     sandbox.cocoaWidget = xr.widgetToolkit == "cocoa";
     sandbox.gtkWidget = xr.widgetToolkit == "gtk2"
                         || xr.widgetToolkit == "gtk3";
     sandbox.qtWidget = xr.widgetToolkit == "qt";
     sandbox.winWidget = xr.widgetToolkit == "windows";
 
+    sandbox.is64Bit = xr.is64Bit;
+
     // Scrollbars that are semi-transparent. See bug 1169666.
     sandbox.transparentScrollbars = xr.widgetToolkit == "gtk3";
 
     if (sandbox.Android) {
         var sysInfo = CC["@mozilla.org/system-info;1"].getService(CI.nsIPropertyBag2);
 
         // This is currently used to distinguish Android 4.0.3 (SDK version 15)
         // and later from Android 2.x