Reviewed by Darin.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 May 2005 01:20:46 +0000 (01:20 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 May 2005 01:20:46 +0000 (01:20 +0000)
- fixed <rdar://problem/4125222> Dashboard heap size grows over time (leak caused by JavaScript DOM node wrappers?)

- changed per-document DOMObject caching to work with DOMNodes, since that is all it was used for anyway.

        Test cases added: (these tests actually ensure that DOM wrappers
are sufficiently protected from GC to match other browsers, they
do not verify that the leak is fixed since there's no way to test
that with layout tests).

        * layout-tests/fast/dom/gc-1-expected.txt: Added.
        * layout-tests/fast/dom/gc-1.html: Added.
        * layout-tests/fast/dom/gc-2-expected.txt: Added.
        * layout-tests/fast/dom/gc-2.html: Added.
        * layout-tests/fast/dom/gc-3-expected.txt: Added.
        * layout-tests/fast/dom/gc-3.html: Added.

        * khtml/ecma/kjs_binding.cpp:
        (KJS::ScriptInterpreter::forgetDOMObjectForDocument): New function - allows nodes
that get removed from the document to go away from the cache if not referenced.
        (KJS::ScriptInterpreter::mark): Don't mark nodes that aren't in the document,
they can stay in the cache but only if they have another source of life.
        (KJS::ScriptInterpreter::domNodesPerDocument): Renamed and changed parameter types.
        (KJS::ScriptInterpreter::getDOMNodeForDocument): Renamed and changed parameter types.
        (KJS::ScriptInterpreter::forgetDOMNodeForDocument): Renamed and changed parameter types.
        (KJS::ScriptInterpreter::putDOMNodeForDocument): Renamed and changed parameter types.
        (KJS::ScriptInterpreter::forgetAllDOMNodesForDocument): Renamed and changed parameter types.
        (KJS::ScriptInterpreter::updateDOMNodeDocument): Renamed and changed parameter types.
        * khtml/ecma/kjs_binding.h:
        * khtml/ecma/kjs_dom.cpp:
        (KJS::DOMNode::~DOMNode): call forgetDOMObjectForDocument.
        (KJS::DOMNode::mark): If the node is not in the document, make sure to mark
all wrappers in its detached piece of the tree.
        (KJS::getDOMNode): Updated for renames
        * khtml/ecma/kjs_dom.h:
        * khtml/xml/dom_docimpl.cpp:
        (DocumentImpl::~DocumentImpl): Updated for renames.
        * khtml/xml/dom_nodeimpl.cpp:
        (NodeImpl::checkAddChild): Updated for renames.

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

13 files changed:
LayoutTests/fast/dom/gc-1-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/gc-1.html [new file with mode: 0644]
LayoutTests/fast/dom/gc-2-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/gc-2.html [new file with mode: 0644]
LayoutTests/fast/dom/gc-3-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/gc-3.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/ecma/kjs_binding.cpp
WebCore/khtml/ecma/kjs_binding.h
WebCore/khtml/ecma/kjs_dom.cpp
WebCore/khtml/ecma/kjs_dom.h
WebCore/khtml/xml/dom_docimpl.cpp
WebCore/khtml/xml/dom_nodeimpl.cpp

diff --git a/LayoutTests/fast/dom/gc-1-expected.txt b/LayoutTests/fast/dom/gc-1-expected.txt
new file mode 100644 (file)
index 0000000..fde5891
--- /dev/null
@@ -0,0 +1,7 @@
+This test verifies that JavaScript wrappers for DOM nodes are protected against garbage collection as long as the node remains in the document (so custom properties are preserved).
+
+The output should be the following pieces of text on lines by themselves: "original span", "B":
+
+original span
+B
+
diff --git a/LayoutTests/fast/dom/gc-1.html b/LayoutTests/fast/dom/gc-1.html
new file mode 100644 (file)
index 0000000..1a055e5
--- /dev/null
@@ -0,0 +1,41 @@
+<head>
+<script>
+function doit()
+{
+    document.getElementById("span-B").customProperty = "B";
+
+    // create lots of objects to force a garbage collection
+    var i = 0;
+    while (i < 1000) {
+        i = i+1;
+    }
+
+    var output= document.getElementById("output");
+
+    output.innerHTML += document.getElementById("span-B").customProperty + "<BR>";
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+}
+
+</script>
+</head>
+
+<body onload="doit()">
+<div style="border: 1px solid red">
+<p>
+This test verifies that JavaScript wrappers for DOM nodes are
+protected against garbage collection as long as the node remains in
+the document (so custom properties are preserved).
+</p>
+<p>
+The output should be the following pieces of text on lines by themselves: "original span", "B": 
+</p>
+</div>
+<div id="div">
+<span id="span-A"><span id="span-B"><span id="span-C">original span</span></span></span>
+</div>
+<div id="output">
+</div>
+</body>
diff --git a/LayoutTests/fast/dom/gc-2-expected.txt b/LayoutTests/fast/dom/gc-2-expected.txt
new file mode 100644 (file)
index 0000000..3c76ffe
--- /dev/null
@@ -0,0 +1,9 @@
+This test verifies that JavaScript wrappers for DOM nodes are protected against garbage collection for node trees that are outside the document, so long as there's a reference to at least one node in the tree.
+
+The output should be the following pieces of text on lines by themselves: "replacement content", "B", "A", "C".
+
+replacement content
+B
+A
+C
+
diff --git a/LayoutTests/fast/dom/gc-2.html b/LayoutTests/fast/dom/gc-2.html
new file mode 100644 (file)
index 0000000..4e8fe25
--- /dev/null
@@ -0,0 +1,55 @@
+<html>
+<head>
+<script>
+function doit()
+{
+    var B = document.getElementById("span-B");
+    B.customProperty = "B";
+    B.parentNode.customProperty = "A";
+    B.firstChild.customProperty = "C";
+
+    document.getElementById("div").innerHTML = "<span>replacement content</span>";
+
+    // create lots of objects to force a garbage collection
+    var i = "";
+    while (i < 1000) {
+        i = i + "a";
+    }
+
+    var output= document.getElementById("output");
+
+    output.innerHTML += B.customProperty + "<BR>";
+    if (B.parentNode) {
+        output.innerHTML += B.parentNode.customProperty + "<BR>";
+    }
+    if (B.firstChild) {
+        output.innerHTML += B.firstChild.customProperty + "<BR>";
+    }
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+}
+
+</script>
+</head>
+
+<body onload="doit()">
+<div style="border: 1px solid red">
+<p>
+This test verifies that JavaScript wrappers for DOM nodes are
+protected against garbage collection for node trees that are outside
+the document, so long as there's a reference to at least one node in
+the tree.
+</p>
+<p>
+The output should be the following pieces of text on lines by themselves: "replacement content", "B", "A", "C".
+</p>
+</div>
+<div id="div">
+<span id="span-A"><span id="span-B"><span id="span-C">original span</span></span></span>
+</div>
+<div id="output">
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/dom/gc-3-expected.txt b/LayoutTests/fast/dom/gc-3-expected.txt
new file mode 100644 (file)
index 0000000..60d3a17
--- /dev/null
@@ -0,0 +1,8 @@
+This test verifies that DOM nodes are not retained just because a wrapper exists for a descendant. A wrapper must exist for the node itself or for an ancestor.
+
+The output should be the following pieces of text on lines by themselves: "replacement content", "B", "child node exists".
+
+replacement content
+B
+child node exists
+
diff --git a/LayoutTests/fast/dom/gc-3.html b/LayoutTests/fast/dom/gc-3.html
new file mode 100644 (file)
index 0000000..880f453
--- /dev/null
@@ -0,0 +1,48 @@
+<head>
+<script>
+function doit()
+{
+    var B = document.getElementById("span-B");
+    B.customProperty = "B";
+
+    document.getElementById("div").innerHTML = "<span>replacement content</span>";
+
+    // create lots of objects to force a garbage collection
+    var i = 0;
+    while (i < 1000) {
+        i = i+1;
+    }
+
+    var output= document.getElementById("output");
+
+    output.innerHTML += B.customProperty + "<BR>";
+    if (B.parentNode) {
+        output.innerHTML += "parent node exists<BR>";
+    }
+    if (B.firstChild) {
+        output.innerHTML += "child node exists<BR>";
+    }
+}
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+}
+
+</script>
+</head>
+
+<body onload="doit()">
+<div style="border: 1px solid red">
+<p>
+This test verifies that DOM nodes are not retained just because a wrapper exists for a descendant. A wrapper must exist for the node itself or for an ancestor.
+</p>
+<p>
+The output should be the following pieces of text on lines by themselves: "replacement content", "B", "child node exists".
+</p>
+</div>
+<div id="div">
+<span id="span-A"><span id="span-B"><span id="span-C">original span</span></span></span>
+</div>
+<div id="output">
+</div>
+</body>
index 7be044812f517a63094dd10ec047664d15821925..1ea422bb04e46ef07c06a4b68b149502046b82d4 100644 (file)
@@ -1,3 +1,46 @@
+2005-05-30  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+
+       - fixed <rdar://problem/4125222> Dashboard heap size grows over time (leak caused by JavaScript DOM node wrappers?)
+
+       - changed per-document DOMObject caching to work with DOMNodes, since that is all it was used for anyway.
+       
+        Test cases added: (these tests actually ensure that DOM wrappers
+       are sufficiently protected from GC to match other browsers, they
+       do not verify that the leak is fixed since there's no way to test
+       that with layout tests).
+
+        * layout-tests/fast/dom/gc-1-expected.txt: Added.
+        * layout-tests/fast/dom/gc-1.html: Added.
+        * layout-tests/fast/dom/gc-2-expected.txt: Added.
+        * layout-tests/fast/dom/gc-2.html: Added.
+        * layout-tests/fast/dom/gc-3-expected.txt: Added.
+        * layout-tests/fast/dom/gc-3.html: Added.
+
+        * khtml/ecma/kjs_binding.cpp:
+        (KJS::ScriptInterpreter::forgetDOMObjectForDocument): New function - allows nodes
+       that get removed from the document to go away from the cache if not referenced.
+        (KJS::ScriptInterpreter::mark): Don't mark nodes that aren't in the document,
+       they can stay in the cache but only if they have another source of life.
+        (KJS::ScriptInterpreter::domNodesPerDocument): Renamed and changed parameter types.
+        (KJS::ScriptInterpreter::getDOMNodeForDocument): Renamed and changed parameter types.
+        (KJS::ScriptInterpreter::forgetDOMNodeForDocument): Renamed and changed parameter types.
+        (KJS::ScriptInterpreter::putDOMNodeForDocument): Renamed and changed parameter types.
+        (KJS::ScriptInterpreter::forgetAllDOMNodesForDocument): Renamed and changed parameter types.
+        (KJS::ScriptInterpreter::updateDOMNodeDocument): Renamed and changed parameter types.
+        * khtml/ecma/kjs_binding.h:
+        * khtml/ecma/kjs_dom.cpp: 
+        (KJS::DOMNode::~DOMNode): call forgetDOMObjectForDocument.
+        (KJS::DOMNode::mark): If the node is not in the document, make sure to mark
+       all wrappers in its detached piece of the tree.
+        (KJS::getDOMNode): Updated for renames
+        * khtml/ecma/kjs_dom.h:
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::~DocumentImpl): Updated for renames.
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::checkAddChild): Updated for renames.
+
 2005-05-30  Darin Adler  <darin@apple.com>
 
         Reviewed by John.
index f5b8268768d5dc413bb951a84625fd4ad1459426..3acc2205ca137e64cebd2728a0c9ac5a351e6960 100644 (file)
@@ -24,6 +24,7 @@
 #include "kjs_dom.h"
 #include "kjs_window.h"
 #include <kjs/internal.h> // for InterpreterImp
+#include <kjs/collector.h>
 
 #include "dom/dom_exception.h"
 #include "dom/dom2_events.h"
@@ -76,7 +77,7 @@ Value DOMFunction::call(ExecState *exec, Object &thisObj, const List &args)
 }
 
 static QPtrDict<DOMObject> * staticDomObjects = 0;
-QPtrDict< QPtrDict<DOMObject> > * staticDomObjectsPerDocument = 0;
+QPtrDict< QPtrDict<DOMNode> > * staticDOMNodesPerDocument = 0;
 
 QPtrDict<DOMObject> & ScriptInterpreter::domObjects()
 {
@@ -86,13 +87,13 @@ QPtrDict<DOMObject> & ScriptInterpreter::domObjects()
   return *staticDomObjects;
 }
 
-QPtrDict< QPtrDict<DOMObject> > & ScriptInterpreter::domObjectsPerDocument()
+QPtrDict< QPtrDict<DOMNode> > & ScriptInterpreter::domNodesPerDocument()
 {
-  if (!staticDomObjectsPerDocument) {
-    staticDomObjectsPerDocument = new QPtrDict<QPtrDict<DOMObject> >();
-    staticDomObjectsPerDocument->setAutoDelete(true);
+  if (!staticDOMNodesPerDocument) {
+    staticDOMNodesPerDocument = new QPtrDict<QPtrDict<DOMNode> >();
+    staticDOMNodesPerDocument->setAutoDelete(true);
   }
-  return *staticDomObjectsPerDocument;
+  return *staticDOMNodesPerDocument;
 }
 
 
@@ -117,62 +118,65 @@ void ScriptInterpreter::forgetDOMObject( void* objectHandle )
   deleteDOMObject( objectHandle );
 }
 
-DOMObject* ScriptInterpreter::getDOMObjectForDocument( DOM::DocumentImpl* documentHandle, void *objectHandle )
+DOMNode *ScriptInterpreter::getDOMNodeForDocument(DOM::DocumentImpl *document, DOM::NodeImpl *node)
 {
-  QPtrDict<DOMObject> *documentDict = (QPtrDict<DOMObject> *)domObjectsPerDocument()[documentHandle];
-  if (documentDict) {
-    return (*documentDict)[objectHandle];
-  }
+  QPtrDict<DOMNode> *documentDict = (QPtrDict<DOMNode> *)domNodesPerDocument()[document];
+  if (documentDict)
+    return (*documentDict)[node];
 
   return NULL;
 }
 
-void ScriptInterpreter::putDOMObjectForDocument( DOM::DocumentImpl* documentHandle, void *objectHandle, DOMObject *obj )
+void ScriptInterpreter::forgetDOMNodeForDocument(DOM::DocumentImpl *document, NodeImpl *node)
+{
+  QPtrDict<DOMNode> *documentDict = domNodesPerDocument()[document];
+  if (documentDict)
+    documentDict->remove(node);
+}
+
+void ScriptInterpreter::putDOMNodeForDocument(DOM::DocumentImpl *document, NodeImpl *nodeHandle, DOMNode *nodeWrapper)
 {
-  QPtrDict<DOMObject> *documentDict = (QPtrDict<DOMObject> *)domObjectsPerDocument()[documentHandle];
+  QPtrDict<DOMNode> *documentDict = domNodesPerDocument()[document];
   if (!documentDict) {
-    documentDict = new QPtrDict<DOMObject>();
-    domObjectsPerDocument().insert(documentHandle, documentDict);
+    documentDict = new QPtrDict<DOMNode>();
+    domNodesPerDocument().insert(document, documentDict);
   }
-
-  documentDict->insert( objectHandle, obj );
+  
+  documentDict->insert(nodeHandle, nodeWrapper);
 }
 
-bool ScriptInterpreter::deleteDOMObjectsForDocument( DOM::DocumentImpl* documentHandle )
+void ScriptInterpreter::forgetAllDOMNodesForDocument(DOM::DocumentImpl *document)
 {
-  return domObjectsPerDocument().remove( documentHandle );
+  domNodesPerDocument().remove(document);
 }
 
 void ScriptInterpreter::mark()
 {
-  QPtrDictIterator<QPtrDict<DOMObject> > dictIterator(domObjectsPerDocument());
-
-  QPtrDict<DOMObject> *objectDict;
-  while ((objectDict = dictIterator.current())) {
-    QPtrDictIterator<DOMObject> objectIterator(*objectDict);
-
-    DOMObject *obj;
-    while ((obj = objectIterator.current())) {
-      if (!obj->marked()) {
-       obj->mark();
-      }
-      ++objectIterator;
+  QPtrDictIterator<QPtrDict<DOMNode> > dictIterator(domNodesPerDocument());
+
+  QPtrDict<DOMNode> *nodeDict;
+  while ((nodeDict = dictIterator.current())) {
+    QPtrDictIterator<DOMNode> nodeIterator(*nodeDict);
+
+    DOMNode *node;
+    while ((node = nodeIterator.current())) {
+      // don't mark wrappers for nodes that are no longer in the
+      // document - they should not be saved if the node is not
+      // otherwise reachable from JS.
+      if (node->impl()->inDocument() && !node->marked())
+          node->mark();
+
+      ++nodeIterator;
     }
     ++dictIterator;
   }
 }
 
-void ScriptInterpreter::forgetDOMObjectsForDocument( DOM::DocumentImpl* documentHandle )
-{
-  deleteDOMObjectsForDocument( documentHandle );
-}
-
-void ScriptInterpreter::updateDOMObjectDocument(void *objectHandle, DOM::DocumentImpl *oldDoc, DOM::DocumentImpl *newDoc)
+void ScriptInterpreter::updateDOMNodeDocument(NodeImpl *node, DOM::DocumentImpl *oldDoc, DOM::DocumentImpl *newDoc)
 {
-  DOMObject* cachedObject = getDOMObjectForDocument(oldDoc, objectHandle);
-  if (cachedObject) {
-    putDOMObjectForDocument(newDoc, objectHandle, cachedObject);
-  }
+  DOMNode *cachedObject = getDOMNodeForDocument(oldDoc, node);
+  if (cachedObject)
+    putDOMNodeForDocument(newDoc, node, cachedObject);
 }
 
 bool ScriptInterpreter::wasRunByUserGesture() const
index ca96c6278cb14c108012f4bcd8c0637e8576f805..60157365774b1f23ecc8b8148bbc52b3cc879238 100644 (file)
@@ -37,6 +37,7 @@ class KHTMLPart;
 namespace DOM {
     class DocumentImpl;
     class EventImpl;
+    class NodeImpl;
 }
 
 namespace KJS {
@@ -84,6 +85,8 @@ namespace KJS {
     virtual UString toString(ExecState *) const { return UString("[function]"); }
   };
 
+  class DOMNode;
+
   /**
    * We inherit from Interpreter, to save a pointer to the HTML part
    * that the interpreter runs for.
@@ -105,17 +108,15 @@ namespace KJS {
       return domObjects().remove( objectHandle );
     }
 
-    static DOMObject* getDOMObjectForDocument( DOM::DocumentImpl* documentHandle, void *objectHandle );
-    static void putDOMObjectForDocument( DOM::DocumentImpl* documentHandle, void *objectHandle, DOMObject *obj );
-    static bool deleteDOMObjectsForDocument( DOM::DocumentImpl* documentHandle );
-
-    /**
-     * Static method. Makes all interpreters forget about the object
-     */
     static void forgetDOMObject( void* objectHandle );
-    static void forgetDOMObjectsForDocument( DOM::DocumentImpl* documentHandle );
 
-    static void updateDOMObjectDocument(void *objectHandle, DOM::DocumentImpl *oldDoc, DOM::DocumentImpl *newDoc);
+
+    static DOMNode *getDOMNodeForDocument(DOM::DocumentImpl *document, DOM::NodeImpl *node);
+    static void putDOMNodeForDocument(DOM::DocumentImpl *document, DOM::NodeImpl *nodeHandle, DOMNode *nodeWrapper);
+    static void forgetDOMNodeForDocument(DOM::DocumentImpl *document, DOM::NodeImpl *node);
+    static void forgetAllDOMNodesForDocument(DOM::DocumentImpl *document);
+    static void updateDOMNodeDocument(DOM::NodeImpl *nodeHandle, DOM::DocumentImpl *oldDoc, DOM::DocumentImpl *newDoc);
+
 
 
     KHTMLPart* part() const { return m_part; }
@@ -149,7 +150,7 @@ namespace KJS {
     KHTMLPart* m_part;
 
     static QPtrDict<DOMObject> &domObjects();
-    static QPtrDict<QPtrDict<DOMObject> > &domObjectsPerDocument();
+    static QPtrDict<QPtrDict<DOMNode> > &domNodesPerDocument();
 
     DOM::EventImpl *m_evt;
     bool m_inlineCode;
index 68f9ab23b8ac94bbbb42014165124baf0b11ffe8..bc2fa7c919f7dae38e98ac4f1cc7388a6183161e 100644 (file)
@@ -133,6 +133,45 @@ DOMNode::DOMNode(NodeImpl *n)
 {
 }
 
+DOMNode::~DOMNode()
+{
+  ScriptInterpreter::forgetDOMNodeForDocument(m_impl->getDocument(), m_impl.get());
+}
+
+void DOMNode::mark()
+{
+  static bool markingTree = false;
+
+  if (m_impl->inDocument() || markingTree) {
+    DOMObject::mark();
+    return;
+  }
+
+  DocumentImpl *document = m_impl->getDocument();
+  NodeImpl *outermostWrappedNode = m_impl.get();
+  for (NodeImpl *current = m_impl->parentNode(); current; current = current->parentNode()) {
+    if (ScriptInterpreter::getDOMNodeForDocument(document, current))
+      outermostWrappedNode = current;
+  }
+
+  markingTree = true;
+
+  NodeImpl *nodeToMark = outermostWrappedNode;
+  while (nodeToMark) {
+    DOMNode *wrapper = ScriptInterpreter::getDOMNodeForDocument(document, nodeToMark);
+    if (!wrapper)
+      nodeToMark = nodeToMark->traverseNextNode();
+    else if (wrapper->marked())
+      nodeToMark = nodeToMark->traverseNextSibling();
+    else {
+      wrapper->mark();
+      nodeToMark = nodeToMark->traverseNextNode();
+    }
+  }
+
+  markingTree = false;
+}
+
 bool DOMNode::toBoolean(ExecState *) const
 {
     return m_impl.notNull();
@@ -1588,13 +1627,13 @@ bool checkNodeSecurity(ExecState *exec, NodeImpl *n)
 
 ValueImp *getDOMNode(ExecState *exec, NodeImpl *n)
 {
-  DOMObject *ret = 0;
+  DOMNode *ret = 0;
   if (!n)
     return Null();
   ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   DocumentImpl *doc = n->getDocument();
 
-  if ((ret = interp->getDOMObjectForDocument(doc, n)))
+  if ((ret = interp->getDOMNodeForDocument(doc, n)))
     return ret;
 
   switch (n->nodeType()) {
@@ -1635,7 +1674,7 @@ ValueImp *getDOMNode(ExecState *exec, NodeImpl *n)
       ret = new DOMNode(exec, n);
   }
 
-  interp->putDOMObjectForDocument(doc, n, ret);
+  interp->putDOMNodeForDocument(doc, n, ret);
 
   return ret;
 }
index 630aca5a0e4c9fde5501a5452a7cb76dd853cee4..0e444cc65fff843a1dcb73389dc9924cadc27905 100644 (file)
@@ -47,10 +47,11 @@ namespace KJS {
   class DOMNode : public DOMObject {
   public:
     DOMNode(ExecState *exec, DOM::NodeImpl *n);
+    virtual ~DOMNode();
     virtual bool toBoolean(ExecState *) const;
     virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
     Value getValueProperty(ExecState *exec, int token) const;
-
+    virtual void mark();
     virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValue(ExecState *exec, int token, const Value& value, int attr);
     DOM::NodeImpl *impl() const { return m_impl.get(); }
index 345c85c9c321d43eaf894f77ea58496c319a79cd..5b2bff293d70fe992caeda7f4461e1d6ff5f73cc 100644 (file)
@@ -398,7 +398,7 @@ DocumentImpl::~DocumentImpl()
     assert(m_savedRenderer == 0);
 #endif
     
-    KJS::ScriptInterpreter::forgetDOMObjectsForDocument(this);
+    KJS::ScriptInterpreter::forgetAllDOMNodesForDocument(this);
 
     if (changedDocuments && m_docChanged)
         changedDocuments->remove(this);
index 5cecbd451442749df102ad7f849c3589ab8f6172..db2f56c38d46b92a9f70a002b03db0eaa999e29d 100644 (file)
@@ -1092,7 +1092,7 @@ void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode)
 
     // only do this once we know there won't be an exception
     if (shouldAdoptChild) {
-       KJS::ScriptInterpreter::updateDOMObjectDocument(newChild, newChild->getDocument(), getDocument());
+       KJS::ScriptInterpreter::updateDOMNodeDocument(newChild, newChild->getDocument(), getDocument());
        newChild->setDocument(getDocument()->docPtr());
     }
 }