- Revision
- 93990
- Author
- [email protected]
- Date
- 2011-08-29 11:24:18 -0700 (Mon, 29 Aug 2011)
Log Message
Viewing a post on reddit.com wastes a lot of memory on event listeners.
https://bugs.webkit.org/show_bug.cgi?id=67133
Reviewed by Darin Adler.
Source/_javascript_Core:
Add a minimum table size to the HashTraits, instead of having it hard coded.
The default value remains at 64, but can now be specialized.
* runtime/StructureTransitionTable.h:
* wtf/HashTable.h:
(WTF::HashTable::shouldShrink):
(WTF::::expand):
(WTF::::checkTableConsistencyExceptSize):
* wtf/HashTraits.h:
Source/WebCore:
Specialize the HashMap used to store registered listeners on an EventTarget
to have a minimum size of 32 (rather than the default 64.)
It's very rare for pages to register listeners for so many different events
and this cuts memory consumption in half for the common case.
As an example, for a typical post on the reddit.com front page,
this reduces memory used by ~700kB on 64-bit.
* dom/EventTarget.h:
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (93989 => 93990)
--- trunk/Source/_javascript_Core/ChangeLog 2011-08-29 18:22:44 UTC (rev 93989)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-08-29 18:24:18 UTC (rev 93990)
@@ -1,3 +1,20 @@
+2011-08-29 Andreas Kling <[email protected]>
+
+ Viewing a post on reddit.com wastes a lot of memory on event listeners.
+ https://bugs.webkit.org/show_bug.cgi?id=67133
+
+ Reviewed by Darin Adler.
+
+ Add a minimum table size to the HashTraits, instead of having it hard coded.
+ The default value remains at 64, but can now be specialized.
+
+ * runtime/StructureTransitionTable.h:
+ * wtf/HashTable.h:
+ (WTF::HashTable::shouldShrink):
+ (WTF::::expand):
+ (WTF::::checkTableConsistencyExceptSize):
+ * wtf/HashTraits.h:
+
2011-08-28 Jonathan Liu <[email protected]>
Fix build error when compiling with MinGW-w64 by disabling JIT
Modified: trunk/Source/_javascript_Core/runtime/StructureTransitionTable.h (93989 => 93990)
--- trunk/Source/_javascript_Core/runtime/StructureTransitionTable.h 2011-08-29 18:22:44 UTC (rev 93989)
+++ trunk/Source/_javascript_Core/runtime/StructureTransitionTable.h 2011-08-29 18:24:18 UTC (rev 93990)
@@ -65,6 +65,8 @@
static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
+ static const int minimumTableSize = FirstTraits::minimumTableSize;
+
static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
};
Modified: trunk/Source/_javascript_Core/wtf/HashTable.h (93989 => 93990)
--- trunk/Source/_javascript_Core/wtf/HashTable.h 2011-08-29 18:22:44 UTC (rev 93989)
+++ trunk/Source/_javascript_Core/wtf/HashTable.h 2011-08-29 18:24:18 UTC (rev 93990)
@@ -377,7 +377,7 @@
bool shouldExpand() const { return (m_keyCount + m_deletedCount) * m_maxLoad >= m_tableSize; }
bool mustRehashInPlace() const { return m_keyCount * m_minLoad < m_tableSize * 2; }
- bool shouldShrink() const { return m_keyCount * m_minLoad < m_tableSize && m_tableSize > m_minTableSize; }
+ bool shouldShrink() const { return m_keyCount * m_minLoad < m_tableSize && m_tableSize > KeyTraits::minimumTableSize; }
void expand();
void shrink() { rehash(m_tableSize / 2); }
@@ -396,7 +396,7 @@
const_iterator makeKnownGoodConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); }
#if !ASSERT_DISABLED
- void checkTableConsistencyExceptSize() const;
+ void checkTableConsistenmcyExceptSize() const;
#else
static void checkTableConsistencyExceptSize() { }
#endif
@@ -407,7 +407,6 @@
static void invalidateIterators() { }
#endif
- static const int m_minTableSize = 64;
static const int m_maxLoad = 2;
static const int m_minLoad = 6;
@@ -901,7 +900,7 @@
{
int newSize;
if (m_tableSize == 0)
- newSize = m_minTableSize;
+ newSize = KeyTraits::minimumTableSize;
else if (mustRehashInPlace())
newSize = m_tableSize;
else
@@ -1039,7 +1038,7 @@
ASSERT(count == m_keyCount);
ASSERT(deletedCount == m_deletedCount);
- ASSERT(m_tableSize >= m_minTableSize);
+ ASSERT(m_tableSize >= KeyTraits::minimumTableSize);
ASSERT(m_tableSizeMask);
ASSERT(m_tableSize == m_tableSizeMask + 1);
}
Modified: trunk/Source/_javascript_Core/wtf/HashTraits.h (93989 => 93990)
--- trunk/Source/_javascript_Core/wtf/HashTraits.h 2011-08-29 18:22:44 UTC (rev 93989)
+++ trunk/Source/_javascript_Core/wtf/HashTraits.h 2011-08-29 18:24:18 UTC (rev 93990)
@@ -38,10 +38,11 @@
template<typename T> struct GenericHashTraitsBase<false, T> {
static const bool emptyValueIsZero = false;
static const bool needsDestruction = true;
+ static const int minimumTableSize = 64;
};
// Default integer traits disallow both 0 and -1 as keys (max value instead of -1 for unsigned).
- template<typename T> struct GenericHashTraitsBase<true, T> {
+ template<typename T> struct GenericHashTraitsBase<true, T> : GenericHashTraitsBase<false, T> {
static const bool emptyValueIsZero = true;
static const bool needsDestruction = false;
static void constructDeletedValue(T& slot) { slot = static_cast<T>(-1); }
@@ -102,6 +103,8 @@
static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
+ static const int minimumTableSize = FirstTraits::minimumTableSize;
+
static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
};
Modified: trunk/Source/WebCore/ChangeLog (93989 => 93990)
--- trunk/Source/WebCore/ChangeLog 2011-08-29 18:22:44 UTC (rev 93989)
+++ trunk/Source/WebCore/ChangeLog 2011-08-29 18:24:18 UTC (rev 93990)
@@ -1,3 +1,20 @@
+2011-08-29 Andreas Kling <[email protected]>
+
+ Viewing a post on reddit.com wastes a lot of memory on event listeners.
+ https://bugs.webkit.org/show_bug.cgi?id=67133
+
+ Reviewed by Darin Adler.
+
+ Specialize the HashMap used to store registered listeners on an EventTarget
+ to have a minimum size of 32 (rather than the default 64.)
+ It's very rare for pages to register listeners for so many different events
+ and this cuts memory consumption in half for the common case.
+
+ As an example, for a typical post on the reddit.com front page,
+ this reduces memory used by ~700kB on 64-bit.
+
+ * dom/EventTarget.h:
+
2011-08-29 Stephen White <[email protected]>
Skia's accelerated canvas 2D implementation should use GrTexture, not DrawingBuffer
Modified: trunk/Source/WebCore/dom/EventTarget.h (93989 => 93990)
--- trunk/Source/WebCore/dom/EventTarget.h 2011-08-29 18:22:44 UTC (rev 93989)
+++ trunk/Source/WebCore/dom/EventTarget.h 2011-08-29 18:24:18 UTC (rev 93990)
@@ -86,8 +86,13 @@
typedef Vector<FiringEventIterator, 1> FiringEventIteratorVector;
typedef Vector<RegisteredEventListener, 1> EventListenerVector;
- typedef HashMap<AtomicString, EventListenerVector*> EventListenerMap;
+ struct EventListenerMapHashTraits : HashTraits<WTF::AtomicString> {
+ static const int minimumTableSize = 32;
+ };
+
+ typedef HashMap<AtomicString, EventListenerVector*, AtomicStringHash, EventListenerMapHashTraits> EventListenerMap;
+
struct EventTargetData {
WTF_MAKE_NONCOPYABLE(EventTargetData); WTF_MAKE_FAST_ALLOCATED;
public: