Title: [136334] trunk/Source/WebCore
Revision
136334
Author
[email protected]
Date
2012-12-02 04:03:44 -0800 (Sun, 02 Dec 2012)

Log Message

Keep ElementAttributeData sharing cache open for a while after document parsing finishes.
<http://webkit.org/b/103720>

Reviewed by Antti Koivisto.

Allow web pages that generate content dynamically to benefit more from the ElementAttributeData sharing
cache by keeping it open for 10 seconds after document parsing finishes. This enables elements constructed
from HTML fragments to share attribute data with other identical elements.

Elements created via Document.createElement are still unsupported since we don't know the list of attributes
at the time of construction.

401kB progression on Membuster3.

Document now holds on to a DocumentSharedObjectPool, accessible via Document::sharedObjectPool().
It is non-null during parsing and for some time afterwards, and can be used to implement additional
caches that are not worth holding on to permanently.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
* WebCore.vcproj/WebCore.vcproj:

    Add new class DocumentSharedObjectPool.

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::setParsing):
(WebCore::Document::finishedParsing):
(WebCore::Document::sharedObjectPoolClearTimerFired):
* dom/Document.h:
(WebCore::Document::sharedObjectPool):

    Create DocumentSharedObjectPool when parsing starts, kill it on a 10s timer after parsing finishes.

* dom/DocumentSharedObjectPool.cpp: Added.
(ImmutableElementAttributeDataCacheKey):
(WebCore::ImmutableElementAttributeDataCacheKey::ImmutableElementAttributeDataCacheKey):
(WebCore::ImmutableElementAttributeDataCacheKey::operator!=):
(WebCore::ImmutableElementAttributeDataCacheKey::hash):
(ImmutableElementAttributeDataCacheEntry):
(WebCore::ImmutableElementAttributeDataCacheEntry::ImmutableElementAttributeDataCacheEntry):
(WebCore::DocumentSharedObjectPool::cachedImmutableElementAttributeData):
(WebCore::DocumentSharedObjectPool::DocumentSharedObjectPool):
(WebCore::DocumentSharedObjectPool::~DocumentSharedObjectPool):
* dom/DocumentSharedObjectPool.h: Added.
(DocumentSharedObjectPool):
(WebCore::DocumentSharedObjectPool::create):
* dom/Element.cpp:
(WebCore::Element::parserSetAttributes):

    Moved the ElementAttributeData cache to DocumentSharedObjectPool.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/CMakeLists.txt (136333 => 136334)


--- trunk/Source/WebCore/CMakeLists.txt	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/CMakeLists.txt	2012-12-02 12:03:44 UTC (rev 136334)
@@ -1145,6 +1145,7 @@
     dom/DocumentFragment.cpp
     dom/DocumentParser.cpp
     dom/DocumentOrderedMap.cpp
+    dom/DocumentSharedObjectPool.cpp
     dom/DocumentStyleSheetCollection.cpp
     dom/DocumentType.cpp
     dom/Element.cpp

Modified: trunk/Source/WebCore/ChangeLog (136333 => 136334)


--- trunk/Source/WebCore/ChangeLog	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/ChangeLog	2012-12-02 12:03:44 UTC (rev 136334)
@@ -1,3 +1,60 @@
+2012-12-02  Andreas Kling  <[email protected]>
+
+        Keep ElementAttributeData sharing cache open for a while after document parsing finishes.
+        <http://webkit.org/b/103720>
+
+        Reviewed by Antti Koivisto.
+
+        Allow web pages that generate content dynamically to benefit more from the ElementAttributeData sharing
+        cache by keeping it open for 10 seconds after document parsing finishes. This enables elements constructed
+        from HTML fragments to share attribute data with other identical elements.
+
+        Elements created via Document.createElement are still unsupported since we don't know the list of attributes
+        at the time of construction.
+
+        401kB progression on Membuster3.
+
+        Document now holds on to a DocumentSharedObjectPool, accessible via Document::sharedObjectPool().
+        It is non-null during parsing and for some time afterwards, and can be used to implement additional
+        caches that are not worth holding on to permanently.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        * WebCore.vcproj/WebCore.vcproj:
+
+            Add new class DocumentSharedObjectPool.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::setParsing):
+        (WebCore::Document::finishedParsing):
+        (WebCore::Document::sharedObjectPoolClearTimerFired):
+        * dom/Document.h:
+        (WebCore::Document::sharedObjectPool):
+
+            Create DocumentSharedObjectPool when parsing starts, kill it on a 10s timer after parsing finishes.
+
+        * dom/DocumentSharedObjectPool.cpp: Added.
+        (ImmutableElementAttributeDataCacheKey):
+        (WebCore::ImmutableElementAttributeDataCacheKey::ImmutableElementAttributeDataCacheKey):
+        (WebCore::ImmutableElementAttributeDataCacheKey::operator!=):
+        (WebCore::ImmutableElementAttributeDataCacheKey::hash):
+        (ImmutableElementAttributeDataCacheEntry):
+        (WebCore::ImmutableElementAttributeDataCacheEntry::ImmutableElementAttributeDataCacheEntry):
+        (WebCore::DocumentSharedObjectPool::cachedImmutableElementAttributeData):
+        (WebCore::DocumentSharedObjectPool::DocumentSharedObjectPool):
+        (WebCore::DocumentSharedObjectPool::~DocumentSharedObjectPool):
+        * dom/DocumentSharedObjectPool.h: Added.
+        (DocumentSharedObjectPool):
+        (WebCore::DocumentSharedObjectPool::create):
+        * dom/Element.cpp:
+        (WebCore::Element::parserSetAttributes):
+
+            Moved the ElementAttributeData cache to DocumentSharedObjectPool.
+
 2012-12-02  John Bauman  <[email protected]>
 
         [chromium] Let Pepper Flash use integrated GPU

Modified: trunk/Source/WebCore/GNUmakefile.list.am (136333 => 136334)


--- trunk/Source/WebCore/GNUmakefile.list.am	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2012-12-02 12:03:44 UTC (rev 136334)
@@ -2757,6 +2757,8 @@
 	Source/WebCore/dom/DocumentOrderedMap.h \
 	Source/WebCore/dom/DocumentParser.cpp \
 	Source/WebCore/dom/DocumentParser.h \
+	Source/WebCore/dom/DocumentSharedObjectPool.cpp \
+	Source/WebCore/dom/DocumentSharedObjectPool.h \
     Source/WebCore/dom/DocumentStyleSheetCollection.cpp \
     Source/WebCore/dom/DocumentStyleSheetCollection.h \
 	Source/WebCore/dom/DocumentTiming.h \

Modified: trunk/Source/WebCore/Target.pri (136333 => 136334)


--- trunk/Source/WebCore/Target.pri	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/Target.pri	2012-12-02 12:03:44 UTC (rev 136334)
@@ -375,6 +375,7 @@
     dom/DocumentMarker.cpp \
     dom/DocumentOrderedMap.cpp \
     dom/DocumentParser.cpp \
+    dom/DocumentSharedObjectPool.cpp \
     dom/DocumentStyleSheetCollection.cpp \
     dom/DocumentType.cpp \
     dom/DOMCoreException.cpp \
@@ -1556,6 +1557,7 @@
     dom/DocumentMarker.h \
     dom/DocumentMarkerController.h \
     dom/DocumentOrderedMap.h \
+    dom/DocumentSharedObjectPool.h \
     dom/DocumentStyleSheetCollection.h \
     dom/DocumentType.h \
     dom/DOMError.h \

Modified: trunk/Source/WebCore/WebCore.gypi (136333 => 136334)


--- trunk/Source/WebCore/WebCore.gypi	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/WebCore.gypi	2012-12-02 12:03:44 UTC (rev 136334)
@@ -659,6 +659,7 @@
             'dom/DocumentMarkerController.h',
             'dom/DocumentOrderedMap.h',
             'dom/DocumentParser.h',
+            'dom/DocumentSharedObjectPool.h',
             'dom/DocumentStyleSheetCollection.h',
             'dom/DocumentTiming.h',
             'dom/DocumentType.h',
@@ -3806,6 +3807,7 @@
             'dom/DocumentMarker.cpp',
             'dom/DocumentOrderedMap.cpp',
             'dom/DocumentParser.cpp',
+            'dom/DocumentSharedObjectPool.cpp',
             'dom/DocumentStyleSheetCollection.cpp',
             'dom/DocumentType.cpp',
             'dom/ElementShadow.cpp',

Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (136333 => 136334)


--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj	2012-12-02 12:03:44 UTC (rev 136334)
@@ -50674,6 +50674,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\dom\DocumentSharedObjectPool.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\dom\DocumentSharedObjectPool.h"
+				>
+			</File>
+			<File
 				RelativePath="..\dom\DocumentStyleSheetCollection.cpp"
 				>
 			</File>

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (136333 => 136334)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-12-02 12:03:44 UTC (rev 136334)
@@ -4626,6 +4626,8 @@
 		AD03AAFA1468455300A39B5B /* CSSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD03AAF81468453900A39B5B /* CSSValue.cpp */; };
 		AD4495F3141FC08900541EDF /* EventListenerMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4495F1141FC08900541EDF /* EventListenerMap.cpp */; };
 		AD4495F4141FC08900541EDF /* EventListenerMap.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4495F2141FC08900541EDF /* EventListenerMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		AD6E71AC1668899D00320C13 /* DocumentSharedObjectPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */; };
+		AD6E71AD1668899D00320C13 /* DocumentSharedObjectPool.h in Headers */ = {isa = PBXBuildFile; fileRef = AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */; };
 		ADDF1AD71257CD9A0003A759 /* RenderSVGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */; };
 		B10B6980140C174000BC1C26 /* WebVTTToken.h in Headers */ = {isa = PBXBuildFile; fileRef = B10B697D140C174000BC1C26 /* WebVTTToken.h */; };
 		B10B6981140C174000BC1C26 /* WebVTTTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B10B697E140C174000BC1C26 /* WebVTTTokenizer.cpp */; };
@@ -11845,6 +11847,8 @@
 		AD03AAF81468453900A39B5B /* CSSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSValue.cpp; sourceTree = "<group>"; };
 		AD4495F1141FC08900541EDF /* EventListenerMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventListenerMap.cpp; sourceTree = "<group>"; };
 		AD4495F2141FC08900541EDF /* EventListenerMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventListenerMap.h; sourceTree = "<group>"; };
+		AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentSharedObjectPool.cpp; sourceTree = "<group>"; };
+		AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentSharedObjectPool.h; sourceTree = "<group>"; };
 		ADDF1AD41257CD9A0003A759 /* RenderSVGPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGPath.cpp; sourceTree = "<group>"; };
 		ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGPath.h; sourceTree = "<group>"; };
 		B10B697D140C174000BC1C26 /* WebVTTToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVTTToken.h; sourceTree = "<group>"; };
@@ -22194,6 +22198,8 @@
 				93EEC1F709C2877700C515D1 /* WheelEvent.idl */,
 				4123E568127B3041000FEEA7 /* WindowEventContext.cpp */,
 				4123E567127B3041000FEEA7 /* WindowEventContext.h */,
+				AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */,
+				AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
 			);
 			path = dom;
 			sourceTree = "<group>";
@@ -25851,6 +25857,7 @@
 				53EF766B16530A61004CBE49 /* SettingsMacros.h in Headers */,
 				447958041643B49A001E0A7F /* ParsedContentType.h in Headers */,
 				FB2C15C3165D649D0039C9F8 /* CachedSVGDocumentReference.h in Headers */,
+				AD6E71AD1668899D00320C13 /* DocumentSharedObjectPool.h in Headers */,
 				31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
 				15B8B7C91652C5220036EF55 /* JSWebKitCSSMixFunctionValue.h in Headers */,
 				93F72AF31666EDFC002A02BD /* LayerPool.h in Headers */,
@@ -28954,6 +28961,7 @@
 				570B78BF1650CE81001DBE1B /* SelectRuleFeatureSet.cpp in Sources */,
 				1E50084816516AD800B7E098 /* RenderThemeMacShared.mm in Sources */,
 				CD7E05221651C28200C1201F /* WebCoreAVFResourceLoader.mm in Sources */,
+				AD6E71AC1668899D00320C13 /* DocumentSharedObjectPool.cpp in Sources */,
 				447958051643B4B2001E0A7F /* ParsedContentType.cpp in Sources */,
 				15B8B7C81652C5220036EF55 /* JSWebKitCSSMixFunctionValue.cpp in Sources */,
 				86BA766E166427A8005BE5D1 /* FrameLoadRequest.cpp in Sources */,

Modified: trunk/Source/WebCore/dom/DOMAllInOne.cpp (136333 => 136334)


--- trunk/Source/WebCore/dom/DOMAllInOne.cpp	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/DOMAllInOne.cpp	2012-12-02 12:03:44 UTC (rev 136334)
@@ -66,6 +66,7 @@
 #include "DocumentMarkerController.cpp"
 #include "DocumentOrderedMap.cpp"
 #include "DocumentParser.cpp"
+#include "DocumentSharedObjectPool.cpp"
 #include "DocumentType.cpp"
 #include "Element.cpp"
 #include "ElementAttributeData.cpp"

Modified: trunk/Source/WebCore/dom/Document.cpp (136333 => 136334)


--- trunk/Source/WebCore/dom/Document.cpp	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-12-02 12:03:44 UTC (rev 136334)
@@ -55,6 +55,7 @@
 #include "DocumentFragment.h"
 #include "DocumentLoader.h"
 #include "DocumentMarkerController.h"
+#include "DocumentSharedObjectPool.h"
 #include "DocumentStyleSheetCollection.h"
 #include "DocumentType.h"
 #include "Editor.h"
@@ -500,6 +501,7 @@
     , m_scheduledTasksAreSuspended(false)
     , m_visualUpdatesAllowed(true)
     , m_visualUpdatesSuppressionTimer(this, &Document::visualUpdatesSuppressionTimerFired)
+    , m_sharedObjectPoolClearTimer(this, &Document::sharedObjectPoolClearTimerFired)
 #ifndef NDEBUG
     , m_didDispatchViewportPropertiesChanged(false)
 #endif
@@ -2491,6 +2493,10 @@
 void Document::setParsing(bool b)
 {
     m_bParsing = b;
+
+    if (m_bParsing && !m_sharedObjectPool)
+        m_sharedObjectPool = DocumentSharedObjectPool::create();
+
     if (!m_bParsing && view())
         view()->scheduleRelayout();
 
@@ -4415,11 +4421,19 @@
         InspectorInstrumentation::domContentLoadedEventFired(f.get());
     }
 
-    // The ElementAttributeData sharing cache is only used during parsing since
-    // that's when the majority of immutable attribute data will be created.
-    m_immutableAttributeDataCache.clear();
+    // Schedule dropping of the DocumentSharedObjectPool. We keep it alive for a while after parsing finishes
+    // so that dynamically inserted content can also benefit from sharing optimizations.
+    // Note that we don't refresh the timer on pool access since that could lead to huge caches being kept
+    // alive indefinitely by something innocuous like JS setting .innerHTML repeatedly on a timer.
+    static const int timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds = 10;
+    m_sharedObjectPoolClearTimer.startOneShot(timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds);
 }
 
+void Document::sharedObjectPoolClearTimerFired(Timer<Document>*)
+{
+    m_sharedObjectPool.clear();
+}
+
 PassRefPtr<XPathExpression> Document::createExpression(const String& _expression_,
                                                        XPathNSResolver* resolver,
                                                        ExceptionCode& ec)
@@ -5860,65 +5874,6 @@
     info.addMember(m_listsInvalidatedAtDocument);
 }
 
-class ImmutableAttributeDataCacheKey {
-public:
-    ImmutableAttributeDataCacheKey(const Attribute* attributes, unsigned attributeCount)
-        : m_attributes(attributes)
-        , m_attributeCount(attributeCount)
-    { }
-
-    bool operator!=(const ImmutableAttributeDataCacheKey& 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;
-};
-
-struct ImmutableAttributeDataCacheEntry {
-    ImmutableAttributeDataCacheEntry(const ImmutableAttributeDataCacheKey& k, PassRefPtr<ElementAttributeData> v)
-        : key(k)
-        , value(v)
-    { }
-
-    ImmutableAttributeDataCacheKey key;
-    RefPtr<ElementAttributeData> value;
-};
-
-PassRefPtr<ElementAttributeData> Document::cachedImmutableAttributeData(const Vector<Attribute>& attributes)
-{
-    ASSERT(!attributes.isEmpty());
-
-    ImmutableAttributeDataCacheKey cacheKey(attributes.data(), attributes.size());
-    unsigned cacheHash = cacheKey.hash();
-
-    ImmutableAttributeDataCache::iterator cacheIterator = m_immutableAttributeDataCache.add(cacheHash, nullptr).iterator;
-    if (cacheIterator->value && cacheIterator->value->key != cacheKey)
-        cacheHash = 0;
-
-    RefPtr<ElementAttributeData> attributeData;
-    if (cacheHash && cacheIterator->value)
-        attributeData = cacheIterator->value->value;
-    else
-        attributeData = ElementAttributeData::createImmutable(attributes);
-
-    if (!cacheHash || cacheIterator->value)
-        return attributeData.release();
-
-    cacheIterator->value = adoptPtr(new ImmutableAttributeDataCacheEntry(ImmutableAttributeDataCacheKey(attributeData->immutableAttributeArray(), attributeData->length()), attributeData));
-
-    return attributeData.release();
-}
-
 bool Document::haveStylesheetsLoaded() const
 {
     return !m_styleSheetCollection->hasPendingSheets() || m_ignorePendingStylesheets;

Modified: trunk/Source/WebCore/dom/Document.h (136333 => 136334)


--- trunk/Source/WebCore/dom/Document.h	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/Document.h	2012-12-02 12:03:44 UTC (rev 136334)
@@ -77,11 +77,11 @@
 class DocumentLoader;
 class DocumentMarkerController;
 class DocumentParser;
+class DocumentSharedObjectPool;
 class DocumentStyleSheetCollection;
 class DocumentType;
 class DocumentWeakReference;
 class Element;
-class ElementAttributeData;
 class EntityReference;
 class Event;
 class EventListener;
@@ -206,9 +206,6 @@
 };
 const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1;
 
-struct ImmutableAttributeDataCacheEntry;
-typedef HashMap<unsigned, OwnPtr<ImmutableAttributeDataCacheEntry>, AlreadyHashed> ImmutableAttributeDataCache;
-
 class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext {
 public:
     static PassRefPtr<Document> create(Frame* frame, const KURL& url)
@@ -1153,7 +1150,7 @@
 
     virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
 
-    PassRefPtr<ElementAttributeData> cachedImmutableAttributeData(const Vector<Attribute>&);
+    DocumentSharedObjectPool* sharedObjectPool() { return m_sharedObjectPool.get(); }
 
     void didRemoveAllPendingStylesheet();
     void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
@@ -1515,8 +1512,11 @@
     RefPtr<DOMSecurityPolicy> m_domSecurityPolicy;
 #endif
 
-    ImmutableAttributeDataCache m_immutableAttributeDataCache;
+    void sharedObjectPoolClearTimerFired(Timer<Document>*);
+    Timer<Document> m_sharedObjectPoolClearTimer;
 
+    OwnPtr<DocumentSharedObjectPool> m_sharedObjectPool;
+
 #ifndef NDEBUG
     bool m_didDispatchViewportPropertiesChanged;
 #endif

Added: trunk/Source/WebCore/dom/DocumentSharedObjectPool.cpp (0 => 136334)


--- trunk/Source/WebCore/dom/DocumentSharedObjectPool.cpp	                        (rev 0)
+++ trunk/Source/WebCore/dom/DocumentSharedObjectPool.cpp	2012-12-02 12:03:44 UTC (rev 136334)
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "DocumentSharedObjectPool.h"
+
+#include "Attribute.h"
+#include "ElementAttributeData.h"
+
+namespace WebCore {
+
+class ImmutableElementAttributeDataCacheKey {
+public:
+    ImmutableElementAttributeDataCacheKey(const Attribute* attributes, unsigned attributeCount)
+        : m_attributes(attributes)
+        , m_attributeCount(attributeCount)
+    { }
+
+    bool operator!=(const ImmutableElementAttributeDataCacheKey& 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 ImmutableElementAttributeDataCacheEntry {
+public:
+    ImmutableElementAttributeDataCacheEntry(const ImmutableElementAttributeDataCacheKey& k, PassRefPtr<ElementAttributeData> v)
+        : key(k)
+        , value(v)
+    { }
+
+    ImmutableElementAttributeDataCacheKey key;
+    RefPtr<ElementAttributeData> value;
+};
+
+PassRefPtr<ElementAttributeData> DocumentSharedObjectPool::cachedImmutableElementAttributeData(const Vector<Attribute>& attributes)
+{
+    ASSERT(!attributes.isEmpty());
+
+    ImmutableElementAttributeDataCacheKey cacheKey(attributes.data(), attributes.size());
+    unsigned cacheHash = cacheKey.hash();
+
+    ImmutableElementAttributeDataCache::iterator cacheIterator = m_immutableElementAttributeDataCache.add(cacheHash, nullptr).iterator;
+    if (cacheIterator->value && cacheIterator->value->key != cacheKey)
+        cacheHash = 0;
+
+    RefPtr<ElementAttributeData> attributeData;
+    if (cacheHash && cacheIterator->value)
+        attributeData = cacheIterator->value->value;
+    else
+        attributeData = ElementAttributeData::createImmutable(attributes);
+
+    if (!cacheHash || cacheIterator->value)
+        return attributeData.release();
+
+    cacheIterator->value = adoptPtr(new ImmutableElementAttributeDataCacheEntry(ImmutableElementAttributeDataCacheKey(attributeData->immutableAttributeArray(), attributeData->length()), attributeData));
+
+    return attributeData.release();
+}
+
+DocumentSharedObjectPool::DocumentSharedObjectPool()
+{
+}
+
+DocumentSharedObjectPool::~DocumentSharedObjectPool()
+{
+}
+
+}

Added: trunk/Source/WebCore/dom/DocumentSharedObjectPool.h (0 => 136334)


--- trunk/Source/WebCore/dom/DocumentSharedObjectPool.h	                        (rev 0)
+++ trunk/Source/WebCore/dom/DocumentSharedObjectPool.h	2012-12-02 12:03:44 UTC (rev 136334)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef DocumentSharedObjectPool_h
+#define DocumentSharedObjectPool_h
+
+#include <wtf/HashMap.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class Attribute;
+class ElementAttributeData;
+class ImmutableElementAttributeDataCacheEntry;
+
+class DocumentSharedObjectPool {
+public:
+    static PassOwnPtr<DocumentSharedObjectPool> create() { return adoptPtr(new DocumentSharedObjectPool); }
+    ~DocumentSharedObjectPool();
+
+    PassRefPtr<ElementAttributeData> cachedImmutableElementAttributeData(const Vector<Attribute>&);
+
+private:
+    DocumentSharedObjectPool();
+
+    typedef HashMap<unsigned, OwnPtr<ImmutableElementAttributeDataCacheEntry>, AlreadyHashed> ImmutableElementAttributeDataCache;
+    ImmutableElementAttributeDataCache m_immutableElementAttributeDataCache;
+};
+
+}
+
+#endif

Modified: trunk/Source/WebCore/dom/Element.cpp (136333 => 136334)


--- trunk/Source/WebCore/dom/Element.cpp	2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/Element.cpp	2012-12-02 12:03:44 UTC (rev 136334)
@@ -37,6 +37,7 @@
 #include "DatasetDOMStringMap.h"
 #include "Document.h"
 #include "DocumentFragment.h"
+#include "DocumentSharedObjectPool.h"
 #include "ElementRareData.h"
 #include "ExceptionCode.h"
 #include "FlowThreadController.h"
@@ -976,12 +977,10 @@
         }
     }
 
-    // When the document is in parsing state, we cache immutable ElementAttributeData objects with the
-    // input attribute vector as key. (This cache is held by Document.)
-    if (!document() || !document()->parsing())
-        m_attributeData = ElementAttributeData::createImmutable(filteredAttributes);
+    if (document() && document()->sharedObjectPool())
+        m_attributeData = document()->sharedObjectPool()->cachedImmutableElementAttributeData(filteredAttributes);
     else
-        m_attributeData = document()->cachedImmutableAttributeData(filteredAttributes);
+        m_attributeData = ElementAttributeData::createImmutable(filteredAttributes);
 
     // Iterate over the set of attributes we already have on the stack in case
     // attributeChanged mutates m_attributeData.
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to