Changeset 63751 in webkit


Ignore:
Timestamp:
Jul 20, 2010 10:20:49 AM (14 years ago)
Author:
antonm@chromium.org
Message:

2010-07-20 Anton Muhin <antonm@chromium.org>

Reviewed by Adam Barth.

[v8] Allow handles to be disposed and WebKit objects to be dereferenced even if their map is already destroyed.
https://bugs.webkit.org/show_bug.cgi?id=42634

Currently DOMDataStore could be destroyed even if it has some mappings (it gets destroyed
when its isolated context gets GCed). However in this case, handles allocated for
such objects would never be disposed as we require presence of mapping from wrapped
WebKit object to handle being collected in the map and now map is gone. That leads to
zombie objects in both WebKit (wrapped WebKit object doesn't get dereferenced) and V8
(both handle and V8 wrapper object could not be destroyed).

See http://code.google.com/p/chromium/issues/detail?id=47125 for further discussion.

  • bindings/v8/DOMData.h: (WebCore::DOMData::handleWeakObject):
  • bindings/v8/DOMDataStore.cpp: (WebCore::DOMDataStore::weakNodeCallback):
  • bindings/v8/V8DOMMap.h: (WebCore::WeakReferenceMap::~WeakReferenceMap):
Location:
trunk/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r63750 r63751  
     12010-07-20  Anton Muhin  <antonm@chromium.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        [v8] Allow handles to be disposed and WebKit objects to be dereferenced even if their map is already destroyed.
     6        https://bugs.webkit.org/show_bug.cgi?id=42634
     7
     8        Currently DOMDataStore could be destroyed even if it has some mappings (it gets destroyed
     9        when its isolated context gets GCed).  However in this case, handles allocated for
     10        such objects would never be disposed as we require presence of mapping from wrapped
     11        WebKit object to handle being collected in the map and now map is gone.  That leads to
     12        zombie objects in both WebKit (wrapped WebKit object doesn't get dereferenced) and V8
     13        (both handle and V8 wrapper object could not be destroyed).
     14
     15        See http://code.google.com/p/chromium/issues/detail?id=47125 for further discussion.
     16
     17        * bindings/v8/DOMData.h:
     18        (WebCore::DOMData::handleWeakObject):
     19        * bindings/v8/DOMDataStore.cpp:
     20        (WebCore::DOMDataStore::weakNodeCallback):
     21        * bindings/v8/V8DOMMap.h:
     22        (WebCore::WeakReferenceMap::~WeakReferenceMap):
     23
    1242010-07-20  Hans Wennborg  <hans@chromium.org>
    225
  • trunk/WebCore/bindings/v8/DOMData.h

    r55882 r63751  
    8080    void DOMData::handleWeakObject(DOMDataStore::DOMWrapperMapType mapType, v8::Persistent<v8::Object> v8Object, T* domObject)
    8181    {
     82        WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(v8Object);
    8283        DOMDataList& list = DOMDataStore::allStores();
     84        bool found = false;
    8385        for (size_t i = 0; i < list.size(); ++i) {
    8486            DOMDataStore* store = list[i];
     
    8688
    8789            DOMWrapperMap<T>* domMap = static_cast<DOMWrapperMap<T>*>(store->getDOMWrapperMap(mapType));
    88             if (domMap->removeIfPresent(domObject, v8Object))
    89                 store->domData()->derefObject(V8DOMWrapper::domWrapperType(v8Object), domObject);
     90            if (domMap->removeIfPresent(domObject, v8Object)) {
     91                derefObject(type, domObject);
     92                found = true;
     93            }
     94        }
     95
     96        // If not found, it means map for the wrapper has been already destroyed, just dispose the
     97        // handle and deref the object to fight memory leak.
     98        if (!found) {
     99            v8Object.Dispose();
     100            derefObject(type, domObject);
    90101        }
    91102    }
  • trunk/WebCore/bindings/v8/DOMDataStore.cpp

    r55882 r63751  
    164164        if (store->domNodeMap().removeIfPresent(node, v8Object)) {
    165165            ASSERT(store->domData()->owningThread() == WTF::currentThread());
    166             node->deref();  // Nobody overrides Node::deref so it's safe
    167             break; // There might be at most one wrapper for the node in world's maps
     166            node->deref(); // Nobody overrides Node::deref so it's safe
     167            return; // There might be at most one wrapper for the node in world's maps
    168168        }
    169169    }
     170
     171    // If not found, it means map for the wrapper has been already destroyed, just dispose the
     172    // handle and deref the object to fight memory leak.
     173    v8Object.Dispose();
     174    node->deref(); // Nobody overrides Node::deref so it's safe
    170175}
    171176
  • trunk/WebCore/bindings/v8/V8DOMMap.h

    r54361 r63751  
    7575        typedef AbstractWeakReferenceMap<KeyType, ValueType> Parent;
    7676        WeakReferenceMap(v8::WeakReferenceCallback callback) : Parent(callback) { }
    77         virtual ~WeakReferenceMap()
    78         {
    79     #ifndef NDEBUG
    80             if (m_map.size() > 0)
    81                 fprintf(stderr, "Leak %d JS wrappers.\n", m_map.size());
    82     #endif
    83         }
     77        virtual ~WeakReferenceMap() { }
    8478
    8579        // Get the JS wrapper object of an object.
     
    136130    protected:
    137131        HashMap<KeyType*, ValueType*> m_map;
    138         v8::WeakReferenceCallback m_weakReferenceCallback;
    139132    };
    140133
Note: See TracChangeset for help on using the changeset viewer.