Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1161)

Unified Diff: third_party/WebKit/WebCore/bindings/v8/V8EventListenerList.cpp

Issue 79059: Switch V8EventListenerList to a hashtable implementation... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/WebCore/bindings/v8/V8EventListenerList.cpp
===================================================================
--- third_party/WebKit/WebCore/bindings/v8/V8EventListenerList.cpp (revision 14992)
+++ third_party/WebKit/WebCore/bindings/v8/V8EventListenerList.cpp (working copy)
@@ -35,96 +35,149 @@
namespace WebCore {
-V8EventListenerList::V8EventListenerList(const char* name)
+V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list)
+ : m_list(list)
+ , m_vectorIndex(0)
+ , m_iter(list->m_table.begin())
{
- ASSERT(strlen(name) <= maxKeyNameLength);
- v8::HandleScope handleScope;
+}
- // Write the name into a temporary buffer, leaving 1 space at the beginning
- // for a prefix we'll vary between the inline and non-inline keys.
- char keyBuffer[maxKeyNameLength + 2] = { 0 };
- strncpy(keyBuffer + 1, name, maxKeyNameLength);
- keyBuffer[0] = '1';
- m_inlineKey = v8::Persistent<v8::String>::New(v8::String::New(keyBuffer));
- keyBuffer[0] = '2';
- m_nonInlineKey = v8::Persistent<v8::String>::New(v8::String::New(keyBuffer));
+V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list, bool shouldSeekToEnd)
+ : m_list(list)
+ , m_vectorIndex(0)
+ , m_iter(list->m_table.begin())
+{
+ if (shouldSeekToEnd)
+ seekToEnd();
}
+V8EventListenerListIterator::~V8EventListenerListIterator() { }
+
+void V8EventListenerListIterator::operator++()
+{
+ if (m_iter != m_list->m_table.end()) {
+ Vector<V8EventListener*>* vector = m_iter->second;
+ if (m_vectorIndex + 1 < vector->size()) {
+ m_vectorIndex++;
+ return;
+ }
+ m_vectorIndex = 0;
+ ++m_iter;
+ }
+}
+
+bool V8EventListenerListIterator::operator==(const V8EventListenerListIterator& other)
+{
+ return other.m_iter == m_iter && other.m_vectorIndex == m_vectorIndex && other.m_list == m_list;
+}
+
+bool V8EventListenerListIterator::operator!=(const V8EventListenerListIterator& other)
+{
+ return !operator==(other);
+}
+
+V8EventListener* V8EventListenerListIterator::operator*()
+{
+ if (m_iter != m_list->m_table.end()) {
+ Vector<V8EventListener*>* vector = m_iter->second;
+ if (m_vectorIndex < vector->size())
+ return vector->at(m_vectorIndex);
+ }
+ return 0;
+}
+
+void V8EventListenerListIterator::seekToEnd()
+{
+ m_iter = m_list->m_table.end();
+ m_vectorIndex = 0;
+}
+
+
+V8EventListenerList::V8EventListenerList()
+{
+}
+
V8EventListenerList::~V8EventListenerList()
{
- m_inlineKey.Dispose();
- m_nonInlineKey.Dispose();
}
-V8EventListenerList::iterator V8EventListenerList::begin()
+V8EventListenerListIterator V8EventListenerList::begin()
{
- return m_list.begin();
+ return iterator(this);
}
-V8EventListenerList::iterator V8EventListenerList::end()
+V8EventListenerListIterator V8EventListenerList::end()
{
- return m_list.end();
+ return iterator(this, true);
}
-v8::Handle<v8::String> V8EventListenerList::getKey(bool isInline)
+
+int getKey(v8::Local<v8::Object> object)
{
- return isInline ? m_inlineKey : m_nonInlineKey;
+ // 0 is a sentinel value for the HashMap key, so we map it to 1.
+ int hash = object->GetIdentityHash();
+ if (!hash)
+ return 1;
+ return hash;
}
-// See comment in .h file for this function, and update accordingly if implementation details change here.
void V8EventListenerList::add(V8EventListener* listener)
{
- // FIXME: http://crbug.com/10562
- //ASSERT(v8::Context::InContext());
- m_list.append(listener);
+ ASSERT(v8::Context::InContext());
+ v8::HandleScope handleScope;
- v8::HandleScope handleScope;
v8::Local<v8::Object> object = listener->getListenerObject();
- v8::Local<v8::Value> value = v8::External::Wrap(listener);
- object->SetHiddenValue(getKey(listener->isAttribute()), value);
+ int key = getKey(object);
+ Vector<V8EventListener*>* vector = m_table.get(key);
+ if (!vector) {
+ vector = new Vector<V8EventListener*>();
+ m_table.set(key, vector);
+ }
+ vector->append(listener);
+ m_reverseTable.set(listener, key);
}
void V8EventListenerList::remove(V8EventListener* listener)
{
- // FIXME: http://crbug.com/10562
- //ASSERT(v8::Context::InContext());
- v8::HandleScope handleScope;
- v8::Handle<v8::String> key = getKey(listener->isAttribute());
- for (size_t i = 0; i < m_list.size(); i++) {
- V8EventListener* element = m_list.at(i);
- if (element->isAttribute() == listener->isAttribute() && element == listener) {
- v8::Local<v8::Object> object = listener->getListenerObject();
+ if (m_reverseTable.contains(listener)) {
+ int key = m_reverseTable.get(listener);
+ Vector<V8EventListener*>* vector = m_table.get(key);
+ if (!vector)
+ return;
+ for (size_t j = 0; j < vector->size(); j++) {
+ if (vector->at(j) == listener) {
+ vector->remove(j);
+ if (!vector->size())
+ m_table.remove(key);
- // FIXME(asargent) this check for hidden value being !empty is a workaround for
- // http://code.google.com/p/v8/issues/detail?id=300
- // Once the fix for that is pulled into chromium we can remove the check here.
- if (!object->GetHiddenValue(key).IsEmpty())
- object->DeleteHiddenValue(getKey(listener->isAttribute()));
- m_list.remove(i);
- break;
+ m_reverseTable.remove(listener);
+ return;
+ }
}
}
}
void V8EventListenerList::clear()
{
- // FIXME: http://crbug.com/10562
- //ASSERT(v8::Context::InContext());
- v8::HandleScope handleScope;
- for (size_t i = 0; i < m_list.size(); i++) {
- V8EventListener* element = m_list.at(i);
- v8::Local<v8::Object> object = element->getListenerObject();
- object->DeleteHiddenValue(getKey(element->isAttribute()));
- }
- m_list.clear();
+ m_table.clear();
+ m_reverseTable.clear();
}
-V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isInline)
+V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isAttribute)
{
- v8::Local<v8::Value> value = object->GetHiddenValue(getKey(isInline));
- if (value.IsEmpty())
+ ASSERT(v8::Context::InContext());
+ int key = getKey(object);
+
+ Vector<V8EventListener*>* vector = m_table.get(key);
+ if (!vector)
return 0;
- return reinterpret_cast<V8EventListener*>(v8::External::Unwrap(value));
+
+ for (size_t i = 0; i < vector->size(); i++) {
+ V8EventListener* element = vector->at(i);
+ if (isAttribute == element->isAttribute() && object == element->getListenerObject())
+ return element;
+ }
+ return 0;
}
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698