WebCore:
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Mar 2008 07:08:43 +0000 (07:08 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Mar 2008 07:08:43 +0000 (07:08 +0000)
        Reviewed by Sam and Oliver.

        - fixed http://bugs.webkit.org/show_bug.cgi?id=16289
        - fixed Acid3 tests 26 and 27 (not exactly the same issue but related)

        * bindings/js/JSNodeCustom.cpp:
        (WebCore::JSNode::mark): When marking a node that's in-document,
        mark the owner document if it hasn't been already. This means holding on
        to a single node from an unreferenced document now keeps the whole document alive.

        We are now at 90/100 on Acid3.

LayoutTests:

        Reviewed by Sam and Oliver.

        - test for http://bugs.webkit.org/show_bug.cgi?id=16289
        - test for Acid3 tests 26 and 27 (not exactly the same issue but related)

        * fast/dom/gc-11-expected.txt: Added. Test case from bug 16289.
        * fast/dom/gc-11.html: Added.
        * fast/dom/gc-acid3.html: Added. DOM garbage collection part of Acid3.
        * fast/dom/gc-acid3-expected.txt: Added.
        * fast/dom/gc-6-expected.txt: Updated results. The old assumptions of this test
        were in conflict with the requirements of Acid3.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@30790 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/dom/gc-11-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/gc-11.html [new file with mode: 0644]
LayoutTests/fast/dom/gc-6-expected.txt
LayoutTests/fast/dom/gc-acid3-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/gc-acid3.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/bindings/js/JSNodeCustom.cpp

index e55795c5de7d4d9db9359559d90da39dc634b19e..e5d72d44c87468affd8359182635fda63ca06c48 100644 (file)
@@ -1,3 +1,17 @@
+2008-03-04  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Sam and Oliver.
+
+        - test for http://bugs.webkit.org/show_bug.cgi?id=16289
+        - test for Acid3 tests 26 and 27 (not exactly the same issue but related)
+
+        * fast/dom/gc-11-expected.txt: Added. Test case from bug 16289.
+        * fast/dom/gc-11.html: Added.
+        * fast/dom/gc-acid3.html: Added. DOM garbage collection part of Acid3.
+        * fast/dom/gc-acid3-expected.txt: Added.
+        * fast/dom/gc-6-expected.txt: Updated results. The old assumptions of this test
+        were in conflict with the requirements of Acid3.
+
 2008-03-04  Dan Bernstein  <mitz@apple.com>
 
         - test for http://bugs.webkit.org/show_bug.cgi?id=17676
diff --git a/LayoutTests/fast/dom/gc-11-expected.txt b/LayoutTests/fast/dom/gc-11-expected.txt
new file mode 100644 (file)
index 0000000..ff43ca4
--- /dev/null
@@ -0,0 +1 @@
+SUCCESS
diff --git a/LayoutTests/fast/dom/gc-11.html b/LayoutTests/fast/dom/gc-11.html
new file mode 100644 (file)
index 0000000..97e27a6
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+</script>
+  <script type="text/javascript">
+    var xmlNode = null;
+
+    loadData();
+    setTimeout("testData()", 0);
+
+    function testData() {
+        var i = 0;
+        var s;
+        while (i < 5000) {
+            i = i+1.11;
+            s = s + " ";
+        }
+        
+        document.write(xmlNode.ownerDocument.data ? "<p>SUCCESS</p>" : "<p>FAILURE</p>");
+        if (window.layoutTestController)
+             layoutTestController.notifyDone();
+    }
+
+    function loadData() {
+        var xmlDoc = document.implementation.createDocument("", "doc", null);
+        if (!xmlDoc.documentElement)
+            xmlDoc.appendChild(document.createElement("doc"));
+        xmlNode = xmlDoc.documentElement;
+        xmlNode.ownerDocument.data = 1;
+     }
+  </script>
+ </head>
+ <body>
+This test checks that custom data on reachable DOM nodes is not lost during GC. If it passes, it should say SUCCESS below.
+ </body>
+</html>
index 51ce81db5d422b60731ff49bd35f0b01042ee139..db6fcc87129a377f3da345a527f927e04f6e81d8 100644 (file)
@@ -4,6 +4,6 @@ The output should be the following pieces of text on lines by themselves: "B", "
 
 B
 [object HTMLElement]
-null
+[object HTMLElement]
 [object HTMLDocument]
 
diff --git a/LayoutTests/fast/dom/gc-acid3-expected.txt b/LayoutTests/fast/dom/gc-acid3-expected.txt
new file mode 100644 (file)
index 0000000..ddec251
--- /dev/null
@@ -0,0 +1,3 @@
+There should be no assertion failures below, but the word DONE should show up.
+
+DONE
diff --git a/LayoutTests/fast/dom/gc-acid3.html b/LayoutTests/fast/dom/gc-acid3.html
new file mode 100644 (file)
index 0000000..113661f
--- /dev/null
@@ -0,0 +1,77 @@
+  <div class="buckets"
+   ><p id="bucket1" class="z"></p
+   ><p id="bucket2" class="z"></p
+   ><p id="bucket3" class="z"></p
+   ><p id="bucket4" class="z"></p
+   ><p id="bucket5" class="z"></p
+   ><p id="bucket6" class="z"></p>
+  </div>
+<p>There should be no assertion failures below, but the word DONE should show up.</p>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+}
+</script>
+<script>
+  function fail(message) {
+      document.write(message + "<br>");
+  }
+  function assert(condition, message) {
+    if (!condition)
+      fail(message);
+  }
+  function assertEquals(expression, value, message) {
+    if (expression != value) {
+      expression = (""+expression).replace(/[\r\n]+/g, "\\n");
+      value = (""+value).replace(/\r?\n/g, "\\n");
+      fail("expected: " + value + ", got: " + expression + " - " + message);
+    }
+  }
+
+
+      var d;
+      // e1 - an element that's in a document
+      d = document.implementation.createDocument(null, null, null);
+      var e1 = d.createElement('test1');
+      d.appendChild(d.createElement('root'));
+      d.documentElement.appendChild(e1);
+      assert(e1.parentNode, "e1 - parent element doesn't exist");
+      assert(e1.parentNode.ownerDocument, "e1 - document doesn't exist");
+      // e2 - an element that's not in a document
+      d = document.implementation.createDocument(null, null, null);
+      var e2 = d.createElement('test2');
+      d.createElement('root').appendChild(e2);
+      assert(e2.parentNode, "e2 - parent element doesn't exist");
+      assert(e2.parentNode.ownerDocument, "e2 - document doesn't exist");
+      // now try to decouple them
+      d = null;
+
+      kungFuDeathGrip = [e1, e2];
+      assert(e1.parentNode, "e1 - parent element doesn't exist after dropping reference to document");
+      assert(e1.parentNode.ownerDocument, "e1 - document doesn't exist after dropping reference to document");
+      assert(e2.parentNode, "e2 - parent element doesn't exist after dropping reference to document");
+      assert(e2.parentNode.ownerDocument, "e2 - document doesn't exist after dropping reference to document");
+      var loops = ((new Date().valueOf() - 1.1e12) / 32e9) * 0x500; // increases linearly over time
+      for (var i = 0; i < loops; i += 1) {
+        // we want to force a GC here, so we use up lots of memory
+        // we take the opportunity to sneak in a perf test to make DOM and JS stuff faster...
+        d = new Date();
+        d = new (function (x) { return { toString: function () { return x.toString() } } })(d.valueOf());
+        d = document.createTextNode("iteration " + i + " at " + d);
+        document.createElement('a').appendChild(d);
+        d = d.parentNode;
+        document.body.insertBefore(d, document.getElementById('bucket1').parentNode);
+        assert(document.getElementById('bucket2').nextSibling.parentNode.previousSibling.firstChild.data.match(/AT\W/i), "iteration " + i + " failed");
+        d.setAttribute('class', d.textContent);
+        document.body.removeChild(d);
+      }
+
+      assert(e1.parentNode, "e1 - parent element doesn't exist after looping");
+      assert(e1.parentNode.ownerDocument, "e1 - document doesn't exist after looping");
+      assertEquals(e1.parentNode.ownerDocument.nodeType, 9, "e1 - document node type has wrong node type");
+      assert(e2.parentNode, "e2 - parent element doesn't exist after looping");
+      assert(e2.parentNode.ownerDocument, "e2 - document doesn't exist after looping");
+      assertEquals(e2.parentNode.ownerDocument.nodeType, 9, "e2 - document node type has wrong node type");
+
+</script>
+<p>DONE</p>
index b6a1de44efb0099f4110a75fe2261b8591ade818..b31cce2161aa854c4ce4f477c4d7c9b0ee0baed3 100644 (file)
@@ -1,3 +1,17 @@
+2008-03-04  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Sam and Oliver.
+
+        - fixed http://bugs.webkit.org/show_bug.cgi?id=16289
+        - fixed Acid3 tests 26 and 27 (not exactly the same issue but related)
+
+        * bindings/js/JSNodeCustom.cpp:
+        (WebCore::JSNode::mark): When marking a node that's in-document,
+        mark the owner document if it hasn't been already. This means holding on
+        to a single node from an unreferenced document now keeps the whole document alive.
+        
+        We are now at 90/100 on Acid3.
+
 2008-03-04  Sam Weinig  <sam@webkit.org>
 
         Qt build fix.
index 20fdad2d4483ddfd573a040f427f7aac88440944..fc27bff6f94829c8918aca4dc097e2a707d2efa9 100644 (file)
@@ -115,6 +115,12 @@ void JSNode::mark()
     // Nodes in the document are kept alive by ScriptInterpreter::mark,
     // so we have no special responsibilities and can just call the base class here.
     if (node->inDocument()) {
+        // But if the document isn't marked we have to mark it to ensure that
+        // nodes reachable from this one are also marked
+        if (Document* doc = node->ownerDocument())
+            if (DOMObject* docWrapper = ScriptInterpreter::getDOMObject(doc))
+                if (!docWrapper->marked())
+                    docWrapper->mark();
         DOMObject::mark();
         return;
     }