Simplify the insides of DocumentSharedObjectPool and reduce memory usage.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Jan 2014 18:45:33 +0000 (18:45 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Jan 2014 18:45:33 +0000 (18:45 +0000)
Merging Blink r164152 by Elliott Sprehn.

Instead of storing an OwnPtr to an object that has a pointer to the
ShareableElementData as well as a pointer into the ShareableElementData
and the length we can just store a RefPtr to the SharableElementData.

This also reduces the memory usage of the pool by 2 pointers per entry.

* dom/DocumentSharedObjectPool.h:
* dom/DocumentSharedObjectPool.cpp:
(WebCore::attributeHash):
(WebCore::hasSameAttributes):
(WebCore::DocumentSharedObjectPool::cachedShareableElementDataWithAttributes):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@161210 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/DocumentSharedObjectPool.cpp
Source/WebCore/dom/DocumentSharedObjectPool.h

index 391f8aabb2fe7f99680e1ba2cc98488e27f88f21..ab001c266c3b20edab1abc0526ae7abb37a5978d 100644 (file)
@@ -1,3 +1,21 @@
+2014-01-02  Andreas Kling  <akling@apple.com>
+
+        Simplify the insides of DocumentSharedObjectPool and reduce memory usage.
+
+        Merging Blink r164152 by Elliott Sprehn.
+
+        Instead of storing an OwnPtr to an object that has a pointer to the
+        ShareableElementData as well as a pointer into the ShareableElementData
+        and the length we can just store a RefPtr to the SharableElementData.
+
+        This also reduces the memory usage of the pool by 2 pointers per entry.
+
+        * dom/DocumentSharedObjectPool.h:
+        * dom/DocumentSharedObjectPool.cpp:
+        (WebCore::attributeHash):
+        (WebCore::hasSameAttributes):
+        (WebCore::DocumentSharedObjectPool::cachedShareableElementDataWithAttributes):
+
 2014-01-02  Dirk Schulze  <krit@webkit.org>
 
         Support <box> values computed style for 'clip-path' property
index 911259fda74754e2da7fa1e399bdf9e4f2ad8c3d..2cf7aeab3a8fcb9ee0fc252ed3499f940394afe6 100644 (file)
 
 namespace WebCore {
 
-class ShareableElementDataCacheKey {
-public:
-    ShareableElementDataCacheKey(const Attribute* attributes, unsigned attributeCount)
-        : m_attributes(attributes)
-        , m_attributeCount(attributeCount)
-    { }
-
-    bool operator!=(const ShareableElementDataCacheKey& other) const
-    {
-        if (m_attributeCount != other.m_attributeCount)
-            return true;
-        return memcmp(m_attributes, other.m_attributes, sizeof(Attribute) * m_attributeCount);
-    }
-
-    unsigned hash() const
-    {
-        return StringHasher::hashMemory(m_attributes, m_attributeCount * sizeof(Attribute));
-    }
-
-private:
-    const Attribute* m_attributes;
-    unsigned m_attributeCount;
-};
-
-class ShareableElementDataCacheEntry {
-public:
-    ShareableElementDataCacheEntry(const ShareableElementDataCacheKey& k, ShareableElementData& v)
-        : key(k)
-        , value(v)
-    { }
+inline unsigned attributeHash(const Vector<Attribute>& attributes)
+{
+    return StringHasher::hashMemory(attributes.data(), attributes.size() * sizeof(Attribute));
+}
 
-    ShareableElementDataCacheKey key;
-    Ref<ShareableElementData> value;
-};
+inline bool hasSameAttributes(const Vector<Attribute>& attributes, ShareableElementData& elementData)
+{
+    if (attributes.size() != elementData.length())
+        return false;
+    return !memcmp(attributes.data(), elementData.m_attributeArray, attributes.size() * sizeof(Attribute));
+}
 
 PassRef<ShareableElementData> DocumentSharedObjectPool::cachedShareableElementDataWithAttributes(const Vector<Attribute>& attributes)
 {
     ASSERT(!attributes.isEmpty());
 
-    ShareableElementDataCacheKey cacheKey(attributes.data(), attributes.size());
-    unsigned cacheHash = cacheKey.hash();
-
-    ShareableElementDataCache::iterator cacheIterator = m_shareableElementDataCache.add(cacheHash, nullptr).iterator;
-    if (cacheIterator->value && cacheIterator->value->key != cacheKey)
-        cacheHash = 0;
-
-    RefPtr<ShareableElementData> elementData;
-    if (cacheHash && cacheIterator->value)
-        elementData = &cacheIterator->value->value.get();
-    else
-        elementData = ShareableElementData::createWithAttributes(attributes);
+    auto& cachedData = m_shareableElementDataCache.add(attributeHash(attributes), nullptr).iterator->value;
 
-    if (!cacheHash || cacheIterator->value)
-        return elementData.releaseNonNull();
+    // FIXME: This prevents sharing when there's a hash collision.
+    if (cachedData && !hasSameAttributes(attributes, *cachedData))
+        return ShareableElementData::createWithAttributes(attributes);
 
-    cacheIterator->value = adoptPtr(new ShareableElementDataCacheEntry(ShareableElementDataCacheKey(elementData->m_attributeArray, elementData->length()), *elementData));
+    if (!cachedData)
+        cachedData = ShareableElementData::createWithAttributes(attributes);
 
-    return elementData.releaseNonNull();
+    return *cachedData;
 }
 
 DocumentSharedObjectPool::DocumentSharedObjectPool()
index 9b645f1b0b34cce0978c5ff491ed3ac5188656c8..21ca8f5a681752c02cba2f4515e34181571f42a5 100644 (file)
 
 #include <wtf/HashMap.h>
 #include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
 #include <wtf/text/StringHash.h>
 
 namespace WebCore {
 
 class Attribute;
 class ShareableElementData;
-class ShareableElementDataCacheEntry;
 
 class DocumentSharedObjectPool {
 public:
@@ -47,7 +47,7 @@ public:
 private:
     DocumentSharedObjectPool();
 
-    typedef HashMap<unsigned, OwnPtr<ShareableElementDataCacheEntry>, AlreadyHashed> ShareableElementDataCache;
+    typedef HashMap<unsigned, RefPtr<ShareableElementData>, AlreadyHashed> ShareableElementDataCache;
     ShareableElementDataCache m_shareableElementDataCache;
 };