2011-04-13 Geoffrey Garen <ggaren@apple.com>
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Apr 2011 22:15:28 +0000 (22:15 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Apr 2011 22:15:28 +0000 (22:15 +0000)
        Reviewed by Oliver Hunt.

        Switched DOM wrappers to use HashMap of Weak<T> instead of WeakGCMap<T>
        https://bugs.webkit.org/show_bug.cgi?id=58482

        This will allow wrappers to make individual decisions about their lifetimes.

        * heap/HandleHeap.h:
        (JSC::HandleHeap::copyWeak): New function for copying a weak handle.
        It's wasn't previously possible to perform this operation using HandleHeap
        API because the HandleHeap doesn't expose its underlying Node structure.

        * heap/Local.h:
        (JSC::::set):
        * heap/Strong.h:
        (JSC::Strong::set): Added ASSERTs to verify that dead objects are not
        resurrected by placement into handles.

        (JSC::swap): Added a swap helper, so use of Strong<T> inside a hash table
        is efficient.

        * heap/Weak.h:
        (JSC::Weak::Weak): Fixed a bug where copying a weak pointer would not
        copy its weak callback and context.

        (JSC::Weak::operator=): Added an assignment operator, since the default
        C++ assignment operator did the wrong thing.

        (JSC::Weak::set): Added ASSERTs to verify that dead objects are not
        resurrected by placement into handles.

        (JSC::swap): Added a swap helper, so use of Strong<T> inside a hash table
        is efficient, and can be done without copying, which is illegal during
        the handle finalization phase.
2011-04-13  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Oliver Hunt.

        Switched DOM wrappers to use HashMap of Weak<T> instead of WeakGCMap<T>
        https://bugs.webkit.org/show_bug.cgi?id=58482

        This will allow wrappers to make individual decisions about their lifetimes.

        * bindings/js/DOMWrapperWorld.cpp:
        (WebCore::DOMWrapperWorld::DOMWrapperWorld):
        (WebCore::JSNodeHandleOwner::isReachableFromOpaqueRoots):
        (WebCore::JSNodeHandleOwner::finalize):
        (WebCore::DOMObjectHandleOwner::isReachableFromOpaqueRoots):
        (WebCore::DOMObjectHandleOwner::finalize):
        * bindings/js/DOMWrapperWorld.h:
        (WebCore::JSNodeHandleOwner::JSNodeHandleOwner):
        (WebCore::DOMObjectHandleOwner::DOMObjectHandleOwner):
        (WebCore::DOMWrapperWorld::jsNodeHandleOwner):
        (WebCore::DOMWrapperWorld::domObjectHandleOwner): Added handle owners
        for JSNode and DOMObject, our two hash table values. For now, the owners
        just take care to remove their handles from their respective hash tables.

        Changed the hash table type to be a standard HashMap of weak pointers,
        instead of a WeakGCMap.

        * bindings/js/JSDOMBinding.cpp:
        (WebCore::getCachedDOMObjectWrapper):
        (WebCore::cacheDOMObjectWrapper):
        (WebCore::cacheDOMNodeWrapper):
        (WebCore::isObservableThroughDOM):
        (WebCore::markDOMNodesForDocument):
        (WebCore::takeWrappers):
        (WebCore::updateDOMNodeDocument):
        (WebCore::markDOMObjectWrapper):
        (WebCore::markDOMNodeWrapper): Updated wrapper hash table access to
        accomodate its new data type.

        * bindings/js/JSNodeCustom.h:
        (WebCore::getCachedDOMNodeWrapper): Ditto.

        * dom/Document.h: Updated declaration to match the above.

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/heap/HandleHeap.h
Source/JavaScriptCore/heap/Local.h
Source/JavaScriptCore/heap/Strong.h
Source/JavaScriptCore/heap/Weak.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/DOMWrapperWorld.cpp
Source/WebCore/bindings/js/DOMWrapperWorld.h
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSNodeCustom.h
Source/WebCore/dom/Document.h

index fa0367d..a645d17 100644 (file)
@@ -1,3 +1,40 @@
+2011-04-13  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Switched DOM wrappers to use HashMap of Weak<T> instead of WeakGCMap<T>
+        https://bugs.webkit.org/show_bug.cgi?id=58482
+        
+        This will allow wrappers to make individual decisions about their lifetimes.
+
+        * heap/HandleHeap.h:
+        (JSC::HandleHeap::copyWeak): New function for copying a weak handle.
+        It's wasn't previously possible to perform this operation using HandleHeap
+        API because the HandleHeap doesn't expose its underlying Node structure.
+
+        * heap/Local.h:
+        (JSC::::set):
+        * heap/Strong.h:
+        (JSC::Strong::set): Added ASSERTs to verify that dead objects are not
+        resurrected by placement into handles.
+
+        (JSC::swap): Added a swap helper, so use of Strong<T> inside a hash table
+        is efficient.
+
+        * heap/Weak.h:
+        (JSC::Weak::Weak): Fixed a bug where copying a weak pointer would not
+        copy its weak callback and context.
+
+        (JSC::Weak::operator=): Added an assignment operator, since the default
+        C++ assignment operator did the wrong thing.
+
+        (JSC::Weak::set): Added ASSERTs to verify that dead objects are not
+        resurrected by placement into handles.
+
+        (JSC::swap): Added a swap helper, so use of Strong<T> inside a hash table
+        is efficient, and can be done without copying, which is illegal during
+        the handle finalization phase.
+
 2011-04-13  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Gavin Barraclough.
index 0559e7b..bc0e03f 100644 (file)
@@ -58,6 +58,7 @@ public:
     void deallocate(HandleSlot);
 
     void makeWeak(HandleSlot, WeakHandleOwner* = 0, void* context = 0);
+    HandleSlot copyWeak(HandleSlot);
 
     void markStrongHandles(HeapRootMarker&);
     void markWeakHandles(HeapRootMarker&);
@@ -165,6 +166,15 @@ inline void HandleHeap::deallocate(HandleSlot handle)
     m_freeList.push(node);
 }
 
+inline HandleSlot HandleHeap::copyWeak(HandleSlot other)
+{
+    Node* node = toNode(allocate());
+    node->makeWeak(toNode(other)->weakOwner(), toNode(other)->weakOwnerContext());
+    writeBarrier(node->slot(), *other);
+    *node->slot() = *other;
+    return toHandle(node);
+}
+
 inline void HandleHeap::makeWeak(HandleSlot handle, WeakHandleOwner* weakOwner, void* context)
 {
     Node* node = toNode(handle);
index 0d3ce23..ac7d136 100644 (file)
@@ -91,10 +91,11 @@ template <typename T> inline Local<T>& Local<T>::operator=(Handle<T> other)
     return *this;
 }
 
-template <typename T> inline void Local<T>::set(ExternalType value)
+template <typename T> inline void Local<T>::set(ExternalType externalType)
 {
     ASSERT(slot());
-    *slot() = value;
+    ASSERT(!HandleTypes<T>::toJSValue(externalType) || !HandleTypes<T>::toJSValue(externalType).isCell() || Heap::isMarked(HandleTypes<T>::toJSValue(externalType).asCell()));
+    *slot() = externalType;
 }
 
 
index 394d2aa..e5b47c7 100644 (file)
@@ -137,11 +137,17 @@ private:
     {
         ASSERT(slot());
         JSValue value = HandleTypes<T>::toJSValue(externalType);
+        ASSERT(!value || !value.isCell() || Heap::isMarked(value.asCell()));
         HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
         *slot() = value;
     }
 };
 
+template<class T> inline void swap(Strong<T>& a, Strong<T>& b)
+{
+    a.swap(b);
+}
+
 } // namespace JSC
 
 namespace WTF {
index 00d7053..62e2596 100644 (file)
@@ -58,8 +58,7 @@ public:
     {
         if (!other.slot())
             return;
-        setSlot(HandleHeap::heapFor(other.slot())->allocate());
-        set(other.get());
+        setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
     }
 
     template <typename U> Weak(const Weak<U>& other)
@@ -67,8 +66,7 @@ public:
     {
         if (!other.slot())
             return;
-        setSlot(HandleHeap::heapFor(other.slot())->allocate());
-        set(other.get());
+        setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
     }
     
     enum HashTableDeletedValueTag { HashTableDeletedValue };
@@ -108,6 +106,22 @@ public:
         set(value);
     }
 
+    template <typename U> Weak& operator=(const Weak<U>& other)
+    {
+        clear();
+        if (other.slot())
+            setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
+        return *this;
+    }
+
+    Weak& operator=(const Weak& other)
+    {
+        clear();
+        if (other.slot())
+            setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
+        return *this;
+    }
+
 private:
     static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
 
@@ -115,11 +129,17 @@ private:
     {
         ASSERT(slot());
         JSValue value = HandleTypes<T>::toJSValue(externalType);
+        ASSERT(!value || !value.isCell() || Heap::isMarked(value.asCell()));
         HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
         *slot() = value;
     }
 };
 
+template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
+{
+    a.swap(b);
+}
+
 } // namespace JSC
 
 namespace WTF {
index 7bd4e52..467a4dc 100644 (file)
@@ -1,3 +1,46 @@
+2011-04-13  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Switched DOM wrappers to use HashMap of Weak<T> instead of WeakGCMap<T>
+        https://bugs.webkit.org/show_bug.cgi?id=58482
+
+        This will allow wrappers to make individual decisions about their lifetimes.
+
+        * bindings/js/DOMWrapperWorld.cpp:
+        (WebCore::DOMWrapperWorld::DOMWrapperWorld):
+        (WebCore::JSNodeHandleOwner::isReachableFromOpaqueRoots):
+        (WebCore::JSNodeHandleOwner::finalize):
+        (WebCore::DOMObjectHandleOwner::isReachableFromOpaqueRoots):
+        (WebCore::DOMObjectHandleOwner::finalize):
+        * bindings/js/DOMWrapperWorld.h:
+        (WebCore::JSNodeHandleOwner::JSNodeHandleOwner):
+        (WebCore::DOMObjectHandleOwner::DOMObjectHandleOwner):
+        (WebCore::DOMWrapperWorld::jsNodeHandleOwner):
+        (WebCore::DOMWrapperWorld::domObjectHandleOwner): Added handle owners
+        for JSNode and DOMObject, our two hash table values. For now, the owners
+        just take care to remove their handles from their respective hash tables.
+        
+        Changed the hash table type to be a standard HashMap of weak pointers,
+        instead of a WeakGCMap.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::getCachedDOMObjectWrapper):
+        (WebCore::cacheDOMObjectWrapper):
+        (WebCore::cacheDOMNodeWrapper):
+        (WebCore::isObservableThroughDOM):
+        (WebCore::markDOMNodesForDocument):
+        (WebCore::takeWrappers):
+        (WebCore::updateDOMNodeDocument):
+        (WebCore::markDOMObjectWrapper):
+        (WebCore::markDOMNodeWrapper): Updated wrapper hash table access to
+        accomodate its new data type.
+
+        * bindings/js/JSNodeCustom.h:
+        (WebCore::getCachedDOMNodeWrapper): Ditto.
+
+        * dom/Document.h: Updated declaration to match the above.
+
 2011-04-13  Sam Weinig  <sam@webkit.org>
 
         Fix Mac builds.
index 13ee37a..7c98315 100644 (file)
 #include "DOMWrapperWorld.h"
 
 #include "JSDOMWindow.h"
+#include "JSNode.h"
 #include "ScriptController.h"
 #include "WebCoreJSClientData.h"
+#include <heap/Weak.h>
 
 using namespace JSC;
 
@@ -32,6 +34,8 @@ namespace WebCore {
 DOMWrapperWorld::DOMWrapperWorld(JSC::JSGlobalData* globalData, bool isNormal)
     : m_globalData(globalData)
     , m_isNormal(isNormal)
+    , m_jsNodeHandleOwner(this)
+    , m_domObjectHandleOwner(this)
 {
     JSGlobalData::ClientData* clientData = m_globalData->clientData;
     ASSERT(clientData);
@@ -79,4 +83,29 @@ DOMWrapperWorld* mainThreadNormalWorld()
     return cachedNormalWorld;
 }
 
+bool JSNodeHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void*, JSC::MarkStack&)
+{
+    return false;
+}
+
+void JSNodeHandleOwner::finalize(JSC::Handle<JSC::Unknown> handle, void*)
+{
+    JSNode* jsNode = static_cast<JSNode*>(handle.get().asCell());
+    Node* node = jsNode->impl();
+    ASSERT(node->document());
+    ASSERT(node->document()->getWrapperCache(m_world)->find(node)->second == jsNode);
+    node->document()->getWrapperCache(m_world)->remove(node);
+}
+
+bool DOMObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void*, JSC::MarkStack&)
+{
+    return false;
+}
+
+void DOMObjectHandleOwner::finalize(JSC::Handle<JSC::Unknown> handle, void*)
+{
+    DOMObject* domObject = static_cast<DOMObject*>(handle.get().asCell());
+    m_world->m_wrappers.remove(domObject);
+}
+
 } // namespace WebCore
index 9825a08..8f0b506 100644 (file)
@@ -32,8 +32,38 @@ namespace WebCore {
 
 class ScriptController;
 
-typedef JSC::WeakGCMap<void*, DOMObject> DOMObjectWrapperMap;
-typedef JSC::WeakGCMap<StringImpl*, JSC::JSString> JSStringCache; 
+typedef HashMap<void*, JSC::Weak<DOMObject> > DOMObjectWrapperMap;
+typedef JSC::WeakGCMap<StringImpl*, JSC::JSString> JSStringCache;
+
+class JSNodeHandleOwner : public JSC::WeakHandleOwner {
+public:
+    JSNodeHandleOwner(DOMWrapperWorld*);
+    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void*, JSC::MarkStack&);
+    virtual void finalize(JSC::Handle<JSC::Unknown>, void*);
+
+private:
+    DOMWrapperWorld* m_world;
+};
+
+inline JSNodeHandleOwner::JSNodeHandleOwner(DOMWrapperWorld* world)
+    : m_world(world)
+{
+}
+
+class DOMObjectHandleOwner : public JSC::WeakHandleOwner {
+public:
+    DOMObjectHandleOwner(DOMWrapperWorld*);
+    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void*, JSC::MarkStack&);
+    virtual void finalize(JSC::Handle<JSC::Unknown>, void*);
+
+private:
+    DOMWrapperWorld* m_world;
+};
+
+inline DOMObjectHandleOwner::DOMObjectHandleOwner(DOMWrapperWorld* world)
+    : m_world(world)
+{
+}
 
 class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
 public:
@@ -59,6 +89,8 @@ public:
     bool isNormal() const { return m_isNormal; }
 
     JSC::JSGlobalData* globalData() const { return m_globalData; }
+    JSNodeHandleOwner* jsNodeHandleOwner() { return &m_jsNodeHandleOwner; }
+    DOMObjectHandleOwner* domObjectHandleOwner() { return &m_domObjectHandleOwner; }
 
 protected:
     DOMWrapperWorld(JSC::JSGlobalData*, bool isNormal);
@@ -68,6 +100,8 @@ private:
     HashSet<Document*> m_documentsWithWrapperCaches;
     HashSet<ScriptController*> m_scriptControllersWithWindowShells;
     bool m_isNormal;
+    JSNodeHandleOwner m_jsNodeHandleOwner;
+    DOMObjectHandleOwner m_domObjectHandleOwner;
 };
 
 DOMWrapperWorld* normalWorld(JSC::JSGlobalData&);
index 8501eb9..69c0db5 100644 (file)
@@ -158,12 +158,13 @@ bool hasCachedDOMObjectWrapper(JSGlobalData* globalData, void* objectHandle)
 
 DOMObject* getCachedDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle) 
 {
-    return domObjectWrapperMapFor(exec).get(objectHandle);
+    return domObjectWrapperMapFor(exec).get(objectHandle).get();
 }
 
 void cacheDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle, DOMObject* wrapper) 
 {
-    domObjectWrapperMapFor(exec).set(exec->globalData(), objectHandle, wrapper);
+    DOMWrapperWorld* world = currentWorld(exec);
+    world->m_wrappers.set(objectHandle, Weak<DOMObject>(*world->globalData(), wrapper, world->domObjectHandleOwner()));
 }
 
 bool hasCachedDOMNodeWrapperUnchecked(Document* document, Node* node)
@@ -181,13 +182,16 @@ bool hasCachedDOMNodeWrapperUnchecked(Document* document, Node* node)
 
 void cacheDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node, JSNode* wrapper)
 {
+    ASSERT(wrapper);
     if (!document)
-        domObjectWrapperMapFor(exec).set(exec->globalData(), node, wrapper);
+        cacheDOMObjectWrapper(exec, node, wrapper);
     else
-        document->getWrapperCache(currentWorld(exec))->set(exec->globalData(), node, wrapper);
+        document->getWrapperCache(currentWorld(exec))->set(node, Weak<JSNode>(exec->globalData(), wrapper, currentWorld(exec)->jsNodeHandleOwner()));
 
-    if (currentWorld(exec)->isNormal())
+    if (currentWorld(exec)->isNormal()) {
         node->setWrapper(exec->globalData(), wrapper);
+        ASSERT(node->wrapper() == (document ? document->getWrapperCache(currentWorld(exec))->get(node).get() : domObjectWrapperMapFor(exec).get(node).get()));
+    }
 }
 
 static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world)
@@ -219,7 +223,7 @@ static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world
         // keep the node wrappers protecting them alive.
         if (node->isElementNode()) {
             if (NamedNodeMap* attributes = static_cast<Element*>(node)->attributeMap()) {
-                if (DOMObject* wrapper = world->m_wrappers.get(attributes)) {
+                if (DOMObject* wrapper = world->m_wrappers.get(attributes).get()) {
                     // FIXME: This check seems insufficient, because NamedNodeMap items can have custom properties themselves.
                     // Maybe it would be OK to just keep the wrapper alive, as it is done for CSSOM objects below.
                     if (wrapper->hasCustomProperties())
@@ -234,7 +238,7 @@ static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world
             }
             if (static_cast<Element*>(node)->hasTagName(canvasTag)) {
                 if (CanvasRenderingContext* context = static_cast<HTMLCanvasElement*>(node)->renderingContext()) {
-                    if (DOMObject* wrapper = world->m_wrappers.get(context)) {
+                    if (DOMObject* wrapper = world->m_wrappers.get(context).get()) {
                         if (wrapper->hasCustomProperties())
                             return true;
                     }
@@ -289,8 +293,10 @@ void markDOMNodesForDocument(MarkStack& markStack, Document* document)
 
         JSWrapperCache::iterator nodeEnd = nodeDict->end();
         for (JSWrapperCache::iterator nodeIt = nodeDict->begin(); nodeIt != nodeEnd; ++nodeIt) {
-            if (isObservableThroughDOM(nodeIt.get().second, world))
-                markStack.deprecatedAppend(nodeIt.getSlot().second);
+            JSNode* node = nodeIt->second.get();
+            if (!isObservableThroughDOM(node, world))
+                continue;
+            markStack.deprecatedAppend(reinterpret_cast<JSCell**>(&node));
         }
     }
 }
@@ -327,13 +333,15 @@ static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrap
     if (document) {
         JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
         for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) {
-            if (JSNode* wrapper = iter->second->take(node))
-                wrapperSet.append(WrapperAndWorld(wrapper, iter->first));
+            JSNode* wrapper = iter->second->take(node).get();
+            if (!wrapper)
+                continue;
+            wrapperSet.append(WrapperAndWorld(wrapper, iter->first));
         }
     } else {
         for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) {
             DOMWrapperWorld* world = *worldIter;
-            if (JSNode* wrapper = static_cast<JSNode*>(world->m_wrappers.take(node)))
+            if (JSNode* wrapper = static_cast<JSNode*>(world->m_wrappers.take(node).get()))
                 wrapperSet.append(WrapperAndWorld(wrapper, world));
         }
     }
@@ -349,9 +357,9 @@ void updateDOMNodeDocument(Node* node, Document* oldDocument, Document* newDocum
     for (unsigned i = 0; i < wrapperSet.size(); ++i) {
         JSNode* wrapper = wrapperSet[i].first;
         if (newDocument)
-            newDocument->getWrapperCache(wrapperSet[i].second)->set(*wrapperSet[i].second->globalData(), node, wrapper);
+            newDocument->getWrapperCache(wrapperSet[i].second)->set(node, Weak<JSNode>(*wrapperSet[i].second->globalData(), wrapper, wrapperSet[i].second->jsNodeHandleOwner()));
         else
-            wrapperSet[i].second->m_wrappers.set(*wrapperSet[i].second->globalData(), node, wrapper);
+            wrapperSet[i].second->m_wrappers.set(node, Weak<DOMObject>(*wrapperSet[i].second->globalData(), wrapper, wrapperSet[i].second->domObjectHandleOwner()));
     }
 }
 
@@ -364,8 +372,8 @@ void markDOMObjectWrapper(MarkStack& markStack, JSGlobalData& globalData, void*
         return;
 
     for (JSGlobalDataWorldIterator worldIter(&globalData); worldIter; ++worldIter) {
-        if (HandleSlot wrapperSlot = worldIter->m_wrappers.getSlot(object))
-            markStack.deprecatedAppend(wrapperSlot);
+        if (DOMObject* wrapper = worldIter->m_wrappers.get(object).get())
+            markStack.deprecatedAppend(reinterpret_cast<JSCell**>(&wrapper));
     }
 }
 
@@ -374,15 +382,17 @@ void markDOMNodeWrapper(MarkStack& markStack, Document* document, Node* node)
     if (document) {
         JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap();
         for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) {
-            if (HandleSlot wrapperSlot = iter->second->getSlot(node))
-                markStack.deprecatedAppend(wrapperSlot);
+            JSNode* wrapper = iter->second->get(node).get();
+            if (!wrapper)
+                continue;
+            markStack.deprecatedAppend(reinterpret_cast<JSCell**>(&wrapper));
         }
         return;
     }
 
     for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) {
-        if (HandleSlot wrapperSlot = worldIter->m_wrappers.getSlot(node))
-            markStack.deprecatedAppend(wrapperSlot);
+        if (DOMObject* wrapper = worldIter->m_wrappers.get(node).get())
+            markStack.deprecatedAppend(reinterpret_cast<JSCell**>(&wrapper));
     }
 }
 
index 9d06ae6..2851f8c 100644 (file)
@@ -34,13 +34,13 @@ namespace WebCore {
 inline JSNode* getCachedDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node)
 {
     if (currentWorld(exec)->isNormal()) {
-        ASSERT(node->wrapper() == (document ? document->getWrapperCache(currentWorld(exec))->get(node) : domObjectWrapperMapFor(exec).get(node)));
+        ASSERT(node->wrapper() == (document ? document->getWrapperCache(currentWorld(exec))->get(node).get() : domObjectWrapperMapFor(exec).get(node).get()));
         return static_cast<JSNode*>(node->wrapper());
     }
 
     if (document)
-        return document->getWrapperCache(currentWorld(exec))->get(node);
-    return static_cast<JSNode*>(domObjectWrapperMapFor(exec).get(node));
+        return document->getWrapperCache(currentWorld(exec))->get(node).get();
+    return static_cast<JSNode*>(domObjectWrapperMapFor(exec).get(node).get());
 }
 
 JSC::JSValue createWrapper(JSC::ExecState*, JSDOMGlobalObject*, Node*);
index 1f0f2a0..64261e6 100644 (file)
@@ -45,7 +45,7 @@
 #include <wtf/PassRefPtr.h>
 
 #if USE(JSC)
-#include <runtime/WeakGCMap.h>
+#include <heap/Weak.h>
 #endif
 
 namespace WebCore {
@@ -948,7 +948,7 @@ public:
     virtual void resumeScriptedAnimationControllerCallbacks();
 
 #if USE(JSC)
-    typedef JSC::WeakGCMap<WebCore::Node*, JSNode> JSWrapperCache;
+    typedef HashMap<WebCore::Node*, JSC::Weak<JSNode> > JSWrapperCache;
     typedef HashMap<DOMWrapperWorld*, JSWrapperCache*> JSWrapperCacheMap;
     JSWrapperCacheMap& wrapperCacheMap() { return m_wrapperCacheMap; }
     JSWrapperCache* getWrapperCache(DOMWrapperWorld* world);