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);