document-leak.patch.txt   [plain text]


Index: ChangeLog
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/ChangeLog,v
retrieving revision 1.1134
diff -u -p -r1.1134 ChangeLog
--- ChangeLog	2002/12/16 10:39:25	1.1134
+++ ChangeLog	2002/12/16 18:49:44
@@ -1,3 +1,20 @@
+2002-12-16  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+
+	- fixed 3129008 - REGRESSION: Successive hot/cached runs of cvs-base PLT are slightly slower
+
+	This was due to me reintroducing a leak of the document. Now fixed.
+	
+        * khtml/ecma/kjs_dom.cpp:
+        (DOMDocument::~DOMDocument): forget self from cached DOM object table.
+        (KJS::getDOMDocumentNode): Instead of storing the document in the
+	marked per-document table, store it in the unmarked table, and as
+	a property on the Window object.
+        (KJS::getDOMNode): use getDocumentNode when appropriate.
+        * khtml/ecma/kjs_dom.h:
+
+
 2002-12-15  David Hyatt  <hyatt@apple.com>
 
 	Fix for 3128728.  Ensure that list markers get placed into an
Index: khtml/ecma/kjs_dom.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_dom.cpp,v
retrieving revision 1.18
diff -u -p -r1.18 khtml/ecma/kjs_dom.cpp
--- khtml/ecma/kjs_dom.cpp	2002/12/16 03:05:40	1.18
+++ khtml/ecma/kjs_dom.cpp	2002/12/16 18:49:44
@@ -687,6 +687,11 @@ DOMDocument::DOMDocument(ExecState *exec
 DOMDocument::DOMDocument(const Object &proto, const DOM::Document &d)
   : DOMNode(proto, d) { }
 
+DOMDocument::~DOMDocument()
+{
+  ScriptInterpreter::forgetDOMObject(node.handle());
+}
+
 Value DOMDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
 {
 #ifdef KJS_VERBOSE
@@ -1244,6 +1249,35 @@ Value DOMEntity::getValueProperty(ExecSt
 
 // -------------------------------------------------------------------------
 
+Value KJS::getDOMDocumentNode(ExecState *exec, const DOM::Document &n)
+{
+  DOMDocument *ret = 0;
+  ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
+
+  if ((ret = static_cast<DOMDocument *>(interp->getDOMObject(n.handle()))))
+    return Value(ret);
+
+  if (static_cast<DOM::Document>(n).isHTMLDocument())
+    ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
+  else
+    ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
+
+  Value val(ret);
+  
+  // Make sure the document is kept around by the window object, and works right with the
+  // back/forward cache.
+  if (n.view()) {
+    static Identifier documentIdentifier("document");
+    Window::retrieveWindow(n.view()->part())->putDirect(documentIdentifier, ret, DontDelete|ReadOnly);
+  } else {
+    puts("no view");
+  }
+
+  interp->putDOMObject(n.handle(), ret);
+
+  return val;
+}
+
 Value KJS::getDOMNode(ExecState *exec, const DOM::Node &n)
 {
   DOMObject *ret = 0;
@@ -1282,11 +1316,8 @@ Value KJS::getDOMNode(ExecState *exec, c
       ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
       break;
     case DOM::Node::DOCUMENT_NODE:
-      if (static_cast<DOM::Document>(n).isHTMLDocument())
-        ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
-      else
-        ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
-      doc = n.handle();
+      // we don't want to cache the document itself in the per-document dictionary
+      return getDOMDocumentNode(exec, static_cast<DOM::Document>(n));
       break;
     case DOM::Node::DOCUMENT_TYPE_NODE:
       ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
Index: khtml/ecma/kjs_dom.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_dom.h,v
retrieving revision 1.12
diff -u -p -r1.12 khtml/ecma/kjs_dom.h
--- khtml/ecma/kjs_dom.h	2002/12/16 03:05:40	1.12
+++ khtml/ecma/kjs_dom.h	2002/12/16 18:49:44
@@ -103,6 +103,7 @@ namespace KJS {
     DOMDocument(ExecState *exec, const DOM::Document &d);
     // Constructor for inherited classes
     DOMDocument(const Object &proto, const DOM::Document &d);
+    ~DOMDocument();
     virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
@@ -248,6 +249,7 @@ namespace KJS {
     static const ClassInfo info;
   };
 
+  Value getDOMDocumentNode(ExecState *exec, const DOM::Document &n);
   Value getDOMNode(ExecState *exec, const DOM::Node &n);
   Value getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap &m);
   Value getDOMNodeList(ExecState *exec, const DOM::NodeList &l);