Title: [130189] trunk/Source/WebCore
Revision
130189
Author
o...@chromium.org
Date
2012-10-02 11:09:33 -0700 (Tue, 02 Oct 2012)

Log Message

Unreviewed, rolling out r130103 and r130125.
http://trac.webkit.org/changeset/130103
http://trac.webkit.org/changeset/130125
https://bugs.webkit.org/show_bug.cgi?id=97974

Causes performance regressions on Dromaeo dom modify tests.

* bindings/v8/IntrusiveDOMWrapperMap.h:
(WebCore):
(ChunkedTable):
(WebCore::ChunkedTable::ChunkedTable):
(WebCore::ChunkedTable::add):
(WebCore::ChunkedTable::remove):
(WebCore::ChunkedTable::clear):
(WebCore::ChunkedTable::visit):
(WebCore::ChunkedTable::reportMemoryUsage):
(WebCore::ChunkedTable::Chunk::Chunk):
(Chunk):
(WebCore::ChunkedTable::clearEntries):
(WebCore::ChunkedTable::visitEntries):
(WebCore::IntrusiveDOMWrapperMap::IntrusiveDOMWrapperMap):
(WebCore::IntrusiveDOMWrapperMap::get):
(WebCore::IntrusiveDOMWrapperMap::set):
(WebCore::IntrusiveDOMWrapperMap::contains):
(WebCore::IntrusiveDOMWrapperMap::visit):
(WebCore::IntrusiveDOMWrapperMap::removeIfPresent):
(IntrusiveDOMWrapperMap):
(WebCore::IntrusiveDOMWrapperMap::clear):
(ChunkedTableTraits):
(WebCore::IntrusiveDOMWrapperMap::ChunkedTableTraits::move):
(WebCore::IntrusiveDOMWrapperMap::ChunkedTableTraits::clear):
(WebCore::IntrusiveDOMWrapperMap::ChunkedTableTraits::visit):
* bindings/v8/ScriptWrappable.h:
(WebCore::ScriptWrappable::ScriptWrappable):
(WebCore::ScriptWrappable::wrapper):
(WebCore::ScriptWrappable::setWrapper):
(WebCore::ScriptWrappable::clearWrapper):
(WebCore::ScriptWrappable::reportMemoryUsage):
(ScriptWrappable):
* bindings/v8/V8DOMWrapper.h:
(WebCore::V8DOMWrapper::getCachedWrapper):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (130188 => 130189)


--- trunk/Source/WebCore/ChangeLog	2012-10-02 18:03:02 UTC (rev 130188)
+++ trunk/Source/WebCore/ChangeLog	2012-10-02 18:09:33 UTC (rev 130189)
@@ -1,3 +1,47 @@
+2012-10-02  Ojan Vafai  <o...@chromium.org>
+
+        Unreviewed, rolling out r130103 and r130125.
+        http://trac.webkit.org/changeset/130103
+        http://trac.webkit.org/changeset/130125
+        https://bugs.webkit.org/show_bug.cgi?id=97974
+
+        Causes performance regressions on Dromaeo dom modify tests.
+
+        * bindings/v8/IntrusiveDOMWrapperMap.h:
+        (WebCore):
+        (ChunkedTable):
+        (WebCore::ChunkedTable::ChunkedTable):
+        (WebCore::ChunkedTable::add):
+        (WebCore::ChunkedTable::remove):
+        (WebCore::ChunkedTable::clear):
+        (WebCore::ChunkedTable::visit):
+        (WebCore::ChunkedTable::reportMemoryUsage):
+        (WebCore::ChunkedTable::Chunk::Chunk):
+        (Chunk):
+        (WebCore::ChunkedTable::clearEntries):
+        (WebCore::ChunkedTable::visitEntries):
+        (WebCore::IntrusiveDOMWrapperMap::IntrusiveDOMWrapperMap):
+        (WebCore::IntrusiveDOMWrapperMap::get):
+        (WebCore::IntrusiveDOMWrapperMap::set):
+        (WebCore::IntrusiveDOMWrapperMap::contains):
+        (WebCore::IntrusiveDOMWrapperMap::visit):
+        (WebCore::IntrusiveDOMWrapperMap::removeIfPresent):
+        (IntrusiveDOMWrapperMap):
+        (WebCore::IntrusiveDOMWrapperMap::clear):
+        (ChunkedTableTraits):
+        (WebCore::IntrusiveDOMWrapperMap::ChunkedTableTraits::move):
+        (WebCore::IntrusiveDOMWrapperMap::ChunkedTableTraits::clear):
+        (WebCore::IntrusiveDOMWrapperMap::ChunkedTableTraits::visit):
+        * bindings/v8/ScriptWrappable.h:
+        (WebCore::ScriptWrappable::ScriptWrappable):
+        (WebCore::ScriptWrappable::wrapper):
+        (WebCore::ScriptWrappable::setWrapper):
+        (WebCore::ScriptWrappable::clearWrapper):
+        (WebCore::ScriptWrappable::reportMemoryUsage):
+        (ScriptWrappable):
+        * bindings/v8/V8DOMWrapper.h:
+        (WebCore::V8DOMWrapper::getCachedWrapper):
+
 2012-10-02  Ilya Tikhonovsky  <loi...@chromium.org>
 
         Web Inspector: NMI: switch to non intrusive instrumentation of ParsedURL.

Modified: trunk/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h (130188 => 130189)


--- trunk/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h	2012-10-02 18:03:02 UTC (rev 130188)
+++ trunk/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h	2012-10-02 18:09:33 UTC (rev 130189)
@@ -34,69 +34,196 @@
 #include "DOMDataStore.h"
 #include "V8Node.h"
 #include "WebCoreMemoryInstrumentation.h"
-#include <wtf/HashSet.h>
 
 namespace WebCore {
 
+template <class T, int CHUNK_SIZE, class Traits>
+class ChunkedTable {
+  public:
+    ChunkedTable() : m_chunks(0), m_current(0), m_last(0) { }
+
+    T* add(T element)
+    {
+        if (m_current == m_last) {
+            m_chunks = new Chunk(m_chunks);
+            m_current = m_chunks->m_entries;
+            m_last = m_current + CHUNK_SIZE;
+        }
+        ASSERT((m_chunks->m_entries <= m_current) && (m_current < m_last));
+        T* p = m_current++;
+        *p = element;
+        return p;
+    }
+
+    void remove(T* element)
+    {
+        ASSERT(element);
+        ASSERT(m_current > m_chunks->m_entries);
+        m_current--;
+        if (element != m_current)
+            Traits::move(element, m_current);
+        if (m_current == m_chunks->m_entries) {
+            Chunk* toDelete = m_chunks;
+            m_chunks = toDelete->m_previous;
+            m_current = m_last = m_chunks ? m_chunks->m_entries + CHUNK_SIZE : 0;
+            delete toDelete;
+        }
+        ASSERT(!m_chunks || ((m_chunks->m_entries < m_current) && (m_current <= m_last)));
+    }
+
+    void clear()
+    {
+        if (!m_chunks)
+            return;
+
+        clearEntries(m_chunks->m_entries, m_current);
+        Chunk* last = m_chunks;
+        while (true) {
+            Chunk* previous = last->m_previous;
+            if (!previous)
+                break;
+            delete last;
+            clearEntries(previous->m_entries, previous->m_entries + CHUNK_SIZE);
+            last = previous;
+        }
+
+        m_chunks = last;
+        m_current = m_chunks->m_entries;
+        m_last = m_current + CHUNK_SIZE;
+    }
+
+    void visit(DOMDataStore* store, typename Traits::Visitor* visitor)
+    {
+        if (!m_chunks)
+            return;
+
+        visitEntries(store, m_chunks->m_entries, m_current, visitor);
+        for (Chunk* chunk = m_chunks->m_previous; chunk; chunk = chunk->m_previous)
+            visitEntries(store, chunk->m_entries, chunk->m_entries + CHUNK_SIZE, visitor);
+    }
+
+    void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+    {
+        MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding);
+        for (Chunk* chunk = m_chunks; chunk; chunk = chunk->m_previous)
+            info.addMember(chunk);
+    }
+
+  private:
+    struct Chunk {
+        explicit Chunk(Chunk* previous) : m_previous(previous) { }
+        Chunk* const m_previous;
+        T m_entries[CHUNK_SIZE];
+    };
+
+    static void clearEntries(T* first, T* last)
+    {
+        for (T* entry = first; entry < last; entry++)
+            Traits::clear(entry);
+    }
+
+    static void visitEntries(DOMDataStore* store, T* first, T* last, typename Traits::Visitor* visitor)
+    {
+        for (T* entry = first; entry < last; entry++)
+            Traits::visit(store, entry, visitor);
+    }
+
+    Chunk* m_chunks;
+    T* m_current;
+    T* m_last;
+};
+
+
 class IntrusiveDOMWrapperMap : public AbstractWeakReferenceMap<Node, v8::Object> {
 public:
     IntrusiveDOMWrapperMap(v8::WeakReferenceCallback callback)
-        : AbstractWeakReferenceMap<Node, v8::Object>(callback)
-    {
-    }
+        : AbstractWeakReferenceMap<Node, v8::Object>(callback) { }
 
-    virtual v8::Persistent<v8::Object> get(Node* node)
+    virtual v8::Persistent<v8::Object> get(Node* obj)
     {
-        return node->wrapper();
+        v8::Persistent<v8::Object>* wrapper = obj->wrapper();
+        return wrapper ? *wrapper : v8::Persistent<v8::Object>();
     }
 
-    virtual void set(Node* node, v8::Persistent<v8::Object> wrapper)
+    virtual void set(Node* obj, v8::Persistent<v8::Object> wrapper)
     {
-        ASSERT(node && node->wrapper().IsEmpty());
-        m_nodes.add(node);
-        node->setWrapper(wrapper);
-        wrapper.MakeWeak(node, weakReferenceCallback());
+        ASSERT(obj);
+        ASSERT(!obj->wrapper());
+        v8::Persistent<v8::Object>* entry = m_table.add(wrapper);
+        obj->setWrapper(entry);
+        wrapper.MakeWeak(obj, weakReferenceCallback());
     }
 
-    virtual bool contains(Node* node)
+    virtual bool contains(Node* obj)
     {
-        bool nodeHasWrapper = !node->wrapper().IsEmpty();
-        ASSERT(nodeHasWrapper == m_nodes.contains(node));
-        return nodeHasWrapper;
+        return obj->wrapper();
     }
 
     virtual void visit(DOMDataStore* store, Visitor* visitor)
     {
-        for (HashSet<Node*>::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
-            visitor->visitDOMWrapper(store, *it, (*it)->wrapper());
+        m_table.visit(store, visitor);
     }
 
-    virtual bool removeIfPresent(Node* node, v8::Persistent<v8::Object> value)
+    virtual bool removeIfPresent(Node* obj, v8::Persistent<v8::Object> value)
     {
-        ASSERT(node);
-        v8::Persistent<v8::Object> wrapper = node->wrapper();
-        if (wrapper.IsEmpty())
+        ASSERT(obj);
+        v8::Persistent<v8::Object>* entry = obj->wrapper();
+        if (!entry)
             return false;
-        if (wrapper != value)
+        if (*entry != value)
             return false;
-        node->disposeWrapper();
-        m_nodes.remove(node);
+        obj->clearWrapper();
+        m_table.remove(entry);
+        value.Dispose();
         return true;
     }
 
+
     virtual void clear()
     {
-        m_nodes.clear();
+        m_table.clear();
     }
 
     virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const OVERRIDE
     {
         MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Binding);
-        info.addMember(m_nodes);
+        info.addMember(m_table);
     }
 
 private:
-    HashSet<Node*> m_nodes;
+    static int const numberOfEntries = (1 << 10) - 1;
+
+    struct ChunkedTableTraits {
+        typedef IntrusiveDOMWrapperMap::Visitor Visitor;
+
+        static void move(v8::Persistent<v8::Object>* target, v8::Persistent<v8::Object>* source)
+        {
+            *target = *source;
+            Node* node = V8Node::toNative(*target);
+            ASSERT(node);
+            node->setWrapper(target);
+        }
+
+        static void clear(v8::Persistent<v8::Object>* entry)
+        {
+            Node* node = V8Node::toNative(*entry);
+            ASSERT(node->wrapper() == entry);
+
+            node->clearWrapper();
+            entry->Dispose();
+        }
+
+        static void visit(DOMDataStore* store, v8::Persistent<v8::Object>* entry, Visitor* visitor)
+        {
+            Node* node = V8Node::toNative(*entry);
+            ASSERT(node->wrapper() == entry);
+
+            visitor->visitDOMWrapper(store, node, *entry);
+        }
+    };
+
+    typedef ChunkedTable<v8::Persistent<v8::Object>, numberOfEntries, ChunkedTableTraits> Table;
+    Table m_table;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/v8/ScriptWrappable.h (130188 => 130189)


--- trunk/Source/WebCore/bindings/v8/ScriptWrappable.h	2012-10-02 18:03:02 UTC (rev 130188)
+++ trunk/Source/WebCore/bindings/v8/ScriptWrappable.h	2012-10-02 18:09:33 UTC (rev 130189)
@@ -38,36 +38,29 @@
 
 class ScriptWrappable {
 public:
-    ScriptWrappable()
-    {
-    }
+    ScriptWrappable() : m_wrapper(0) { }
 
-    v8::Persistent<v8::Object> wrapper() const
+    v8::Persistent<v8::Object>* wrapper() const
     {
         return m_wrapper;
     }
 
-    void setWrapper(v8::Persistent<v8::Object> wrapper)
+    void setWrapper(v8::Persistent<v8::Object>* wrapper)
     {
-        ASSERT(!wrapper.IsEmpty());
+        ASSERT(wrapper);
         m_wrapper = wrapper;
     }
 
-    void disposeWrapper()
-    {
-        ASSERT(!m_wrapper.IsEmpty());
-        m_wrapper.Dispose();
-        m_wrapper.Clear();
-    }
+    void clearWrapper() { m_wrapper = 0; }
 
     void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     {
         MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
-        info.addWeakPointer(const_cast<v8::Persistent<v8::Object>*>(&m_wrapper));
+        info.addWeakPointer(m_wrapper);
     }
 
 private:
-    v8::Persistent<v8::Object> m_wrapper;
+    v8::Persistent<v8::Object>* m_wrapper;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/v8/V8DOMWrapper.h (130188 => 130189)


--- trunk/Source/WebCore/bindings/v8/V8DOMWrapper.h	2012-10-02 18:03:02 UTC (rev 130188)
+++ trunk/Source/WebCore/bindings/v8/V8DOMWrapper.h	2012-10-02 18:09:33 UTC (rev 130189)
@@ -113,15 +113,18 @@
         {
             ASSERT(isMainThread());
             if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) {
-                v8::Persistent<v8::Object> wrapper = node->wrapper();
-                if (LIKELY(!wrapper.IsEmpty()))
-                    return wrapper;
+                v8::Persistent<v8::Object>* wrapper = node->wrapper();
+                if (LIKELY(!!wrapper))
+                    return *wrapper;
             }
 
             V8DOMWindowShell* context = V8DOMWindowShell::getEntered();
-            if (LIKELY(!context))
-                return node->wrapper();
-
+            if (LIKELY(!context)) {
+                v8::Persistent<v8::Object>* wrapper = node->wrapper();
+                if (!wrapper)
+                    return v8::Handle<v8::Object>();
+                return *wrapper;
+            }
             DOMDataStore* store = context->world()->domDataStore();
             DOMNodeMapping& domNodeMap = node->isActiveNode() ? store->activeDomNodeMap() : store->domNodeMap();
             return domNodeMap.get(node);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to