[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/KDE/4.0/kdelibs/khtml/ecma
From:       Maks Orlovich <maksim () kde ! org>
Date:       2008-01-19 17:42:06
Message-ID: 1200764526.479013.29768.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 763528 by orlovich:

Properly coalesce wrappers accross documents. This requires having a global
map for hashconsing along with the previous local wrapper maps
used for memory management. (We also have to be careful to insert into
local maps when reusing from global ones).

BUG: 145775

 M  +4 -1      kjs_binding.cpp  
 M  +26 -10    kjs_binding.h  


--- branches/KDE/4.0/kdelibs/khtml/ecma/kjs_binding.cpp #763527:763528
@@ -60,6 +60,8 @@
   return "[object " + className() + "]";	//krazy:exclude=doublequote_chars DOM demands chars
 }
 
+HashMap<void*, DOMObject*>* ScriptInterpreter::s_allDomObjects;
+
 typedef QList<ScriptInterpreter*> InterpreterList;
 static InterpreterList *interpreterList;
 
@@ -93,7 +95,8 @@
   if( !interpreterList ) return;
 
   for (int i = 0; i < interpreterList->size(); ++i)
-    interpreterList->at(i)->deleteDOMObject( objectHandle );
+    interpreterList->at(i)->m_domObjects.remove( objectHandle );
+  allDomObjects()->remove( objectHandle );
 }
 
 void ScriptInterpreter::mark(bool isMain)
--- branches/KDE/4.0/kdelibs/khtml/ecma/kjs_binding.h #763527:763528
@@ -82,23 +82,32 @@
     ScriptInterpreter( JSObject *global, khtml::ChildFrame* frame );
     virtual ~ScriptInterpreter();
 
-    DOMObject* getDOMObject( void* objectHandle ) const {
-      return m_domObjects.get( objectHandle );
+    // We need to keep track of wrappers in 2 ways:
+    //  - we want the same wrapper for the same node (see #145775)
+    //  - we want to drop all the references from this interpreter on clear, so
+    //  wrappers don't stick around. Hence we have a global set and a per-interpreter one.
+
+    // Reuses an existing wrapper, perhaps also updating the current map
+    // to refer to it as well.
+    DOMObject* getDOMObject( void* objectHandle ) {
+      DOMObject* existing = allDomObjects()->get( objectHandle );
+      if (existing)
+          m_domObjects.set(objectHandle, existing );
+      return existing;
     }
+    
     void putDOMObject( void* objectHandle, DOMObject* obj ) {
+      allDomObjects()->set( objectHandle, obj );
       m_domObjects.set( objectHandle, obj );
     }
-    void deleteDOMObject( void* objectHandle ) {
-      m_domObjects.remove( objectHandle );
-    }
+
+    static void forgetDOMObject( void* objectHandle );
+    
     void clear() {
-      m_domObjects.clear();
+      m_domObjects.clear(); // Global set will be cleared at GC time.
     }
-    /**
-     * Static method. Makes all interpreters forget about the object
-     */
-    static void forgetDOMObject( void* objectHandle );
 
+
     /**
      * Mark objects in the DOMObject cache.
      */
@@ -132,6 +141,13 @@
   private:
     khtml::ChildFrame* m_frame;
     HashMap<void*, DOMObject*> m_domObjects;
+    static HashMap<void*, DOMObject*>* s_allDomObjects;
+    static HashMap<void*, DOMObject*>* allDomObjects() {
+        if (!s_allDomObjects)
+            s_allDomObjects = new HashMap<void*, DOMObject*>();
+        return s_allDomObjects;
+    }
+    
     DOM::Event *m_evt;
     bool m_inlineCode;
     bool m_timerCallback;
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic